^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * drivers/soc/tegra/pmc.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2010 Google, Inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Author:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Colin Cross <ccross@google.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #define pr_fmt(fmt) "tegra-pmc: " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/arm-smccc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/clkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/clk/clk-conf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/clk/tegra.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/iopoll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/irqdomain.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/of_clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/of_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/pinctrl/pinconf-generic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/pinctrl/pinconf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/pinctrl/pinctrl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/pm_domain.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/reboot.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/reset.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <soc/tegra/common.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <soc/tegra/fuse.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <soc/tegra/pmc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <dt-bindings/interrupt-controller/arm-gic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <dt-bindings/pinctrl/pinctrl-tegra-io-pad.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #include <dt-bindings/gpio/tegra186-gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include <dt-bindings/gpio/tegra194-gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #include <dt-bindings/soc/tegra-pmc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define PMC_CNTRL 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define PMC_CNTRL_INTR_POLARITY BIT(17) /* inverts INTR polarity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define PMC_CNTRL_CPU_PWRREQ_OE BIT(16) /* CPU pwr req enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define PMC_CNTRL_CPU_PWRREQ_POLARITY BIT(15) /* CPU pwr req polarity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define PMC_CNTRL_SIDE_EFFECT_LP0 BIT(14) /* LP0 when CPU pwr gated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define PMC_CNTRL_SYSCLK_OE BIT(11) /* system clock enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define PMC_CNTRL_SYSCLK_POLARITY BIT(10) /* sys clk polarity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define PMC_CNTRL_PWRREQ_POLARITY BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define PMC_CNTRL_BLINK_EN 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define PMC_CNTRL_MAIN_RST BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define PMC_WAKE_MASK 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define PMC_WAKE_LEVEL 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define PMC_WAKE_STATUS 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define PMC_SW_WAKE_STATUS 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define PMC_DPD_PADS_ORIDE 0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define PMC_DPD_PADS_ORIDE_BLINK 20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define DPD_SAMPLE 0x020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define DPD_SAMPLE_ENABLE BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define DPD_SAMPLE_DISABLE (0 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define PWRGATE_TOGGLE 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define PWRGATE_TOGGLE_START BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define REMOVE_CLAMPING 0x34
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define PWRGATE_STATUS 0x38
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define PMC_BLINK_TIMER 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define PMC_IMPL_E_33V_PWR 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define PMC_PWR_DET 0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define PMC_SCRATCH0_MODE_RECOVERY BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define PMC_SCRATCH0_MODE_BOOTLOADER BIT(30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define PMC_SCRATCH0_MODE_RCM BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define PMC_SCRATCH0_MODE_MASK (PMC_SCRATCH0_MODE_RECOVERY | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) PMC_SCRATCH0_MODE_BOOTLOADER | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) PMC_SCRATCH0_MODE_RCM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define PMC_CPUPWRGOOD_TIMER 0xc8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define PMC_CPUPWROFF_TIMER 0xcc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define PMC_COREPWRGOOD_TIMER 0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define PMC_COREPWROFF_TIMER 0xe0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define PMC_PWR_DET_VALUE 0xe4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define PMC_SCRATCH41 0x140
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define PMC_WAKE2_MASK 0x160
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define PMC_WAKE2_LEVEL 0x164
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define PMC_WAKE2_STATUS 0x168
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define PMC_SW_WAKE2_STATUS 0x16c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define PMC_CLK_OUT_CNTRL 0x1a8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define PMC_CLK_OUT_MUX_MASK GENMASK(1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define PMC_SENSOR_CTRL 0x1b0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define PMC_SENSOR_CTRL_SCRATCH_WRITE BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define PMC_SENSOR_CTRL_ENABLE_RST BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define PMC_RST_STATUS_POR 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define PMC_RST_STATUS_WATCHDOG 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define PMC_RST_STATUS_SENSOR 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define PMC_RST_STATUS_SW_MAIN 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define PMC_RST_STATUS_LP0 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define PMC_RST_STATUS_AOTAG 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define IO_DPD_REQ 0x1b8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define IO_DPD_REQ_CODE_IDLE (0U << 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define IO_DPD_REQ_CODE_OFF (1U << 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define IO_DPD_REQ_CODE_ON (2U << 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define IO_DPD_REQ_CODE_MASK (3U << 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define IO_DPD_STATUS 0x1bc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define IO_DPD2_REQ 0x1c0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define IO_DPD2_STATUS 0x1c4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define SEL_DPD_TIM 0x1c8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define PMC_SCRATCH54 0x258
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define PMC_SCRATCH54_DATA_SHIFT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define PMC_SCRATCH54_ADDR_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define PMC_SCRATCH55 0x25c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define PMC_SCRATCH55_RESET_TEGRA BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define PMC_SCRATCH55_CNTRL_ID_SHIFT 27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define PMC_SCRATCH55_PINMUX_SHIFT 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define PMC_SCRATCH55_16BITOP BIT(15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define PMC_SCRATCH55_CHECKSUM_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define PMC_SCRATCH55_I2CSLV1_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define GPU_RG_CNTRL 0x2d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /* Tegra186 and later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define WAKE_AOWAKE_CNTRL(x) (0x000 + ((x) << 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #define WAKE_AOWAKE_CNTRL_LEVEL (1 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define WAKE_AOWAKE_MASK_W(x) (0x180 + ((x) << 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define WAKE_AOWAKE_MASK_R(x) (0x300 + ((x) << 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define WAKE_AOWAKE_STATUS_W(x) (0x30c + ((x) << 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #define WAKE_AOWAKE_STATUS_R(x) (0x48c + ((x) << 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #define WAKE_AOWAKE_TIER0_ROUTING(x) (0x4b4 + ((x) << 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #define WAKE_AOWAKE_TIER1_ROUTING(x) (0x4c0 + ((x) << 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #define WAKE_AOWAKE_TIER2_ROUTING(x) (0x4cc + ((x) << 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #define WAKE_AOWAKE_CTRL 0x4f4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #define WAKE_AOWAKE_CTRL_INTR_POLARITY BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /* for secure PMC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define TEGRA_SMC_PMC 0xc2fffe00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #define TEGRA_SMC_PMC_READ 0xaa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #define TEGRA_SMC_PMC_WRITE 0xbb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) struct pmc_clk {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct clk_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) unsigned long offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) u32 mux_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) u32 force_en_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #define to_pmc_clk(_hw) container_of(_hw, struct pmc_clk, hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct pmc_clk_gate {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct clk_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) unsigned long offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) u32 shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #define to_pmc_clk_gate(_hw) container_of(_hw, struct pmc_clk_gate, hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) struct pmc_clk_init_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) const char *const *parents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) int num_parents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) int clk_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) u8 mux_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) u8 force_en_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static const char * const clk_out1_parents[] = { "osc", "osc_div2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) "osc_div4", "extern1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static const char * const clk_out2_parents[] = { "osc", "osc_div2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) "osc_div4", "extern2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static const char * const clk_out3_parents[] = { "osc", "osc_div2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) "osc_div4", "extern3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static const struct pmc_clk_init_data tegra_pmc_clks_data[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) .name = "pmc_clk_out_1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) .parents = clk_out1_parents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) .num_parents = ARRAY_SIZE(clk_out1_parents),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) .clk_id = TEGRA_PMC_CLK_OUT_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) .mux_shift = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) .force_en_shift = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) .name = "pmc_clk_out_2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) .parents = clk_out2_parents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) .num_parents = ARRAY_SIZE(clk_out2_parents),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) .clk_id = TEGRA_PMC_CLK_OUT_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) .mux_shift = 14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) .force_en_shift = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) .name = "pmc_clk_out_3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) .parents = clk_out3_parents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) .num_parents = ARRAY_SIZE(clk_out3_parents),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) .clk_id = TEGRA_PMC_CLK_OUT_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) .mux_shift = 22,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) .force_en_shift = 18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) struct tegra_powergate {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) struct generic_pm_domain genpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) struct tegra_pmc *pmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) unsigned int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct clk **clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) unsigned int num_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) struct reset_control *reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct tegra_io_pad_soc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) enum tegra_io_pad id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) unsigned int dpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) unsigned int voltage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct tegra_pmc_regs {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) unsigned int scratch0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) unsigned int dpd_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) unsigned int dpd_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) unsigned int dpd2_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) unsigned int dpd2_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) unsigned int rst_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) unsigned int rst_source_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) unsigned int rst_source_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) unsigned int rst_level_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) unsigned int rst_level_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) struct tegra_wake_event {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) unsigned int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) unsigned int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) unsigned int instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) unsigned int pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) } gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) #define TEGRA_WAKE_IRQ(_name, _id, _irq) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) .name = _name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) .id = _id, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) .irq = _irq, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) .gpio = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) .instance = UINT_MAX, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) .pin = UINT_MAX, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) #define TEGRA_WAKE_GPIO(_name, _id, _instance, _pin) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) .name = _name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) .id = _id, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) .irq = 0, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) .gpio = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) .instance = _instance, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) .pin = _pin, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct tegra_pmc_soc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) unsigned int num_powergates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) const char *const *powergates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) unsigned int num_cpu_powergates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) const u8 *cpu_powergates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) bool has_tsense_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) bool has_gpu_clamps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) bool needs_mbist_war;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) bool has_impl_33v_pwr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) bool maybe_tz_only;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) const struct tegra_io_pad_soc *io_pads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) unsigned int num_io_pads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) const struct pinctrl_pin_desc *pin_descs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) unsigned int num_pin_descs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) const struct tegra_pmc_regs *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) void (*init)(struct tegra_pmc *pmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) void (*setup_irq_polarity)(struct tegra_pmc *pmc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) bool invert);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) int (*irq_set_wake)(struct irq_data *data, unsigned int on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) int (*irq_set_type)(struct irq_data *data, unsigned int type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) int (*powergate_set)(struct tegra_pmc *pmc, unsigned int id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) bool new_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) const char * const *reset_sources;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) unsigned int num_reset_sources;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) const char * const *reset_levels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) unsigned int num_reset_levels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) * These describe events that can wake the system from sleep (i.e.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * LP0 or SC7). Wakeup from other sleep states (such as LP1 or LP2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) * are dealt with in the LIC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) const struct tegra_wake_event *wake_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) unsigned int num_wake_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) const struct pmc_clk_init_data *pmc_clks_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) unsigned int num_pmc_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) bool has_blink_output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) * struct tegra_pmc - NVIDIA Tegra PMC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) * @dev: pointer to PMC device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * @base: pointer to I/O remapped register region
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * @wake: pointer to I/O remapped region for WAKE registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) * @aotag: pointer to I/O remapped region for AOTAG registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) * @scratch: pointer to I/O remapped region for scratch registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) * @clk: pointer to pclk clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * @soc: pointer to SoC data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * @tz_only: flag specifying if the PMC can only be accessed via TrustZone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) * @debugfs: pointer to debugfs entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * @rate: currently configured rate of pclk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * @suspend_mode: lowest suspend mode available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) * @cpu_good_time: CPU power good time (in microseconds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * @cpu_off_time: CPU power off time (in microsecends)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * @core_osc_time: core power good OSC time (in microseconds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * @core_pmu_time: core power good PMU time (in microseconds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * @core_off_time: core power off time (in microseconds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * @corereq_high: core power request is active-high
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * @sysclkreq_high: system clock request is active-high
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * @combined_req: combined power request for CPU & core
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * @cpu_pwr_good_en: CPU power good signal is enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * @lp0_vec_phys: physical base address of the LP0 warm boot code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * @lp0_vec_size: size of the LP0 warm boot code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * @powergates_available: Bitmap of available power gates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * @powergates_lock: mutex for power gate register access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) * @pctl_dev: pin controller exposed by the PMC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * @domain: IRQ domain provided by the PMC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * @irq: chip implementation for the IRQ domain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * @clk_nb: pclk clock changes handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) struct tegra_pmc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) void __iomem *wake;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) void __iomem *aotag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) void __iomem *scratch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) struct dentry *debugfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) const struct tegra_pmc_soc *soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) bool tz_only;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) unsigned long rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) enum tegra_suspend_mode suspend_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) u32 cpu_good_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) u32 cpu_off_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) u32 core_osc_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) u32 core_pmu_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) u32 core_off_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) bool corereq_high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) bool sysclkreq_high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) bool combined_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) bool cpu_pwr_good_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) u32 lp0_vec_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) u32 lp0_vec_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) DECLARE_BITMAP(powergates_available, TEGRA_POWERGATE_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) struct mutex powergates_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) struct pinctrl_dev *pctl_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) struct irq_domain *domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct irq_chip irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct notifier_block clk_nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) static struct tegra_pmc *pmc = &(struct tegra_pmc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) .base = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) .suspend_mode = TEGRA_SUSPEND_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) static inline struct tegra_powergate *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) to_powergate(struct generic_pm_domain *domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return container_of(domain, struct tegra_powergate, genpd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) static u32 tegra_pmc_readl(struct tegra_pmc *pmc, unsigned long offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) struct arm_smccc_res res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (pmc->tz_only) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) arm_smccc_smc(TEGRA_SMC_PMC, TEGRA_SMC_PMC_READ, offset, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 0, 0, 0, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (res.a0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (pmc->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) dev_warn(pmc->dev, "%s(): SMC failed: %lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) __func__, res.a0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) pr_warn("%s(): SMC failed: %lu\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) res.a0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) return res.a1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) return readl(pmc->base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) static void tegra_pmc_writel(struct tegra_pmc *pmc, u32 value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) unsigned long offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) struct arm_smccc_res res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (pmc->tz_only) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) arm_smccc_smc(TEGRA_SMC_PMC, TEGRA_SMC_PMC_WRITE, offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) value, 0, 0, 0, 0, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (res.a0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (pmc->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) dev_warn(pmc->dev, "%s(): SMC failed: %lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) __func__, res.a0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) pr_warn("%s(): SMC failed: %lu\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) res.a0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) writel(value, pmc->base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) static u32 tegra_pmc_scratch_readl(struct tegra_pmc *pmc, unsigned long offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (pmc->tz_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return tegra_pmc_readl(pmc, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) return readl(pmc->scratch + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) static void tegra_pmc_scratch_writel(struct tegra_pmc *pmc, u32 value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) unsigned long offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (pmc->tz_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) tegra_pmc_writel(pmc, value, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) writel(value, pmc->scratch + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * TODO Figure out a way to call this with the struct tegra_pmc * passed in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * This currently doesn't work because readx_poll_timeout() can only operate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) * on functions that take a single argument.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) static inline bool tegra_powergate_state(int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (id == TEGRA_POWERGATE_3D && pmc->soc->has_gpu_clamps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return (tegra_pmc_readl(pmc, GPU_RG_CNTRL) & 0x1) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return (tegra_pmc_readl(pmc, PWRGATE_STATUS) & BIT(id)) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) static inline bool tegra_powergate_is_valid(struct tegra_pmc *pmc, int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return (pmc->soc && pmc->soc->powergates[id]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) static inline bool tegra_powergate_is_available(struct tegra_pmc *pmc, int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) return test_bit(id, pmc->powergates_available);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) static int tegra_powergate_lookup(struct tegra_pmc *pmc, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if (!pmc || !pmc->soc || !name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) for (i = 0; i < pmc->soc->num_powergates; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (!tegra_powergate_is_valid(pmc, i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (!strcmp(name, pmc->soc->powergates[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) static int tegra20_powergate_set(struct tegra_pmc *pmc, unsigned int id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) bool new_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) unsigned int retries = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) bool status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) * As per TRM documentation, the toggle command will be dropped by PMC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) * if there is contention with a HW-initiated toggling (i.e. CPU core
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) * power-gated), the command should be retried in that case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) tegra_pmc_writel(pmc, PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) /* wait for PMC to execute the command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) ret = readx_poll_timeout(tegra_powergate_state, id, status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) status == new_state, 1, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) } while (ret == -ETIMEDOUT && retries--);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) static inline bool tegra_powergate_toggle_ready(struct tegra_pmc *pmc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) return !(tegra_pmc_readl(pmc, PWRGATE_TOGGLE) & PWRGATE_TOGGLE_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) static int tegra114_powergate_set(struct tegra_pmc *pmc, unsigned int id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) bool new_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) bool status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) /* wait while PMC power gating is contended */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) err = readx_poll_timeout(tegra_powergate_toggle_ready, pmc, status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) status == true, 1, 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) tegra_pmc_writel(pmc, PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) /* wait for PMC to accept the command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) err = readx_poll_timeout(tegra_powergate_toggle_ready, pmc, status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) status == true, 1, 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) /* wait for PMC to execute the command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) err = readx_poll_timeout(tegra_powergate_state, id, status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) status == new_state, 10, 100000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) * tegra_powergate_set() - set the state of a partition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) * @pmc: power management controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) * @id: partition ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) * @new_state: new state of the partition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) static int tegra_powergate_set(struct tegra_pmc *pmc, unsigned int id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) bool new_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if (id == TEGRA_POWERGATE_3D && pmc->soc->has_gpu_clamps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) mutex_lock(&pmc->powergates_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (tegra_powergate_state(id) == new_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) mutex_unlock(&pmc->powergates_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) err = pmc->soc->powergate_set(pmc, id, new_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) mutex_unlock(&pmc->powergates_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) static int __tegra_powergate_remove_clamping(struct tegra_pmc *pmc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) unsigned int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) u32 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) mutex_lock(&pmc->powergates_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) * On Tegra124 and later, the clamps for the GPU are controlled by a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) * separate register (with different semantics).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) if (id == TEGRA_POWERGATE_3D) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) if (pmc->soc->has_gpu_clamps) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) tegra_pmc_writel(pmc, 0, GPU_RG_CNTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) * Tegra 2 has a bug where PCIE and VDE clamping masks are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) * swapped relatively to the partition ids
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (id == TEGRA_POWERGATE_VDEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) mask = (1 << TEGRA_POWERGATE_PCIE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) else if (id == TEGRA_POWERGATE_PCIE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) mask = (1 << TEGRA_POWERGATE_VDEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) mask = (1 << id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) tegra_pmc_writel(pmc, mask, REMOVE_CLAMPING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) mutex_unlock(&pmc->powergates_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) static void tegra_powergate_disable_clocks(struct tegra_powergate *pg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) for (i = 0; i < pg->num_clks; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) clk_disable_unprepare(pg->clks[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) static int tegra_powergate_enable_clocks(struct tegra_powergate *pg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) for (i = 0; i < pg->num_clks; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) err = clk_prepare_enable(pg->clks[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) while (i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) clk_disable_unprepare(pg->clks[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) int __weak tegra210_clk_handle_mbist_war(unsigned int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) static int tegra_powergate_power_up(struct tegra_powergate *pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) bool disable_clocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) err = reset_control_assert(pg->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) usleep_range(10, 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) err = tegra_powergate_set(pg->pmc, pg->id, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) usleep_range(10, 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) err = tegra_powergate_enable_clocks(pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) goto powergate_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) usleep_range(10, 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) err = __tegra_powergate_remove_clamping(pg->pmc, pg->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) goto disable_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) usleep_range(10, 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) err = reset_control_deassert(pg->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) goto disable_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) usleep_range(10, 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (pg->pmc->soc->needs_mbist_war)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) err = tegra210_clk_handle_mbist_war(pg->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) goto disable_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) if (disable_clocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) tegra_powergate_disable_clocks(pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) disable_clks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) tegra_powergate_disable_clocks(pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) usleep_range(10, 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) powergate_off:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) tegra_powergate_set(pg->pmc, pg->id, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) static int tegra_powergate_power_down(struct tegra_powergate *pg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) err = tegra_powergate_enable_clocks(pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) usleep_range(10, 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) err = reset_control_assert(pg->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) goto disable_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) usleep_range(10, 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) tegra_powergate_disable_clocks(pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) usleep_range(10, 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) err = tegra_powergate_set(pg->pmc, pg->id, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) goto assert_resets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) assert_resets:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) tegra_powergate_enable_clocks(pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) usleep_range(10, 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) reset_control_deassert(pg->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) usleep_range(10, 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) disable_clks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) tegra_powergate_disable_clocks(pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) static int tegra_genpd_power_on(struct generic_pm_domain *domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) struct tegra_powergate *pg = to_powergate(domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) struct device *dev = pg->pmc->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) err = tegra_powergate_power_up(pg, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) dev_err(dev, "failed to turn on PM domain %s: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) pg->genpd.name, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) reset_control_release(pg->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) static int tegra_genpd_power_off(struct generic_pm_domain *domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) struct tegra_powergate *pg = to_powergate(domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) struct device *dev = pg->pmc->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) err = reset_control_acquire(pg->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) pr_err("failed to acquire resets: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) err = tegra_powergate_power_down(pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) dev_err(dev, "failed to turn off PM domain %s: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) pg->genpd.name, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) reset_control_release(pg->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) * tegra_powergate_power_on() - power on partition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) * @id: partition ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) int tegra_powergate_power_on(unsigned int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) if (!tegra_powergate_is_available(pmc, id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) return tegra_powergate_set(pmc, id, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) EXPORT_SYMBOL(tegra_powergate_power_on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) * tegra_powergate_power_off() - power off partition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) * @id: partition ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) int tegra_powergate_power_off(unsigned int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (!tegra_powergate_is_available(pmc, id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) return tegra_powergate_set(pmc, id, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) EXPORT_SYMBOL(tegra_powergate_power_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) * tegra_powergate_is_powered() - check if partition is powered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) * @pmc: power management controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) * @id: partition ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) static int tegra_powergate_is_powered(struct tegra_pmc *pmc, unsigned int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) if (!tegra_powergate_is_valid(pmc, id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) return tegra_powergate_state(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) * tegra_powergate_remove_clamping() - remove power clamps for partition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) * @id: partition ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) int tegra_powergate_remove_clamping(unsigned int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) if (!tegra_powergate_is_available(pmc, id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) return __tegra_powergate_remove_clamping(pmc, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) EXPORT_SYMBOL(tegra_powergate_remove_clamping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) * tegra_powergate_sequence_power_up() - power up partition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) * @id: partition ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) * @clk: clock for partition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) * @rst: reset for partition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) * Must be called with clk disabled, and returns with clk enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) struct reset_control *rst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) struct tegra_powergate *pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) if (!tegra_powergate_is_available(pmc, id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) pg = kzalloc(sizeof(*pg), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) if (!pg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) pg->id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) pg->clks = &clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) pg->num_clks = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) pg->reset = rst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) pg->pmc = pmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) err = tegra_powergate_power_up(pg, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) dev_err(pmc->dev, "failed to turn on partition %d: %d\n", id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) kfree(pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) EXPORT_SYMBOL(tegra_powergate_sequence_power_up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) * tegra_get_cpu_powergate_id() - convert from CPU ID to partition ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) * @pmc: power management controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) * @cpuid: CPU partition ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) * Returns the partition ID corresponding to the CPU partition ID or a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) * negative error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) static int tegra_get_cpu_powergate_id(struct tegra_pmc *pmc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) unsigned int cpuid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) if (pmc->soc && cpuid < pmc->soc->num_cpu_powergates)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) return pmc->soc->cpu_powergates[cpuid];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) * tegra_pmc_cpu_is_powered() - check if CPU partition is powered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) * @cpuid: CPU partition ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) bool tegra_pmc_cpu_is_powered(unsigned int cpuid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) id = tegra_get_cpu_powergate_id(pmc, cpuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (id < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) return tegra_powergate_is_powered(pmc, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) * tegra_pmc_cpu_power_on() - power on CPU partition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) * @cpuid: CPU partition ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) int tegra_pmc_cpu_power_on(unsigned int cpuid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) id = tegra_get_cpu_powergate_id(pmc, cpuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) if (id < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) return id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) return tegra_powergate_set(pmc, id, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) * tegra_pmc_cpu_remove_clamping() - remove power clamps for CPU partition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) * @cpuid: CPU partition ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) int tegra_pmc_cpu_remove_clamping(unsigned int cpuid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) id = tegra_get_cpu_powergate_id(pmc, cpuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) if (id < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) return id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) return tegra_powergate_remove_clamping(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) static int tegra_pmc_restart_notify(struct notifier_block *this,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) unsigned long action, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) const char *cmd = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) value = tegra_pmc_scratch_readl(pmc, pmc->soc->regs->scratch0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) value &= ~PMC_SCRATCH0_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) if (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) if (strcmp(cmd, "recovery") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) value |= PMC_SCRATCH0_MODE_RECOVERY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) if (strcmp(cmd, "bootloader") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) value |= PMC_SCRATCH0_MODE_BOOTLOADER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (strcmp(cmd, "forced-recovery") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) value |= PMC_SCRATCH0_MODE_RCM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) tegra_pmc_scratch_writel(pmc, value, pmc->soc->regs->scratch0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) /* reset everything but PMC_SCRATCH0 and PMC_RST_STATUS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) value = tegra_pmc_readl(pmc, PMC_CNTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) value |= PMC_CNTRL_MAIN_RST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) tegra_pmc_writel(pmc, value, PMC_CNTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) static struct notifier_block tegra_pmc_restart_handler = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) .notifier_call = tegra_pmc_restart_notify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) .priority = 128,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) static int powergate_show(struct seq_file *s, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) seq_printf(s, " powergate powered\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) seq_printf(s, "------------------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) for (i = 0; i < pmc->soc->num_powergates; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) status = tegra_powergate_is_powered(pmc, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) seq_printf(s, " %9s %7s\n", pmc->soc->powergates[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) status ? "yes" : "no");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) DEFINE_SHOW_ATTRIBUTE(powergate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) static int tegra_powergate_debugfs_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) pmc->debugfs = debugfs_create_file("powergate", S_IRUGO, NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) &powergate_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) if (!pmc->debugfs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) static int tegra_powergate_of_get_clks(struct tegra_powergate *pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) unsigned int i, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) count = of_clk_get_parent_count(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) if (count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) pg->clks = kcalloc(count, sizeof(clk), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) if (!pg->clks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) for (i = 0; i < count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) pg->clks[i] = of_clk_get(np, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) if (IS_ERR(pg->clks[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) err = PTR_ERR(pg->clks[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) pg->num_clks = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) while (i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) clk_put(pg->clks[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) kfree(pg->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) static int tegra_powergate_of_get_resets(struct tegra_powergate *pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) struct device_node *np, bool off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) struct device *dev = pg->pmc->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) pg->reset = of_reset_control_array_get_exclusive_released(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) if (IS_ERR(pg->reset)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) err = PTR_ERR(pg->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) dev_err(dev, "failed to get device resets: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) err = reset_control_acquire(pg->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) pr_err("failed to acquire resets: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) if (off) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) err = reset_control_assert(pg->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) err = reset_control_deassert(pg->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) reset_control_release(pg->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) reset_control_release(pg->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) reset_control_put(pg->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) static int tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) struct device *dev = pmc->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) struct tegra_powergate *pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) int id, err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) bool off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) pg = kzalloc(sizeof(*pg), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) if (!pg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) id = tegra_powergate_lookup(pmc, np->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) if (id < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) dev_err(dev, "powergate lookup failed for %pOFn: %d\n", np, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) goto free_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) * Clear the bit for this powergate so it cannot be managed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) * directly via the legacy APIs for controlling powergates.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) clear_bit(id, pmc->powergates_available);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) pg->id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) pg->genpd.name = np->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) pg->genpd.power_off = tegra_genpd_power_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) pg->genpd.power_on = tegra_genpd_power_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) pg->pmc = pmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) off = !tegra_powergate_is_powered(pmc, pg->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) err = tegra_powergate_of_get_clks(pg, np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) dev_err(dev, "failed to get clocks for %pOFn: %d\n", np, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) goto set_available;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) err = tegra_powergate_of_get_resets(pg, np, off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) dev_err(dev, "failed to get resets for %pOFn: %d\n", np, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) goto remove_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if (!IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) if (off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) WARN_ON(tegra_powergate_power_up(pg, true));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) goto remove_resets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) err = pm_genpd_init(&pg->genpd, NULL, off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) dev_err(dev, "failed to initialise PM domain %pOFn: %d\n", np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) goto remove_resets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) err = of_genpd_add_provider_simple(np, &pg->genpd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) dev_err(dev, "failed to add PM domain provider for %pOFn: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) np, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) goto remove_genpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) dev_dbg(dev, "added PM domain %s\n", pg->genpd.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) remove_genpd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) pm_genpd_remove(&pg->genpd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) remove_resets:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) reset_control_put(pg->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) remove_clks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) while (pg->num_clks--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) clk_put(pg->clks[pg->num_clks]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) kfree(pg->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) set_available:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) set_bit(id, pmc->powergates_available);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) free_mem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) kfree(pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) static int tegra_powergate_init(struct tegra_pmc *pmc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) struct device_node *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) struct device_node *np, *child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) np = of_get_child_by_name(parent, "powergates");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) for_each_child_of_node(np, child) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) err = tegra_powergate_add(pmc, child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) of_node_put(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) static void tegra_powergate_remove(struct generic_pm_domain *genpd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) struct tegra_powergate *pg = to_powergate(genpd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) reset_control_put(pg->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) while (pg->num_clks--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) clk_put(pg->clks[pg->num_clks]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) kfree(pg->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) set_bit(pg->id, pmc->powergates_available);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) kfree(pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) static void tegra_powergate_remove_all(struct device_node *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) struct generic_pm_domain *genpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) struct device_node *np, *child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) np = of_get_child_by_name(parent, "powergates");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) for_each_child_of_node(np, child) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) of_genpd_del_provider(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) genpd = of_genpd_remove_last(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) if (IS_ERR(genpd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) tegra_powergate_remove(genpd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) static const struct tegra_io_pad_soc *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) tegra_io_pad_find(struct tegra_pmc *pmc, enum tegra_io_pad id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) for (i = 0; i < pmc->soc->num_io_pads; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) if (pmc->soc->io_pads[i].id == id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) return &pmc->soc->io_pads[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) static int tegra_io_pad_get_dpd_register_bit(struct tegra_pmc *pmc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) enum tegra_io_pad id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) unsigned long *request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) unsigned long *status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) u32 *mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) const struct tegra_io_pad_soc *pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) pad = tegra_io_pad_find(pmc, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) if (!pad) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) dev_err(pmc->dev, "invalid I/O pad ID %u\n", id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) if (pad->dpd == UINT_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) *mask = BIT(pad->dpd % 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) if (pad->dpd < 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) *status = pmc->soc->regs->dpd_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) *request = pmc->soc->regs->dpd_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) *status = pmc->soc->regs->dpd2_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) *request = pmc->soc->regs->dpd2_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) static int tegra_io_pad_prepare(struct tegra_pmc *pmc, enum tegra_io_pad id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) unsigned long *request, unsigned long *status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) u32 *mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) unsigned long rate, value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) err = tegra_io_pad_get_dpd_register_bit(pmc, id, request, status, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) if (pmc->clk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) rate = pmc->rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) if (!rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) dev_err(pmc->dev, "failed to get clock rate\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) tegra_pmc_writel(pmc, DPD_SAMPLE_ENABLE, DPD_SAMPLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) /* must be at least 200 ns, in APB (PCLK) clock cycles */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) value = DIV_ROUND_UP(1000000000, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) value = DIV_ROUND_UP(200, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) tegra_pmc_writel(pmc, value, SEL_DPD_TIM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) static int tegra_io_pad_poll(struct tegra_pmc *pmc, unsigned long offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) u32 mask, u32 val, unsigned long timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) timeout = jiffies + msecs_to_jiffies(timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) while (time_after(timeout, jiffies)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) value = tegra_pmc_readl(pmc, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) if ((value & mask) == val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) usleep_range(250, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) static void tegra_io_pad_unprepare(struct tegra_pmc *pmc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) if (pmc->clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) tegra_pmc_writel(pmc, DPD_SAMPLE_DISABLE, DPD_SAMPLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) * tegra_io_pad_power_enable() - enable power to I/O pad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) * @id: Tegra I/O pad ID for which to enable power
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) * Returns: 0 on success or a negative error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) int tegra_io_pad_power_enable(enum tegra_io_pad id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) unsigned long request, status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) u32 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) mutex_lock(&pmc->powergates_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) err = tegra_io_pad_prepare(pmc, id, &request, &status, &mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) dev_err(pmc->dev, "failed to prepare I/O pad: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) tegra_pmc_writel(pmc, IO_DPD_REQ_CODE_OFF | mask, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) err = tegra_io_pad_poll(pmc, status, mask, 0, 250);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) dev_err(pmc->dev, "failed to enable I/O pad: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) tegra_io_pad_unprepare(pmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) mutex_unlock(&pmc->powergates_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) EXPORT_SYMBOL(tegra_io_pad_power_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) * tegra_io_pad_power_disable() - disable power to I/O pad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) * @id: Tegra I/O pad ID for which to disable power
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) * Returns: 0 on success or a negative error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) int tegra_io_pad_power_disable(enum tegra_io_pad id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) unsigned long request, status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) u32 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) mutex_lock(&pmc->powergates_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) err = tegra_io_pad_prepare(pmc, id, &request, &status, &mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) dev_err(pmc->dev, "failed to prepare I/O pad: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) tegra_pmc_writel(pmc, IO_DPD_REQ_CODE_ON | mask, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) err = tegra_io_pad_poll(pmc, status, mask, mask, 250);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) dev_err(pmc->dev, "failed to disable I/O pad: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) tegra_io_pad_unprepare(pmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) mutex_unlock(&pmc->powergates_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) EXPORT_SYMBOL(tegra_io_pad_power_disable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) static int tegra_io_pad_is_powered(struct tegra_pmc *pmc, enum tegra_io_pad id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) unsigned long request, status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) u32 mask, value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) err = tegra_io_pad_get_dpd_register_bit(pmc, id, &request, &status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) &mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) value = tegra_pmc_readl(pmc, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) return !(value & mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) static int tegra_io_pad_set_voltage(struct tegra_pmc *pmc, enum tegra_io_pad id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) int voltage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) const struct tegra_io_pad_soc *pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) pad = tegra_io_pad_find(pmc, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) if (!pad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) if (pad->voltage == UINT_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) mutex_lock(&pmc->powergates_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) if (pmc->soc->has_impl_33v_pwr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) value = tegra_pmc_readl(pmc, PMC_IMPL_E_33V_PWR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) if (voltage == TEGRA_IO_PAD_VOLTAGE_1V8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) value &= ~BIT(pad->voltage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) value |= BIT(pad->voltage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) tegra_pmc_writel(pmc, value, PMC_IMPL_E_33V_PWR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) /* write-enable PMC_PWR_DET_VALUE[pad->voltage] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) value = tegra_pmc_readl(pmc, PMC_PWR_DET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) value |= BIT(pad->voltage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) tegra_pmc_writel(pmc, value, PMC_PWR_DET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) /* update I/O voltage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) value = tegra_pmc_readl(pmc, PMC_PWR_DET_VALUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) if (voltage == TEGRA_IO_PAD_VOLTAGE_1V8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) value &= ~BIT(pad->voltage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) value |= BIT(pad->voltage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) tegra_pmc_writel(pmc, value, PMC_PWR_DET_VALUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) mutex_unlock(&pmc->powergates_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) usleep_range(100, 250);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) static int tegra_io_pad_get_voltage(struct tegra_pmc *pmc, enum tegra_io_pad id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) const struct tegra_io_pad_soc *pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) pad = tegra_io_pad_find(pmc, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) if (!pad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) if (pad->voltage == UINT_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) if (pmc->soc->has_impl_33v_pwr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) value = tegra_pmc_readl(pmc, PMC_IMPL_E_33V_PWR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) value = tegra_pmc_readl(pmc, PMC_PWR_DET_VALUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) if ((value & BIT(pad->voltage)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) return TEGRA_IO_PAD_VOLTAGE_1V8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) return TEGRA_IO_PAD_VOLTAGE_3V3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) * tegra_io_rail_power_on() - enable power to I/O rail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) * @id: Tegra I/O pad ID for which to enable power
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) * See also: tegra_io_pad_power_enable()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) int tegra_io_rail_power_on(unsigned int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) return tegra_io_pad_power_enable(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) EXPORT_SYMBOL(tegra_io_rail_power_on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) * tegra_io_rail_power_off() - disable power to I/O rail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) * @id: Tegra I/O pad ID for which to disable power
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) * See also: tegra_io_pad_power_disable()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) int tegra_io_rail_power_off(unsigned int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) return tegra_io_pad_power_disable(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) EXPORT_SYMBOL(tegra_io_rail_power_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) enum tegra_suspend_mode tegra_pmc_get_suspend_mode(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) return pmc->suspend_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) void tegra_pmc_set_suspend_mode(enum tegra_suspend_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) if (mode < TEGRA_SUSPEND_NONE || mode >= TEGRA_MAX_SUSPEND_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) pmc->suspend_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) void tegra_pmc_enter_suspend_mode(enum tegra_suspend_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) unsigned long long rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) u64 ticks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) case TEGRA_SUSPEND_LP1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) rate = 32768;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) case TEGRA_SUSPEND_LP2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) rate = pmc->rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) if (WARN_ON_ONCE(rate == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) rate = 100000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) ticks = pmc->cpu_good_time * rate + USEC_PER_SEC - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) do_div(ticks, USEC_PER_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) tegra_pmc_writel(pmc, ticks, PMC_CPUPWRGOOD_TIMER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) ticks = pmc->cpu_off_time * rate + USEC_PER_SEC - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) do_div(ticks, USEC_PER_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) tegra_pmc_writel(pmc, ticks, PMC_CPUPWROFF_TIMER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) value = tegra_pmc_readl(pmc, PMC_CNTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) value &= ~PMC_CNTRL_SIDE_EFFECT_LP0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) value |= PMC_CNTRL_CPU_PWRREQ_OE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) tegra_pmc_writel(pmc, value, PMC_CNTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) static int tegra_pmc_parse_dt(struct tegra_pmc *pmc, struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) u32 value, values[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) if (of_property_read_u32(np, "nvidia,suspend-mode", &value)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) switch (value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) pmc->suspend_mode = TEGRA_SUSPEND_LP0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) pmc->suspend_mode = TEGRA_SUSPEND_LP1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) pmc->suspend_mode = TEGRA_SUSPEND_LP2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) pmc->suspend_mode = TEGRA_SUSPEND_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) pmc->suspend_mode = tegra_pm_validate_suspend_mode(pmc->suspend_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) if (of_property_read_u32(np, "nvidia,cpu-pwr-good-time", &value))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) pmc->suspend_mode = TEGRA_SUSPEND_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) pmc->cpu_good_time = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) if (of_property_read_u32(np, "nvidia,cpu-pwr-off-time", &value))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) pmc->suspend_mode = TEGRA_SUSPEND_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) pmc->cpu_off_time = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) if (of_property_read_u32_array(np, "nvidia,core-pwr-good-time",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) values, ARRAY_SIZE(values)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) pmc->suspend_mode = TEGRA_SUSPEND_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) pmc->core_osc_time = values[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) pmc->core_pmu_time = values[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) if (of_property_read_u32(np, "nvidia,core-pwr-off-time", &value))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) pmc->suspend_mode = TEGRA_SUSPEND_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) pmc->core_off_time = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) pmc->corereq_high = of_property_read_bool(np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) "nvidia,core-power-req-active-high");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) pmc->sysclkreq_high = of_property_read_bool(np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) "nvidia,sys-clock-req-active-high");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) pmc->combined_req = of_property_read_bool(np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) "nvidia,combined-power-req");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) pmc->cpu_pwr_good_en = of_property_read_bool(np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) "nvidia,cpu-pwr-good-en");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) if (of_property_read_u32_array(np, "nvidia,lp0-vec", values,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) ARRAY_SIZE(values)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) if (pmc->suspend_mode == TEGRA_SUSPEND_LP0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) pmc->suspend_mode = TEGRA_SUSPEND_LP1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) pmc->lp0_vec_phys = values[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) pmc->lp0_vec_size = values[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) static void tegra_pmc_init(struct tegra_pmc *pmc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) if (pmc->soc->init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) pmc->soc->init(pmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) static void tegra_pmc_init_tsense_reset(struct tegra_pmc *pmc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) static const char disabled[] = "emergency thermal reset disabled";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) u32 pmu_addr, ctrl_id, reg_addr, reg_data, pinmux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) struct device *dev = pmc->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) u32 value, checksum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) if (!pmc->soc->has_tsense_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) np = of_get_child_by_name(pmc->dev->of_node, "i2c-thermtrip");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) if (!np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) dev_warn(dev, "i2c-thermtrip node not found, %s.\n", disabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) if (of_property_read_u32(np, "nvidia,i2c-controller-id", &ctrl_id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) dev_err(dev, "I2C controller ID missing, %s.\n", disabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) if (of_property_read_u32(np, "nvidia,bus-addr", &pmu_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) dev_err(dev, "nvidia,bus-addr missing, %s.\n", disabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) if (of_property_read_u32(np, "nvidia,reg-addr", ®_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) dev_err(dev, "nvidia,reg-addr missing, %s.\n", disabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) if (of_property_read_u32(np, "nvidia,reg-data", ®_data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) dev_err(dev, "nvidia,reg-data missing, %s.\n", disabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) if (of_property_read_u32(np, "nvidia,pinmux-id", &pinmux))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) pinmux = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) value = tegra_pmc_readl(pmc, PMC_SENSOR_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) value |= PMC_SENSOR_CTRL_SCRATCH_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) tegra_pmc_writel(pmc, value, PMC_SENSOR_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) value = (reg_data << PMC_SCRATCH54_DATA_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) (reg_addr << PMC_SCRATCH54_ADDR_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) tegra_pmc_writel(pmc, value, PMC_SCRATCH54);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) value = PMC_SCRATCH55_RESET_TEGRA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) value |= ctrl_id << PMC_SCRATCH55_CNTRL_ID_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) value |= pinmux << PMC_SCRATCH55_PINMUX_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) value |= pmu_addr << PMC_SCRATCH55_I2CSLV1_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) * Calculate checksum of SCRATCH54, SCRATCH55 fields. Bits 23:16 will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) * contain the checksum and are currently zero, so they are not added.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) checksum = reg_addr + reg_data + (value & 0xff) + ((value >> 8) & 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) + ((value >> 24) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) checksum &= 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) checksum = 0x100 - checksum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) value |= checksum << PMC_SCRATCH55_CHECKSUM_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) tegra_pmc_writel(pmc, value, PMC_SCRATCH55);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) value = tegra_pmc_readl(pmc, PMC_SENSOR_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) value |= PMC_SENSOR_CTRL_ENABLE_RST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) tegra_pmc_writel(pmc, value, PMC_SENSOR_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) dev_info(pmc->dev, "emergency thermal reset enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) static int tegra_io_pad_pinctrl_get_groups_count(struct pinctrl_dev *pctl_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) struct tegra_pmc *pmc = pinctrl_dev_get_drvdata(pctl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) return pmc->soc->num_io_pads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) static const char *tegra_io_pad_pinctrl_get_group_name(struct pinctrl_dev *pctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) unsigned int group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) struct tegra_pmc *pmc = pinctrl_dev_get_drvdata(pctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) return pmc->soc->io_pads[group].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) static int tegra_io_pad_pinctrl_get_group_pins(struct pinctrl_dev *pctl_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) unsigned int group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) const unsigned int **pins,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) unsigned int *num_pins)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) struct tegra_pmc *pmc = pinctrl_dev_get_drvdata(pctl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) *pins = &pmc->soc->io_pads[group].id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) *num_pins = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) static const struct pinctrl_ops tegra_io_pad_pinctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) .get_groups_count = tegra_io_pad_pinctrl_get_groups_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) .get_group_name = tegra_io_pad_pinctrl_get_group_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) .get_group_pins = tegra_io_pad_pinctrl_get_group_pins,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) .dt_free_map = pinconf_generic_dt_free_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) static int tegra_io_pad_pinconf_get(struct pinctrl_dev *pctl_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) unsigned int pin, unsigned long *config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) enum pin_config_param param = pinconf_to_config_param(*config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) struct tegra_pmc *pmc = pinctrl_dev_get_drvdata(pctl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) const struct tegra_io_pad_soc *pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) u32 arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) pad = tegra_io_pad_find(pmc, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) if (!pad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) switch (param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) case PIN_CONFIG_POWER_SOURCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) ret = tegra_io_pad_get_voltage(pmc, pad->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) arg = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) case PIN_CONFIG_LOW_POWER_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) ret = tegra_io_pad_is_powered(pmc, pad->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) arg = !ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) *config = pinconf_to_config_packed(param, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) static int tegra_io_pad_pinconf_set(struct pinctrl_dev *pctl_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) unsigned int pin, unsigned long *configs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) unsigned int num_configs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) struct tegra_pmc *pmc = pinctrl_dev_get_drvdata(pctl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) const struct tegra_io_pad_soc *pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) enum pin_config_param param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) u32 arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) pad = tegra_io_pad_find(pmc, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) if (!pad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) for (i = 0; i < num_configs; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) param = pinconf_to_config_param(configs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) arg = pinconf_to_config_argument(configs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) switch (param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) case PIN_CONFIG_LOW_POWER_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) if (arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) err = tegra_io_pad_power_disable(pad->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) err = tegra_io_pad_power_enable(pad->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) case PIN_CONFIG_POWER_SOURCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) if (arg != TEGRA_IO_PAD_VOLTAGE_1V8 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) arg != TEGRA_IO_PAD_VOLTAGE_3V3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) err = tegra_io_pad_set_voltage(pmc, pad->id, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) static const struct pinconf_ops tegra_io_pad_pinconf_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) .pin_config_get = tegra_io_pad_pinconf_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) .pin_config_set = tegra_io_pad_pinconf_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) .is_generic = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) static struct pinctrl_desc tegra_pmc_pctl_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) .pctlops = &tegra_io_pad_pinctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) .confops = &tegra_io_pad_pinconf_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) static int tegra_pmc_pinctrl_init(struct tegra_pmc *pmc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) if (!pmc->soc->num_pin_descs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) tegra_pmc_pctl_desc.name = dev_name(pmc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) tegra_pmc_pctl_desc.pins = pmc->soc->pin_descs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) tegra_pmc_pctl_desc.npins = pmc->soc->num_pin_descs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) pmc->pctl_dev = devm_pinctrl_register(pmc->dev, &tegra_pmc_pctl_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) pmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) if (IS_ERR(pmc->pctl_dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) err = PTR_ERR(pmc->pctl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) dev_err(pmc->dev, "failed to register pin controller: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) static ssize_t reset_reason_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) value = tegra_pmc_readl(pmc, pmc->soc->regs->rst_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) value &= pmc->soc->regs->rst_source_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) value >>= pmc->soc->regs->rst_source_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) if (WARN_ON(value >= pmc->soc->num_reset_sources))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) return sprintf(buf, "%s\n", "UNKNOWN");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) return sprintf(buf, "%s\n", pmc->soc->reset_sources[value]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) static DEVICE_ATTR_RO(reset_reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) static ssize_t reset_level_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) value = tegra_pmc_readl(pmc, pmc->soc->regs->rst_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) value &= pmc->soc->regs->rst_level_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) value >>= pmc->soc->regs->rst_level_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) if (WARN_ON(value >= pmc->soc->num_reset_levels))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) return sprintf(buf, "%s\n", "UNKNOWN");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) return sprintf(buf, "%s\n", pmc->soc->reset_levels[value]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) static DEVICE_ATTR_RO(reset_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) static void tegra_pmc_reset_sysfs_init(struct tegra_pmc *pmc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) struct device *dev = pmc->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) if (pmc->soc->reset_sources) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) err = device_create_file(dev, &dev_attr_reset_reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) dev_warn(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) "failed to create attr \"reset_reason\": %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) if (pmc->soc->reset_levels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) err = device_create_file(dev, &dev_attr_reset_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) dev_warn(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) "failed to create attr \"reset_level\": %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) static int tegra_pmc_irq_translate(struct irq_domain *domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) struct irq_fwspec *fwspec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) unsigned long *hwirq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) unsigned int *type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) if (WARN_ON(fwspec->param_count < 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) *hwirq = fwspec->param[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) *type = fwspec->param[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) static int tegra_pmc_irq_alloc(struct irq_domain *domain, unsigned int virq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) unsigned int num_irqs, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) struct tegra_pmc *pmc = domain->host_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) const struct tegra_pmc_soc *soc = pmc->soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) struct irq_fwspec *fwspec = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) if (WARN_ON(num_irqs > 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) for (i = 0; i < soc->num_wake_events; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) const struct tegra_wake_event *event = &soc->wake_events[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) if (fwspec->param_count == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) struct irq_fwspec spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) if (event->id != fwspec->param[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) err = irq_domain_set_hwirq_and_chip(domain, virq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) event->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) &pmc->irq, pmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) spec.fwnode = &pmc->dev->of_node->fwnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) spec.param_count = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) spec.param[0] = GIC_SPI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) spec.param[1] = event->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) spec.param[2] = fwspec->param[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) err = irq_domain_alloc_irqs_parent(domain, virq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) num_irqs, &spec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) if (fwspec->param_count == 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) if (event->gpio.instance != fwspec->param[0] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) event->gpio.pin != fwspec->param[1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) err = irq_domain_set_hwirq_and_chip(domain, virq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) event->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) &pmc->irq, pmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) /* GPIO hierarchies stop at the PMC level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) if (!err && domain->parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) err = irq_domain_disconnect_hierarchy(domain->parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) virq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) /* If there is no wake-up event, there is no PMC mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) if (i == soc->num_wake_events)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) err = irq_domain_disconnect_hierarchy(domain, virq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) static const struct irq_domain_ops tegra_pmc_irq_domain_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) .translate = tegra_pmc_irq_translate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) .alloc = tegra_pmc_irq_alloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) static int tegra210_pmc_irq_set_wake(struct irq_data *data, unsigned int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) struct tegra_pmc *pmc = irq_data_get_irq_chip_data(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) unsigned int offset, bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) offset = data->hwirq / 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) bit = data->hwirq % 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) /* clear wake status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) tegra_pmc_writel(pmc, 0, PMC_SW_WAKE_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) tegra_pmc_writel(pmc, 0, PMC_SW_WAKE2_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) tegra_pmc_writel(pmc, 0, PMC_WAKE_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) tegra_pmc_writel(pmc, 0, PMC_WAKE2_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) /* enable PMC wake */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) if (data->hwirq >= 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) offset = PMC_WAKE2_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) offset = PMC_WAKE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) value = tegra_pmc_readl(pmc, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) if (on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) value |= BIT(bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) value &= ~BIT(bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) tegra_pmc_writel(pmc, value, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) static int tegra210_pmc_irq_set_type(struct irq_data *data, unsigned int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) struct tegra_pmc *pmc = irq_data_get_irq_chip_data(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) unsigned int offset, bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) offset = data->hwirq / 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) bit = data->hwirq % 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) if (data->hwirq >= 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) offset = PMC_WAKE2_LEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) offset = PMC_WAKE_LEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) value = tegra_pmc_readl(pmc, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) case IRQ_TYPE_EDGE_RISING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) case IRQ_TYPE_LEVEL_HIGH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) value |= BIT(bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) case IRQ_TYPE_EDGE_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) case IRQ_TYPE_LEVEL_LOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) value &= ~BIT(bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) case IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) value ^= BIT(bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) tegra_pmc_writel(pmc, value, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) static int tegra186_pmc_irq_set_wake(struct irq_data *data, unsigned int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) struct tegra_pmc *pmc = irq_data_get_irq_chip_data(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) unsigned int offset, bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) offset = data->hwirq / 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) bit = data->hwirq % 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) /* clear wake status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) writel(0x1, pmc->wake + WAKE_AOWAKE_STATUS_W(data->hwirq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) /* route wake to tier 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) value = readl(pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) if (!on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) value &= ~(1 << bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) value |= 1 << bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) writel(value, pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) /* enable wakeup event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) writel(!!on, pmc->wake + WAKE_AOWAKE_MASK_W(data->hwirq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) static int tegra186_pmc_irq_set_type(struct irq_data *data, unsigned int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) struct tegra_pmc *pmc = irq_data_get_irq_chip_data(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) value = readl(pmc->wake + WAKE_AOWAKE_CNTRL(data->hwirq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) case IRQ_TYPE_EDGE_RISING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) case IRQ_TYPE_LEVEL_HIGH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) value |= WAKE_AOWAKE_CNTRL_LEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) case IRQ_TYPE_EDGE_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) case IRQ_TYPE_LEVEL_LOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) value &= ~WAKE_AOWAKE_CNTRL_LEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) case IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) value ^= WAKE_AOWAKE_CNTRL_LEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) writel(value, pmc->wake + WAKE_AOWAKE_CNTRL(data->hwirq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) static void tegra_irq_mask_parent(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) if (data->parent_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) irq_chip_mask_parent(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) static void tegra_irq_unmask_parent(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) if (data->parent_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) irq_chip_unmask_parent(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) static void tegra_irq_eoi_parent(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) if (data->parent_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) irq_chip_eoi_parent(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) static int tegra_irq_set_affinity_parent(struct irq_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) const struct cpumask *dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) bool force)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) if (data->parent_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) return irq_chip_set_affinity_parent(data, dest, force);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) static int tegra_pmc_irq_init(struct tegra_pmc *pmc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) struct irq_domain *parent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) np = of_irq_find_parent(pmc->dev->of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) if (np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) parent = irq_find_host(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) if (!parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) pmc->irq.name = dev_name(pmc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) pmc->irq.irq_mask = tegra_irq_mask_parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) pmc->irq.irq_unmask = tegra_irq_unmask_parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) pmc->irq.irq_eoi = tegra_irq_eoi_parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) pmc->irq.irq_set_affinity = tegra_irq_set_affinity_parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) pmc->irq.irq_set_type = pmc->soc->irq_set_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) pmc->irq.irq_set_wake = pmc->soc->irq_set_wake;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) pmc->domain = irq_domain_add_hierarchy(parent, 0, 96, pmc->dev->of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) &tegra_pmc_irq_domain_ops, pmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) if (!pmc->domain) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) dev_err(pmc->dev, "failed to allocate domain\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) static int tegra_pmc_clk_notify_cb(struct notifier_block *nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) unsigned long action, void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) struct tegra_pmc *pmc = container_of(nb, struct tegra_pmc, clk_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) struct clk_notifier_data *data = ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) switch (action) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) case PRE_RATE_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) mutex_lock(&pmc->powergates_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) case POST_RATE_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) pmc->rate = data->new_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) case ABORT_RATE_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) mutex_unlock(&pmc->powergates_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) return notifier_from_errno(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) return NOTIFY_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) static void pmc_clk_fence_udelay(u32 offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) tegra_pmc_readl(pmc, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) /* pmc clk propagation delay 2 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) udelay(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) static u8 pmc_clk_mux_get_parent(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) struct pmc_clk *clk = to_pmc_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) val = tegra_pmc_readl(pmc, clk->offs) >> clk->mux_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) val &= PMC_CLK_OUT_MUX_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) static int pmc_clk_mux_set_parent(struct clk_hw *hw, u8 index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) struct pmc_clk *clk = to_pmc_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) val = tegra_pmc_readl(pmc, clk->offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) val &= ~(PMC_CLK_OUT_MUX_MASK << clk->mux_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) val |= index << clk->mux_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) tegra_pmc_writel(pmc, val, clk->offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) pmc_clk_fence_udelay(clk->offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) static int pmc_clk_is_enabled(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) struct pmc_clk *clk = to_pmc_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) val = tegra_pmc_readl(pmc, clk->offs) & BIT(clk->force_en_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) return val ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) static void pmc_clk_set_state(unsigned long offs, u32 shift, int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) val = tegra_pmc_readl(pmc, offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) val = state ? (val | BIT(shift)) : (val & ~BIT(shift));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) tegra_pmc_writel(pmc, val, offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) pmc_clk_fence_udelay(offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) static int pmc_clk_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) struct pmc_clk *clk = to_pmc_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) pmc_clk_set_state(clk->offs, clk->force_en_shift, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) static void pmc_clk_disable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) struct pmc_clk *clk = to_pmc_clk(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) pmc_clk_set_state(clk->offs, clk->force_en_shift, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) static const struct clk_ops pmc_clk_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) .get_parent = pmc_clk_mux_get_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) .set_parent = pmc_clk_mux_set_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) .determine_rate = __clk_mux_determine_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) .is_enabled = pmc_clk_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) .enable = pmc_clk_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) .disable = pmc_clk_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) static struct clk *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) tegra_pmc_clk_out_register(struct tegra_pmc *pmc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) const struct pmc_clk_init_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) unsigned long offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) struct clk_init_data init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) struct pmc_clk *pmc_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) pmc_clk = devm_kzalloc(pmc->dev, sizeof(*pmc_clk), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) if (!pmc_clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) init.name = data->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) init.ops = &pmc_clk_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) init.parent_names = data->parents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) init.num_parents = data->num_parents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) init.flags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) CLK_SET_PARENT_GATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) pmc_clk->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) pmc_clk->offs = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) pmc_clk->mux_shift = data->mux_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) pmc_clk->force_en_shift = data->force_en_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) return clk_register(NULL, &pmc_clk->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) static int pmc_clk_gate_is_enabled(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) struct pmc_clk_gate *gate = to_pmc_clk_gate(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) return tegra_pmc_readl(pmc, gate->offs) & BIT(gate->shift) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) static int pmc_clk_gate_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) struct pmc_clk_gate *gate = to_pmc_clk_gate(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) pmc_clk_set_state(gate->offs, gate->shift, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) static void pmc_clk_gate_disable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) struct pmc_clk_gate *gate = to_pmc_clk_gate(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) pmc_clk_set_state(gate->offs, gate->shift, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) static const struct clk_ops pmc_clk_gate_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) .is_enabled = pmc_clk_gate_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) .enable = pmc_clk_gate_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) .disable = pmc_clk_gate_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) static struct clk *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) tegra_pmc_clk_gate_register(struct tegra_pmc *pmc, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) const char *parent_name, unsigned long offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) u32 shift)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) struct clk_init_data init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) struct pmc_clk_gate *gate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) gate = devm_kzalloc(pmc->dev, sizeof(*gate), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) if (!gate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) init.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) init.ops = &pmc_clk_gate_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) init.parent_names = &parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) init.num_parents = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) init.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) gate->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) gate->offs = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) gate->shift = shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) return clk_register(NULL, &gate->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) static void tegra_pmc_clock_register(struct tegra_pmc *pmc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) struct clk_onecell_data *clk_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) unsigned int num_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) num_clks = pmc->soc->num_pmc_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) if (pmc->soc->has_blink_output)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) num_clks += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) if (!num_clks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) clk_data = devm_kmalloc(pmc->dev, sizeof(*clk_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) if (!clk_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) clk_data->clks = devm_kcalloc(pmc->dev, TEGRA_PMC_CLK_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) sizeof(*clk_data->clks), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) if (!clk_data->clks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) clk_data->clk_num = TEGRA_PMC_CLK_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) for (i = 0; i < TEGRA_PMC_CLK_MAX; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) clk_data->clks[i] = ERR_PTR(-ENOENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) for (i = 0; i < pmc->soc->num_pmc_clks; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) const struct pmc_clk_init_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) data = pmc->soc->pmc_clks_data + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) clk = tegra_pmc_clk_out_register(pmc, data, PMC_CLK_OUT_CNTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) if (IS_ERR(clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) dev_warn(pmc->dev, "unable to register clock %s: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) data->name, PTR_ERR_OR_ZERO(clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) err = clk_register_clkdev(clk, data->name, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) dev_warn(pmc->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) "unable to register %s clock lookup: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) data->name, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) clk_data->clks[data->clk_id] = clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) if (pmc->soc->has_blink_output) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) tegra_pmc_writel(pmc, 0x0, PMC_BLINK_TIMER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) clk = tegra_pmc_clk_gate_register(pmc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) "pmc_blink_override",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) "clk_32k",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) PMC_DPD_PADS_ORIDE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) PMC_DPD_PADS_ORIDE_BLINK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) if (IS_ERR(clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) dev_warn(pmc->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) "unable to register pmc_blink_override: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) PTR_ERR_OR_ZERO(clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) clk = tegra_pmc_clk_gate_register(pmc, "pmc_blink",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) "pmc_blink_override",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) PMC_CNTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) PMC_CNTRL_BLINK_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) if (IS_ERR(clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) dev_warn(pmc->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) "unable to register pmc_blink: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) PTR_ERR_OR_ZERO(clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) err = clk_register_clkdev(clk, "pmc_blink", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) dev_warn(pmc->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) "unable to register pmc_blink lookup: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) clk_data->clks[TEGRA_PMC_CLK_BLINK] = clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) err = of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) dev_warn(pmc->dev, "failed to add pmc clock provider: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) static int tegra_pmc_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) * Early initialisation should have configured an initial
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) * register mapping and setup the soc data pointer. If these
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) * are not valid then something went badly wrong!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) if (WARN_ON(!pmc->base || !pmc->soc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) err = tegra_pmc_parse_dt(pmc, pdev->dev.of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) /* take over the memory region from the early initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) base = devm_ioremap_resource(&pdev->dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) if (IS_ERR(base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) return PTR_ERR(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "wake");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) if (res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) pmc->wake = devm_ioremap_resource(&pdev->dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) if (IS_ERR(pmc->wake))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) return PTR_ERR(pmc->wake);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) pmc->wake = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "aotag");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) if (res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) pmc->aotag = devm_ioremap_resource(&pdev->dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) if (IS_ERR(pmc->aotag))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) return PTR_ERR(pmc->aotag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) pmc->aotag = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "scratch");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) if (res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) pmc->scratch = devm_ioremap_resource(&pdev->dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) if (IS_ERR(pmc->scratch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) return PTR_ERR(pmc->scratch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) pmc->scratch = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) pmc->clk = devm_clk_get(&pdev->dev, "pclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) if (IS_ERR(pmc->clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) err = PTR_ERR(pmc->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) if (err != -ENOENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) dev_err(&pdev->dev, "failed to get pclk: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) pmc->clk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) * PCLK clock rate can't be retrieved using CLK API because it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) * causes lockup if CPU enters LP2 idle state from some other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) * CLK notifier, hence we're caching the rate's value locally.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) if (pmc->clk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) pmc->clk_nb.notifier_call = tegra_pmc_clk_notify_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) err = clk_notifier_register(pmc->clk, &pmc->clk_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) dev_err(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) "failed to register clk notifier\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) pmc->rate = clk_get_rate(pmc->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) pmc->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) tegra_pmc_init(pmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) tegra_pmc_init_tsense_reset(pmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) tegra_pmc_reset_sysfs_init(pmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) if (IS_ENABLED(CONFIG_DEBUG_FS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) err = tegra_powergate_debugfs_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) goto cleanup_sysfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) err = register_restart_handler(&tegra_pmc_restart_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) dev_err(&pdev->dev, "unable to register restart handler, %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) goto cleanup_debugfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) err = tegra_pmc_pinctrl_init(pmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) goto cleanup_restart_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) err = tegra_powergate_init(pmc, pdev->dev.of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) goto cleanup_powergates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) err = tegra_pmc_irq_init(pmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) goto cleanup_powergates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) mutex_lock(&pmc->powergates_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) iounmap(pmc->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) pmc->base = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) mutex_unlock(&pmc->powergates_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) tegra_pmc_clock_register(pmc, pdev->dev.of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) platform_set_drvdata(pdev, pmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) cleanup_powergates:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) tegra_powergate_remove_all(pdev->dev.of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) cleanup_restart_handler:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) unregister_restart_handler(&tegra_pmc_restart_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) cleanup_debugfs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) debugfs_remove(pmc->debugfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) cleanup_sysfs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) device_remove_file(&pdev->dev, &dev_attr_reset_reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) device_remove_file(&pdev->dev, &dev_attr_reset_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) clk_notifier_unregister(pmc->clk, &pmc->clk_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) static int tegra_pmc_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) struct tegra_pmc *pmc = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) tegra_pmc_writel(pmc, virt_to_phys(tegra_resume), PMC_SCRATCH41);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) static int tegra_pmc_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) struct tegra_pmc *pmc = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) tegra_pmc_writel(pmc, 0x0, PMC_SCRATCH41);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) static SIMPLE_DEV_PM_OPS(tegra_pmc_pm_ops, tegra_pmc_suspend, tegra_pmc_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) static const char * const tegra20_powergates[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) [TEGRA_POWERGATE_CPU] = "cpu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) [TEGRA_POWERGATE_3D] = "3d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) [TEGRA_POWERGATE_VENC] = "venc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) [TEGRA_POWERGATE_VDEC] = "vdec",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) [TEGRA_POWERGATE_PCIE] = "pcie",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) [TEGRA_POWERGATE_L2] = "l2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) [TEGRA_POWERGATE_MPE] = "mpe",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) static const struct tegra_pmc_regs tegra20_pmc_regs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) .scratch0 = 0x50,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) .dpd_req = 0x1b8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) .dpd_status = 0x1bc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) .dpd2_req = 0x1c0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) .dpd2_status = 0x1c4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) .rst_status = 0x1b4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) .rst_source_shift = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) .rst_source_mask = 0x7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) .rst_level_shift = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) .rst_level_mask = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) static void tegra20_pmc_init(struct tegra_pmc *pmc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) u32 value, osc, pmu, off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) /* Always enable CPU power request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) value = tegra_pmc_readl(pmc, PMC_CNTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) value |= PMC_CNTRL_CPU_PWRREQ_OE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) tegra_pmc_writel(pmc, value, PMC_CNTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) value = tegra_pmc_readl(pmc, PMC_CNTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) if (pmc->sysclkreq_high)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) value &= ~PMC_CNTRL_SYSCLK_POLARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) value |= PMC_CNTRL_SYSCLK_POLARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) if (pmc->corereq_high)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) value &= ~PMC_CNTRL_PWRREQ_POLARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) value |= PMC_CNTRL_PWRREQ_POLARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) /* configure the output polarity while the request is tristated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) tegra_pmc_writel(pmc, value, PMC_CNTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) /* now enable the request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) value = tegra_pmc_readl(pmc, PMC_CNTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) value |= PMC_CNTRL_SYSCLK_OE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) tegra_pmc_writel(pmc, value, PMC_CNTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) /* program core timings which are applicable only for suspend state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) if (pmc->suspend_mode != TEGRA_SUSPEND_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) osc = DIV_ROUND_UP(pmc->core_osc_time * 8192, 1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) pmu = DIV_ROUND_UP(pmc->core_pmu_time * 32768, 1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) off = DIV_ROUND_UP(pmc->core_off_time * 32768, 1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) tegra_pmc_writel(pmc, ((osc << 8) & 0xff00) | (pmu & 0xff),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) PMC_COREPWRGOOD_TIMER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) tegra_pmc_writel(pmc, off, PMC_COREPWROFF_TIMER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) static void tegra20_pmc_setup_irq_polarity(struct tegra_pmc *pmc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) bool invert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) value = tegra_pmc_readl(pmc, PMC_CNTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) if (invert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) value |= PMC_CNTRL_INTR_POLARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) value &= ~PMC_CNTRL_INTR_POLARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) tegra_pmc_writel(pmc, value, PMC_CNTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) static const struct tegra_pmc_soc tegra20_pmc_soc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) .num_powergates = ARRAY_SIZE(tegra20_powergates),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) .powergates = tegra20_powergates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) .num_cpu_powergates = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) .cpu_powergates = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) .has_tsense_reset = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) .has_gpu_clamps = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) .needs_mbist_war = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) .has_impl_33v_pwr = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) .maybe_tz_only = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) .num_io_pads = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) .io_pads = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) .num_pin_descs = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) .pin_descs = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) .regs = &tegra20_pmc_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) .init = tegra20_pmc_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) .setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) .powergate_set = tegra20_powergate_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) .reset_sources = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) .num_reset_sources = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) .reset_levels = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) .num_reset_levels = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) .pmc_clks_data = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) .num_pmc_clks = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) .has_blink_output = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) static const char * const tegra30_powergates[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) [TEGRA_POWERGATE_CPU] = "cpu0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) [TEGRA_POWERGATE_3D] = "3d0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) [TEGRA_POWERGATE_VENC] = "venc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) [TEGRA_POWERGATE_VDEC] = "vdec",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) [TEGRA_POWERGATE_PCIE] = "pcie",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) [TEGRA_POWERGATE_L2] = "l2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) [TEGRA_POWERGATE_MPE] = "mpe",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) [TEGRA_POWERGATE_HEG] = "heg",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) [TEGRA_POWERGATE_SATA] = "sata",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) [TEGRA_POWERGATE_CPU1] = "cpu1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) [TEGRA_POWERGATE_CPU2] = "cpu2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) [TEGRA_POWERGATE_CPU3] = "cpu3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) [TEGRA_POWERGATE_CELP] = "celp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) [TEGRA_POWERGATE_3D1] = "3d1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) static const u8 tegra30_cpu_powergates[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) TEGRA_POWERGATE_CPU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) TEGRA_POWERGATE_CPU1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) TEGRA_POWERGATE_CPU2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) TEGRA_POWERGATE_CPU3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) static const char * const tegra30_reset_sources[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) "POWER_ON_RESET",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) "WATCHDOG",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) "SENSOR",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) "SW_MAIN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) "LP0"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) static const struct tegra_pmc_soc tegra30_pmc_soc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) .num_powergates = ARRAY_SIZE(tegra30_powergates),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) .powergates = tegra30_powergates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) .num_cpu_powergates = ARRAY_SIZE(tegra30_cpu_powergates),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) .cpu_powergates = tegra30_cpu_powergates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) .has_tsense_reset = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) .has_gpu_clamps = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) .needs_mbist_war = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) .has_impl_33v_pwr = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) .maybe_tz_only = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) .num_io_pads = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) .io_pads = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) .num_pin_descs = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) .pin_descs = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) .regs = &tegra20_pmc_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) .init = tegra20_pmc_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) .setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) .powergate_set = tegra20_powergate_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) .reset_sources = tegra30_reset_sources,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) .num_reset_sources = ARRAY_SIZE(tegra30_reset_sources),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) .reset_levels = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) .num_reset_levels = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) .pmc_clks_data = tegra_pmc_clks_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) .num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) .has_blink_output = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) static const char * const tegra114_powergates[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) [TEGRA_POWERGATE_CPU] = "crail",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) [TEGRA_POWERGATE_3D] = "3d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) [TEGRA_POWERGATE_VENC] = "venc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) [TEGRA_POWERGATE_VDEC] = "vdec",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) [TEGRA_POWERGATE_MPE] = "mpe",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) [TEGRA_POWERGATE_HEG] = "heg",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) [TEGRA_POWERGATE_CPU1] = "cpu1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) [TEGRA_POWERGATE_CPU2] = "cpu2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) [TEGRA_POWERGATE_CPU3] = "cpu3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) [TEGRA_POWERGATE_CELP] = "celp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) [TEGRA_POWERGATE_CPU0] = "cpu0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) [TEGRA_POWERGATE_C0NC] = "c0nc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) [TEGRA_POWERGATE_C1NC] = "c1nc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) [TEGRA_POWERGATE_DIS] = "dis",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) [TEGRA_POWERGATE_DISB] = "disb",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) [TEGRA_POWERGATE_XUSBA] = "xusba",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) [TEGRA_POWERGATE_XUSBB] = "xusbb",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) [TEGRA_POWERGATE_XUSBC] = "xusbc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) static const u8 tegra114_cpu_powergates[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) TEGRA_POWERGATE_CPU0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) TEGRA_POWERGATE_CPU1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) TEGRA_POWERGATE_CPU2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) TEGRA_POWERGATE_CPU3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) static const struct tegra_pmc_soc tegra114_pmc_soc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) .num_powergates = ARRAY_SIZE(tegra114_powergates),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) .powergates = tegra114_powergates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) .num_cpu_powergates = ARRAY_SIZE(tegra114_cpu_powergates),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) .cpu_powergates = tegra114_cpu_powergates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) .has_tsense_reset = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) .has_gpu_clamps = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) .needs_mbist_war = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) .has_impl_33v_pwr = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) .maybe_tz_only = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) .num_io_pads = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) .io_pads = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) .num_pin_descs = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) .pin_descs = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) .regs = &tegra20_pmc_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) .init = tegra20_pmc_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) .setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) .powergate_set = tegra114_powergate_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) .reset_sources = tegra30_reset_sources,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) .num_reset_sources = ARRAY_SIZE(tegra30_reset_sources),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) .reset_levels = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) .num_reset_levels = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) .pmc_clks_data = tegra_pmc_clks_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) .num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) .has_blink_output = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) static const char * const tegra124_powergates[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) [TEGRA_POWERGATE_CPU] = "crail",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) [TEGRA_POWERGATE_3D] = "3d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) [TEGRA_POWERGATE_VENC] = "venc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) [TEGRA_POWERGATE_PCIE] = "pcie",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) [TEGRA_POWERGATE_VDEC] = "vdec",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) [TEGRA_POWERGATE_MPE] = "mpe",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) [TEGRA_POWERGATE_HEG] = "heg",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) [TEGRA_POWERGATE_SATA] = "sata",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) [TEGRA_POWERGATE_CPU1] = "cpu1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) [TEGRA_POWERGATE_CPU2] = "cpu2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) [TEGRA_POWERGATE_CPU3] = "cpu3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) [TEGRA_POWERGATE_CELP] = "celp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) [TEGRA_POWERGATE_CPU0] = "cpu0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) [TEGRA_POWERGATE_C0NC] = "c0nc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) [TEGRA_POWERGATE_C1NC] = "c1nc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) [TEGRA_POWERGATE_SOR] = "sor",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) [TEGRA_POWERGATE_DIS] = "dis",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) [TEGRA_POWERGATE_DISB] = "disb",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) [TEGRA_POWERGATE_XUSBA] = "xusba",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) [TEGRA_POWERGATE_XUSBB] = "xusbb",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) [TEGRA_POWERGATE_XUSBC] = "xusbc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) [TEGRA_POWERGATE_VIC] = "vic",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) [TEGRA_POWERGATE_IRAM] = "iram",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) static const u8 tegra124_cpu_powergates[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) TEGRA_POWERGATE_CPU0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) TEGRA_POWERGATE_CPU1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) TEGRA_POWERGATE_CPU2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) TEGRA_POWERGATE_CPU3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) #define TEGRA_IO_PAD(_id, _dpd, _voltage, _name) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) ((struct tegra_io_pad_soc) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) .id = (_id), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) .dpd = (_dpd), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) .voltage = (_voltage), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) .name = (_name), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) #define TEGRA_IO_PIN_DESC(_id, _dpd, _voltage, _name) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) ((struct pinctrl_pin_desc) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) .number = (_id), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) .name = (_name) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) #define TEGRA124_IO_PAD_TABLE(_pad) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) /* .id .dpd .voltage .name */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) _pad(TEGRA_IO_PAD_AUDIO, 17, UINT_MAX, "audio"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) _pad(TEGRA_IO_PAD_BB, 15, UINT_MAX, "bb"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) _pad(TEGRA_IO_PAD_CAM, 36, UINT_MAX, "cam"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) _pad(TEGRA_IO_PAD_COMP, 22, UINT_MAX, "comp"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) _pad(TEGRA_IO_PAD_CSIA, 0, UINT_MAX, "csia"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) _pad(TEGRA_IO_PAD_CSIB, 1, UINT_MAX, "csb"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) _pad(TEGRA_IO_PAD_CSIE, 44, UINT_MAX, "cse"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) _pad(TEGRA_IO_PAD_DSI, 2, UINT_MAX, "dsi"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) _pad(TEGRA_IO_PAD_DSIB, 39, UINT_MAX, "dsib"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) _pad(TEGRA_IO_PAD_DSIC, 40, UINT_MAX, "dsic"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) _pad(TEGRA_IO_PAD_DSID, 41, UINT_MAX, "dsid"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) _pad(TEGRA_IO_PAD_HDMI, 28, UINT_MAX, "hdmi"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) _pad(TEGRA_IO_PAD_HSIC, 19, UINT_MAX, "hsic"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) _pad(TEGRA_IO_PAD_HV, 38, UINT_MAX, "hv"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) _pad(TEGRA_IO_PAD_LVDS, 57, UINT_MAX, "lvds"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) _pad(TEGRA_IO_PAD_MIPI_BIAS, 3, UINT_MAX, "mipi-bias"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) _pad(TEGRA_IO_PAD_NAND, 13, UINT_MAX, "nand"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) _pad(TEGRA_IO_PAD_PEX_BIAS, 4, UINT_MAX, "pex-bias"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) _pad(TEGRA_IO_PAD_PEX_CLK1, 5, UINT_MAX, "pex-clk1"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) _pad(TEGRA_IO_PAD_PEX_CLK2, 6, UINT_MAX, "pex-clk2"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) _pad(TEGRA_IO_PAD_PEX_CNTRL, 32, UINT_MAX, "pex-cntrl"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) _pad(TEGRA_IO_PAD_SDMMC1, 33, UINT_MAX, "sdmmc1"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) _pad(TEGRA_IO_PAD_SDMMC3, 34, UINT_MAX, "sdmmc3"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) _pad(TEGRA_IO_PAD_SDMMC4, 35, UINT_MAX, "sdmmc4"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) _pad(TEGRA_IO_PAD_SYS_DDC, 58, UINT_MAX, "sys_ddc"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) _pad(TEGRA_IO_PAD_UART, 14, UINT_MAX, "uart"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) _pad(TEGRA_IO_PAD_USB0, 9, UINT_MAX, "usb0"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) _pad(TEGRA_IO_PAD_USB1, 10, UINT_MAX, "usb1"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) _pad(TEGRA_IO_PAD_USB2, 11, UINT_MAX, "usb2"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) _pad(TEGRA_IO_PAD_USB_BIAS, 12, UINT_MAX, "usb_bias")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) static const struct tegra_io_pad_soc tegra124_io_pads[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) TEGRA124_IO_PAD_TABLE(TEGRA_IO_PAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) static const struct pinctrl_pin_desc tegra124_pin_descs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) TEGRA124_IO_PAD_TABLE(TEGRA_IO_PIN_DESC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) static const struct tegra_pmc_soc tegra124_pmc_soc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) .num_powergates = ARRAY_SIZE(tegra124_powergates),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) .powergates = tegra124_powergates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) .num_cpu_powergates = ARRAY_SIZE(tegra124_cpu_powergates),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) .cpu_powergates = tegra124_cpu_powergates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) .has_tsense_reset = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) .has_gpu_clamps = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) .needs_mbist_war = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) .has_impl_33v_pwr = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) .maybe_tz_only = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) .num_io_pads = ARRAY_SIZE(tegra124_io_pads),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) .io_pads = tegra124_io_pads,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) .num_pin_descs = ARRAY_SIZE(tegra124_pin_descs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) .pin_descs = tegra124_pin_descs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) .regs = &tegra20_pmc_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) .init = tegra20_pmc_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) .setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) .powergate_set = tegra114_powergate_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) .reset_sources = tegra30_reset_sources,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) .num_reset_sources = ARRAY_SIZE(tegra30_reset_sources),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) .reset_levels = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) .num_reset_levels = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) .pmc_clks_data = tegra_pmc_clks_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) .num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) .has_blink_output = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) static const char * const tegra210_powergates[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) [TEGRA_POWERGATE_CPU] = "crail",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) [TEGRA_POWERGATE_3D] = "3d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) [TEGRA_POWERGATE_VENC] = "venc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) [TEGRA_POWERGATE_PCIE] = "pcie",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) [TEGRA_POWERGATE_MPE] = "mpe",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) [TEGRA_POWERGATE_SATA] = "sata",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) [TEGRA_POWERGATE_CPU1] = "cpu1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) [TEGRA_POWERGATE_CPU2] = "cpu2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) [TEGRA_POWERGATE_CPU3] = "cpu3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) [TEGRA_POWERGATE_CPU0] = "cpu0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) [TEGRA_POWERGATE_C0NC] = "c0nc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) [TEGRA_POWERGATE_SOR] = "sor",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) [TEGRA_POWERGATE_DIS] = "dis",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) [TEGRA_POWERGATE_DISB] = "disb",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) [TEGRA_POWERGATE_XUSBA] = "xusba",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) [TEGRA_POWERGATE_XUSBB] = "xusbb",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) [TEGRA_POWERGATE_XUSBC] = "xusbc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) [TEGRA_POWERGATE_VIC] = "vic",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) [TEGRA_POWERGATE_IRAM] = "iram",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) [TEGRA_POWERGATE_NVDEC] = "nvdec",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) [TEGRA_POWERGATE_NVJPG] = "nvjpg",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) [TEGRA_POWERGATE_AUD] = "aud",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) [TEGRA_POWERGATE_DFD] = "dfd",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) [TEGRA_POWERGATE_VE2] = "ve2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) static const u8 tegra210_cpu_powergates[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) TEGRA_POWERGATE_CPU0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) TEGRA_POWERGATE_CPU1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) TEGRA_POWERGATE_CPU2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) TEGRA_POWERGATE_CPU3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) #define TEGRA210_IO_PAD_TABLE(_pad) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) /* .id .dpd .voltage .name */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) _pad(TEGRA_IO_PAD_AUDIO, 17, 5, "audio"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) _pad(TEGRA_IO_PAD_AUDIO_HV, 61, 18, "audio-hv"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) _pad(TEGRA_IO_PAD_CAM, 36, 10, "cam"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) _pad(TEGRA_IO_PAD_CSIA, 0, UINT_MAX, "csia"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) _pad(TEGRA_IO_PAD_CSIB, 1, UINT_MAX, "csib"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) _pad(TEGRA_IO_PAD_CSIC, 42, UINT_MAX, "csic"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) _pad(TEGRA_IO_PAD_CSID, 43, UINT_MAX, "csid"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) _pad(TEGRA_IO_PAD_CSIE, 44, UINT_MAX, "csie"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) _pad(TEGRA_IO_PAD_CSIF, 45, UINT_MAX, "csif"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) _pad(TEGRA_IO_PAD_DBG, 25, 19, "dbg"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) _pad(TEGRA_IO_PAD_DEBUG_NONAO, 26, UINT_MAX, "debug-nonao"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) _pad(TEGRA_IO_PAD_DMIC, 50, 20, "dmic"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) _pad(TEGRA_IO_PAD_DP, 51, UINT_MAX, "dp"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) _pad(TEGRA_IO_PAD_DSI, 2, UINT_MAX, "dsi"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) _pad(TEGRA_IO_PAD_DSIB, 39, UINT_MAX, "dsib"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) _pad(TEGRA_IO_PAD_DSIC, 40, UINT_MAX, "dsic"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) _pad(TEGRA_IO_PAD_DSID, 41, UINT_MAX, "dsid"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) _pad(TEGRA_IO_PAD_EMMC, 35, UINT_MAX, "emmc"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) _pad(TEGRA_IO_PAD_EMMC2, 37, UINT_MAX, "emmc2"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) _pad(TEGRA_IO_PAD_GPIO, 27, 21, "gpio"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) _pad(TEGRA_IO_PAD_HDMI, 28, UINT_MAX, "hdmi"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) _pad(TEGRA_IO_PAD_HSIC, 19, UINT_MAX, "hsic"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) _pad(TEGRA_IO_PAD_LVDS, 57, UINT_MAX, "lvds"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) _pad(TEGRA_IO_PAD_MIPI_BIAS, 3, UINT_MAX, "mipi-bias"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) _pad(TEGRA_IO_PAD_PEX_BIAS, 4, UINT_MAX, "pex-bias"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) _pad(TEGRA_IO_PAD_PEX_CLK1, 5, UINT_MAX, "pex-clk1"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) _pad(TEGRA_IO_PAD_PEX_CLK2, 6, UINT_MAX, "pex-clk2"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) _pad(TEGRA_IO_PAD_PEX_CNTRL, UINT_MAX, 11, "pex-cntrl"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) _pad(TEGRA_IO_PAD_SDMMC1, 33, 12, "sdmmc1"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) _pad(TEGRA_IO_PAD_SDMMC3, 34, 13, "sdmmc3"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) _pad(TEGRA_IO_PAD_SPI, 46, 22, "spi"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) _pad(TEGRA_IO_PAD_SPI_HV, 47, 23, "spi-hv"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) _pad(TEGRA_IO_PAD_UART, 14, 2, "uart"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) _pad(TEGRA_IO_PAD_USB0, 9, UINT_MAX, "usb0"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) _pad(TEGRA_IO_PAD_USB1, 10, UINT_MAX, "usb1"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) _pad(TEGRA_IO_PAD_USB2, 11, UINT_MAX, "usb2"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) _pad(TEGRA_IO_PAD_USB3, 18, UINT_MAX, "usb3"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) _pad(TEGRA_IO_PAD_USB_BIAS, 12, UINT_MAX, "usb-bias")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) static const struct tegra_io_pad_soc tegra210_io_pads[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) TEGRA210_IO_PAD_TABLE(TEGRA_IO_PAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) static const struct pinctrl_pin_desc tegra210_pin_descs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) TEGRA210_IO_PAD_TABLE(TEGRA_IO_PIN_DESC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) static const char * const tegra210_reset_sources[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) "POWER_ON_RESET",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) "WATCHDOG",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) "SENSOR",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) "SW_MAIN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) "LP0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) "AOTAG"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) static const struct tegra_wake_event tegra210_wake_events[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) TEGRA_WAKE_IRQ("rtc", 16, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) TEGRA_WAKE_IRQ("pmu", 51, 86),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) static const struct tegra_pmc_soc tegra210_pmc_soc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) .num_powergates = ARRAY_SIZE(tegra210_powergates),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) .powergates = tegra210_powergates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) .num_cpu_powergates = ARRAY_SIZE(tegra210_cpu_powergates),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) .cpu_powergates = tegra210_cpu_powergates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) .has_tsense_reset = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) .has_gpu_clamps = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) .needs_mbist_war = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) .has_impl_33v_pwr = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) .maybe_tz_only = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) .num_io_pads = ARRAY_SIZE(tegra210_io_pads),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) .io_pads = tegra210_io_pads,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) .num_pin_descs = ARRAY_SIZE(tegra210_pin_descs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) .pin_descs = tegra210_pin_descs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) .regs = &tegra20_pmc_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) .init = tegra20_pmc_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) .setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) .powergate_set = tegra114_powergate_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) .irq_set_wake = tegra210_pmc_irq_set_wake,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) .irq_set_type = tegra210_pmc_irq_set_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) .reset_sources = tegra210_reset_sources,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) .num_reset_sources = ARRAY_SIZE(tegra210_reset_sources),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) .reset_levels = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) .num_reset_levels = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) .num_wake_events = ARRAY_SIZE(tegra210_wake_events),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) .wake_events = tegra210_wake_events,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) .pmc_clks_data = tegra_pmc_clks_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) .num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) .has_blink_output = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) #define TEGRA186_IO_PAD_TABLE(_pad) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) /* .id .dpd .voltage .name */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) _pad(TEGRA_IO_PAD_CSIA, 0, UINT_MAX, "csia"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) _pad(TEGRA_IO_PAD_CSIB, 1, UINT_MAX, "csib"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) _pad(TEGRA_IO_PAD_DSI, 2, UINT_MAX, "dsi"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) _pad(TEGRA_IO_PAD_MIPI_BIAS, 3, UINT_MAX, "mipi-bias"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) _pad(TEGRA_IO_PAD_PEX_CLK_BIAS, 4, UINT_MAX, "pex-clk-bias"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) _pad(TEGRA_IO_PAD_PEX_CLK3, 5, UINT_MAX, "pex-clk3"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) _pad(TEGRA_IO_PAD_PEX_CLK2, 6, UINT_MAX, "pex-clk2"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) _pad(TEGRA_IO_PAD_PEX_CLK1, 7, UINT_MAX, "pex-clk1"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) _pad(TEGRA_IO_PAD_USB0, 9, UINT_MAX, "usb0"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) _pad(TEGRA_IO_PAD_USB1, 10, UINT_MAX, "usb1"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) _pad(TEGRA_IO_PAD_USB2, 11, UINT_MAX, "usb2"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) _pad(TEGRA_IO_PAD_USB_BIAS, 12, UINT_MAX, "usb-bias"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) _pad(TEGRA_IO_PAD_UART, 14, UINT_MAX, "uart"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) _pad(TEGRA_IO_PAD_AUDIO, 17, UINT_MAX, "audio"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) _pad(TEGRA_IO_PAD_HSIC, 19, UINT_MAX, "hsic"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) _pad(TEGRA_IO_PAD_DBG, 25, UINT_MAX, "dbg"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) _pad(TEGRA_IO_PAD_HDMI_DP0, 28, UINT_MAX, "hdmi-dp0"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) _pad(TEGRA_IO_PAD_HDMI_DP1, 29, UINT_MAX, "hdmi-dp1"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) _pad(TEGRA_IO_PAD_PEX_CNTRL, 32, UINT_MAX, "pex-cntrl"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) _pad(TEGRA_IO_PAD_SDMMC2_HV, 34, 5, "sdmmc2-hv"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) _pad(TEGRA_IO_PAD_SDMMC4, 36, UINT_MAX, "sdmmc4"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) _pad(TEGRA_IO_PAD_CAM, 38, UINT_MAX, "cam"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) _pad(TEGRA_IO_PAD_DSIB, 40, UINT_MAX, "dsib"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) _pad(TEGRA_IO_PAD_DSIC, 41, UINT_MAX, "dsic"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) _pad(TEGRA_IO_PAD_DSID, 42, UINT_MAX, "dsid"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) _pad(TEGRA_IO_PAD_CSIC, 43, UINT_MAX, "csic"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) _pad(TEGRA_IO_PAD_CSID, 44, UINT_MAX, "csid"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) _pad(TEGRA_IO_PAD_CSIE, 45, UINT_MAX, "csie"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) _pad(TEGRA_IO_PAD_CSIF, 46, UINT_MAX, "csif"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) _pad(TEGRA_IO_PAD_SPI, 47, UINT_MAX, "spi"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) _pad(TEGRA_IO_PAD_UFS, 49, UINT_MAX, "ufs"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) _pad(TEGRA_IO_PAD_DMIC_HV, 52, 2, "dmic-hv"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) _pad(TEGRA_IO_PAD_EDP, 53, UINT_MAX, "edp"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) _pad(TEGRA_IO_PAD_SDMMC1_HV, 55, 4, "sdmmc1-hv"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) _pad(TEGRA_IO_PAD_SDMMC3_HV, 56, 6, "sdmmc3-hv"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) _pad(TEGRA_IO_PAD_CONN, 60, UINT_MAX, "conn"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) _pad(TEGRA_IO_PAD_AUDIO_HV, 61, 1, "audio-hv"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) _pad(TEGRA_IO_PAD_AO_HV, UINT_MAX, 0, "ao-hv")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) static const struct tegra_io_pad_soc tegra186_io_pads[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) TEGRA186_IO_PAD_TABLE(TEGRA_IO_PAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) static const struct pinctrl_pin_desc tegra186_pin_descs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) TEGRA186_IO_PAD_TABLE(TEGRA_IO_PIN_DESC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) static const struct tegra_pmc_regs tegra186_pmc_regs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) .scratch0 = 0x2000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) .dpd_req = 0x74,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) .dpd_status = 0x78,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) .dpd2_req = 0x7c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) .dpd2_status = 0x80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) .rst_status = 0x70,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) .rst_source_shift = 0x2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) .rst_source_mask = 0x3c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) .rst_level_shift = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) .rst_level_mask = 0x3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) static void tegra186_pmc_setup_irq_polarity(struct tegra_pmc *pmc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) bool invert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) struct resource regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) void __iomem *wake;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) index = of_property_match_string(np, "reg-names", "wake");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) if (index < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) dev_err(pmc->dev, "failed to find PMC wake registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) of_address_to_resource(np, index, ®s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) wake = ioremap(regs.start, resource_size(®s));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) if (!wake) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) dev_err(pmc->dev, "failed to map PMC wake registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) value = readl(wake + WAKE_AOWAKE_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) if (invert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) value |= WAKE_AOWAKE_CTRL_INTR_POLARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) value &= ~WAKE_AOWAKE_CTRL_INTR_POLARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) writel(value, wake + WAKE_AOWAKE_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) iounmap(wake);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) static const char * const tegra186_reset_sources[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) "SYS_RESET",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) "AOWDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) "MCCPLEXWDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) "BPMPWDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) "SCEWDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) "SPEWDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) "APEWDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) "BCCPLEXWDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) "SENSOR",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) "AOTAG",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) "VFSENSOR",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) "SWREST",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) "SC7",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) "HSM",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) "CORESIGHT"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) static const char * const tegra186_reset_levels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) "L0", "L1", "L2", "WARM"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) static const struct tegra_wake_event tegra186_wake_events[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) TEGRA_WAKE_IRQ("pmu", 24, 209),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) TEGRA_WAKE_GPIO("power", 29, 1, TEGRA186_AON_GPIO(FF, 0)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) TEGRA_WAKE_IRQ("rtc", 73, 10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) static const struct tegra_pmc_soc tegra186_pmc_soc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) .num_powergates = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) .powergates = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) .num_cpu_powergates = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) .cpu_powergates = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) .has_tsense_reset = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) .has_gpu_clamps = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) .needs_mbist_war = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) .has_impl_33v_pwr = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) .maybe_tz_only = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) .num_io_pads = ARRAY_SIZE(tegra186_io_pads),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) .io_pads = tegra186_io_pads,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) .num_pin_descs = ARRAY_SIZE(tegra186_pin_descs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) .pin_descs = tegra186_pin_descs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) .regs = &tegra186_pmc_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) .init = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) .setup_irq_polarity = tegra186_pmc_setup_irq_polarity,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) .irq_set_wake = tegra186_pmc_irq_set_wake,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) .irq_set_type = tegra186_pmc_irq_set_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) .reset_sources = tegra186_reset_sources,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) .num_reset_sources = ARRAY_SIZE(tegra186_reset_sources),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) .reset_levels = tegra186_reset_levels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) .num_reset_levels = ARRAY_SIZE(tegra186_reset_levels),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) .num_wake_events = ARRAY_SIZE(tegra186_wake_events),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) .wake_events = tegra186_wake_events,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) .pmc_clks_data = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) .num_pmc_clks = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) .has_blink_output = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) #define TEGRA194_IO_PAD_TABLE(_pad) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) /* .id .dpd .voltage .name */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) _pad(TEGRA_IO_PAD_CSIA, 0, UINT_MAX, "csia"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) _pad(TEGRA_IO_PAD_CSIB, 1, UINT_MAX, "csib"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) _pad(TEGRA_IO_PAD_MIPI_BIAS, 3, UINT_MAX, "mipi-bias"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) _pad(TEGRA_IO_PAD_PEX_CLK_BIAS, 4, UINT_MAX, "pex-clk-bias"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) _pad(TEGRA_IO_PAD_PEX_CLK3, 5, UINT_MAX, "pex-clk3"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) _pad(TEGRA_IO_PAD_PEX_CLK2, 6, UINT_MAX, "pex-clk2"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) _pad(TEGRA_IO_PAD_PEX_CLK1, 7, UINT_MAX, "pex-clk1"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) _pad(TEGRA_IO_PAD_EQOS, 8, UINT_MAX, "eqos"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) _pad(TEGRA_IO_PAD_PEX_CLK_2_BIAS, 9, UINT_MAX, "pex-clk-2-bias"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) _pad(TEGRA_IO_PAD_PEX_CLK_2, 10, UINT_MAX, "pex-clk-2"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) _pad(TEGRA_IO_PAD_DAP3, 11, UINT_MAX, "dap3"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) _pad(TEGRA_IO_PAD_DAP5, 12, UINT_MAX, "dap5"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) _pad(TEGRA_IO_PAD_UART, 14, UINT_MAX, "uart"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) _pad(TEGRA_IO_PAD_PWR_CTL, 15, UINT_MAX, "pwr-ctl"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) _pad(TEGRA_IO_PAD_SOC_GPIO53, 16, UINT_MAX, "soc-gpio53"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) _pad(TEGRA_IO_PAD_AUDIO, 17, UINT_MAX, "audio"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) _pad(TEGRA_IO_PAD_GP_PWM2, 18, UINT_MAX, "gp-pwm2"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) _pad(TEGRA_IO_PAD_GP_PWM3, 19, UINT_MAX, "gp-pwm3"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) _pad(TEGRA_IO_PAD_SOC_GPIO12, 20, UINT_MAX, "soc-gpio12"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) _pad(TEGRA_IO_PAD_SOC_GPIO13, 21, UINT_MAX, "soc-gpio13"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) _pad(TEGRA_IO_PAD_SOC_GPIO10, 22, UINT_MAX, "soc-gpio10"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) _pad(TEGRA_IO_PAD_UART4, 23, UINT_MAX, "uart4"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) _pad(TEGRA_IO_PAD_UART5, 24, UINT_MAX, "uart5"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) _pad(TEGRA_IO_PAD_DBG, 25, UINT_MAX, "dbg"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) _pad(TEGRA_IO_PAD_HDMI_DP3, 26, UINT_MAX, "hdmi-dp3"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) _pad(TEGRA_IO_PAD_HDMI_DP2, 27, UINT_MAX, "hdmi-dp2"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) _pad(TEGRA_IO_PAD_HDMI_DP0, 28, UINT_MAX, "hdmi-dp0"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) _pad(TEGRA_IO_PAD_HDMI_DP1, 29, UINT_MAX, "hdmi-dp1"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) _pad(TEGRA_IO_PAD_PEX_CNTRL, 32, UINT_MAX, "pex-cntrl"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) _pad(TEGRA_IO_PAD_PEX_CTL2, 33, UINT_MAX, "pex-ctl2"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) _pad(TEGRA_IO_PAD_PEX_L0_RST_N, 34, UINT_MAX, "pex-l0-rst"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) _pad(TEGRA_IO_PAD_PEX_L1_RST_N, 35, UINT_MAX, "pex-l1-rst"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) _pad(TEGRA_IO_PAD_SDMMC4, 36, UINT_MAX, "sdmmc4"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) _pad(TEGRA_IO_PAD_PEX_L5_RST_N, 37, UINT_MAX, "pex-l5-rst"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) _pad(TEGRA_IO_PAD_CAM, 38, UINT_MAX, "cam"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) _pad(TEGRA_IO_PAD_CSIC, 43, UINT_MAX, "csic"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) _pad(TEGRA_IO_PAD_CSID, 44, UINT_MAX, "csid"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) _pad(TEGRA_IO_PAD_CSIE, 45, UINT_MAX, "csie"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) _pad(TEGRA_IO_PAD_CSIF, 46, UINT_MAX, "csif"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) _pad(TEGRA_IO_PAD_SPI, 47, UINT_MAX, "spi"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) _pad(TEGRA_IO_PAD_UFS, 49, UINT_MAX, "ufs"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) _pad(TEGRA_IO_PAD_CSIG, 50, UINT_MAX, "csig"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) _pad(TEGRA_IO_PAD_CSIH, 51, UINT_MAX, "csih"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) _pad(TEGRA_IO_PAD_EDP, 53, UINT_MAX, "edp"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) _pad(TEGRA_IO_PAD_SDMMC1_HV, 55, 4, "sdmmc1-hv"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) _pad(TEGRA_IO_PAD_SDMMC3_HV, 56, 6, "sdmmc3-hv"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) _pad(TEGRA_IO_PAD_CONN, 60, UINT_MAX, "conn"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) _pad(TEGRA_IO_PAD_AUDIO_HV, 61, 1, "audio-hv"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) _pad(TEGRA_IO_PAD_AO_HV, UINT_MAX, 0, "ao-hv")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) static const struct tegra_io_pad_soc tegra194_io_pads[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) TEGRA194_IO_PAD_TABLE(TEGRA_IO_PAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) static const struct pinctrl_pin_desc tegra194_pin_descs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) TEGRA194_IO_PAD_TABLE(TEGRA_IO_PIN_DESC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) static const struct tegra_pmc_regs tegra194_pmc_regs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) .scratch0 = 0x2000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) .dpd_req = 0x74,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) .dpd_status = 0x78,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) .dpd2_req = 0x7c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) .dpd2_status = 0x80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) .rst_status = 0x70,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) .rst_source_shift = 0x2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) .rst_source_mask = 0x7c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) .rst_level_shift = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) .rst_level_mask = 0x3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) static const char * const tegra194_reset_sources[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) "SYS_RESET_N",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) "AOWDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) "BCCPLEXWDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) "BPMPWDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) "SCEWDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) "SPEWDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) "APEWDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) "LCCPLEXWDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) "SENSOR",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) "AOTAG",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) "VFSENSOR",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) "MAINSWRST",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) "SC7",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) "HSM",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) "CSITE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) "RCEWDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) "PVA0WDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) "PVA1WDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) "L1A_ASYNC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) "BPMPBOOT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) "FUSECRC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) static const struct tegra_wake_event tegra194_wake_events[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) TEGRA_WAKE_IRQ("pmu", 24, 209),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) TEGRA_WAKE_GPIO("power", 29, 1, TEGRA194_AON_GPIO(EE, 4)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) TEGRA_WAKE_IRQ("rtc", 73, 10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) static const struct tegra_pmc_soc tegra194_pmc_soc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) .num_powergates = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) .powergates = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) .num_cpu_powergates = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) .cpu_powergates = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) .has_tsense_reset = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) .has_gpu_clamps = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) .needs_mbist_war = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) .has_impl_33v_pwr = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) .maybe_tz_only = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) .num_io_pads = ARRAY_SIZE(tegra194_io_pads),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) .io_pads = tegra194_io_pads,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) .num_pin_descs = ARRAY_SIZE(tegra194_pin_descs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) .pin_descs = tegra194_pin_descs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) .regs = &tegra194_pmc_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) .init = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) .setup_irq_polarity = tegra186_pmc_setup_irq_polarity,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) .irq_set_wake = tegra186_pmc_irq_set_wake,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) .irq_set_type = tegra186_pmc_irq_set_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) .reset_sources = tegra194_reset_sources,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) .num_reset_sources = ARRAY_SIZE(tegra194_reset_sources),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) .reset_levels = tegra186_reset_levels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) .num_reset_levels = ARRAY_SIZE(tegra186_reset_levels),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) .num_wake_events = ARRAY_SIZE(tegra194_wake_events),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) .wake_events = tegra194_wake_events,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) .pmc_clks_data = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) .num_pmc_clks = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) .has_blink_output = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) static const struct tegra_pmc_regs tegra234_pmc_regs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) .scratch0 = 0x2000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) .dpd_req = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) .dpd_status = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) .dpd2_req = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) .dpd2_status = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) .rst_status = 0x70,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) .rst_source_shift = 0x2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) .rst_source_mask = 0xfc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) .rst_level_shift = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) .rst_level_mask = 0x3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) static const char * const tegra234_reset_sources[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) "SYS_RESET_N",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) "AOWDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) "BCCPLEXWDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) "BPMPWDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) "SCEWDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) "SPEWDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) "APEWDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) "LCCPLEXWDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) "SENSOR",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) "AOTAG",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) "VFSENSOR",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) "MAINSWRST",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) "SC7",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) "HSM",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) "CSITE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) "RCEWDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) "PVA0WDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) "PVA1WDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) "L1A_ASYNC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) "BPMPBOOT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) "FUSECRC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) static const struct tegra_pmc_soc tegra234_pmc_soc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) .num_powergates = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) .powergates = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) .num_cpu_powergates = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) .cpu_powergates = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) .has_tsense_reset = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) .has_gpu_clamps = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) .needs_mbist_war = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) .has_impl_33v_pwr = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) .maybe_tz_only = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) .num_io_pads = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) .io_pads = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) .num_pin_descs = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) .pin_descs = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) .regs = &tegra234_pmc_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) .init = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) .setup_irq_polarity = tegra186_pmc_setup_irq_polarity,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) .irq_set_wake = tegra186_pmc_irq_set_wake,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) .irq_set_type = tegra186_pmc_irq_set_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) .reset_sources = tegra234_reset_sources,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) .num_reset_sources = ARRAY_SIZE(tegra234_reset_sources),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) .reset_levels = tegra186_reset_levels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) .num_reset_levels = ARRAY_SIZE(tegra186_reset_levels),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) .num_wake_events = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) .wake_events = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) .pmc_clks_data = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) .num_pmc_clks = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) .has_blink_output = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) static const struct of_device_id tegra_pmc_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) { .compatible = "nvidia,tegra234-pmc", .data = &tegra234_pmc_soc },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) { .compatible = "nvidia,tegra194-pmc", .data = &tegra194_pmc_soc },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) { .compatible = "nvidia,tegra186-pmc", .data = &tegra186_pmc_soc },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) { .compatible = "nvidia,tegra210-pmc", .data = &tegra210_pmc_soc },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) { .compatible = "nvidia,tegra132-pmc", .data = &tegra124_pmc_soc },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) { .compatible = "nvidia,tegra124-pmc", .data = &tegra124_pmc_soc },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) { .compatible = "nvidia,tegra114-pmc", .data = &tegra114_pmc_soc },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) { .compatible = "nvidia,tegra30-pmc", .data = &tegra30_pmc_soc },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) { .compatible = "nvidia,tegra20-pmc", .data = &tegra20_pmc_soc },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) static struct platform_driver tegra_pmc_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) .name = "tegra-pmc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) .suppress_bind_attrs = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) .of_match_table = tegra_pmc_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) .pm = &tegra_pmc_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) .probe = tegra_pmc_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) builtin_platform_driver(tegra_pmc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) static bool __init tegra_pmc_detect_tz_only(struct tegra_pmc *pmc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) u32 value, saved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) saved = readl(pmc->base + pmc->soc->regs->scratch0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) value = saved ^ 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) if (value == 0xffffffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) value = 0xdeadbeef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) /* write pattern and read it back */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) writel(value, pmc->base + pmc->soc->regs->scratch0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) value = readl(pmc->base + pmc->soc->regs->scratch0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) /* if we read all-zeroes, access is restricted to TZ only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) if (value == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) pr_info("access to PMC is restricted to TZ\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) /* restore original value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) writel(saved, pmc->base + pmc->soc->regs->scratch0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) * Early initialization to allow access to registers in the very early boot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) * process.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) static int __init tegra_pmc_early_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) const struct of_device_id *match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) struct resource regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) bool invert;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) mutex_init(&pmc->powergates_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) np = of_find_matching_node_and_match(NULL, tegra_pmc_match, &match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) if (!np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) * Fall back to legacy initialization for 32-bit ARM only. All
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) * 64-bit ARM device tree files for Tegra are required to have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) * a PMC node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) * This is for backwards-compatibility with old device trees
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) * that didn't contain a PMC node. Note that in this case the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) * SoC data can't be matched and therefore powergating is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) * disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) if (IS_ENABLED(CONFIG_ARM) && soc_is_tegra()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) pr_warn("DT node not found, powergating disabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) regs.start = 0x7000e400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) regs.end = 0x7000e7ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) regs.flags = IORESOURCE_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) pr_warn("Using memory region %pR\n", ®s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) * At this point we're not running on Tegra, so play
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) * nice with multi-platform kernels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) * Extract information from the device tree if we've found a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) * matching node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) if (of_address_to_resource(np, 0, ®s) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) pr_err("failed to get PMC registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) pmc->base = ioremap(regs.start, resource_size(®s));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) if (!pmc->base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) pr_err("failed to map PMC registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) if (np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) pmc->soc = match->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) if (pmc->soc->maybe_tz_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) pmc->tz_only = tegra_pmc_detect_tz_only(pmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) /* Create a bitmap of the available and valid partitions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) for (i = 0; i < pmc->soc->num_powergates; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) if (pmc->soc->powergates[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) set_bit(i, pmc->powergates_available);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) * Invert the interrupt polarity if a PMC device tree node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) * exists and contains the nvidia,invert-interrupt property.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) invert = of_property_read_bool(np, "nvidia,invert-interrupt");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) pmc->soc->setup_irq_polarity(pmc, np, invert);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) early_initcall(tegra_pmc_early_init);