Loading drivers/soc/tegra/pmc.c +98 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,11 @@ #define PMC_CNTRL_SYSCLK_POLARITY BIT(10) /* sys clk polarity */ #define PMC_CNTRL_MAIN_RST BIT(4) #define PMC_WAKE_MASK 0x0c #define PMC_WAKE_LEVEL 0x10 #define PMC_WAKE_STATUS 0x14 #define PMC_SW_WAKE_STATUS 0x18 #define DPD_SAMPLE 0x020 #define DPD_SAMPLE_ENABLE BIT(0) #define DPD_SAMPLE_DISABLE (0 << 0) Loading Loading @@ -87,6 +92,11 @@ #define PMC_SCRATCH41 0x140 #define PMC_WAKE2_MASK 0x160 #define PMC_WAKE2_LEVEL 0x164 #define PMC_WAKE2_STATUS 0x168 #define PMC_SW_WAKE2_STATUS 0x16c #define PMC_SENSOR_CTRL 0x1b0 #define PMC_SENSOR_CTRL_SCRATCH_WRITE BIT(2) #define PMC_SENSOR_CTRL_ENABLE_RST BIT(1) Loading Loading @@ -1948,6 +1958,86 @@ static const struct irq_domain_ops tegra_pmc_irq_domain_ops = { .alloc = tegra_pmc_irq_alloc, }; static int tegra210_pmc_irq_set_wake(struct irq_data *data, unsigned int on) { struct tegra_pmc *pmc = irq_data_get_irq_chip_data(data); unsigned int offset, bit; u32 value; if (data->hwirq == ULONG_MAX) return 0; offset = data->hwirq / 32; bit = data->hwirq % 32; /* clear wake status */ tegra_pmc_writel(pmc, 0, PMC_SW_WAKE_STATUS); tegra_pmc_writel(pmc, 0, PMC_SW_WAKE2_STATUS); tegra_pmc_writel(pmc, 0, PMC_WAKE_STATUS); tegra_pmc_writel(pmc, 0, PMC_WAKE2_STATUS); /* enable PMC wake */ if (data->hwirq >= 32) offset = PMC_WAKE2_MASK; else offset = PMC_WAKE_MASK; value = tegra_pmc_readl(pmc, offset); if (on) value |= BIT(bit); else value &= ~BIT(bit); tegra_pmc_writel(pmc, value, offset); return 0; } static int tegra210_pmc_irq_set_type(struct irq_data *data, unsigned int type) { struct tegra_pmc *pmc = irq_data_get_irq_chip_data(data); unsigned int offset, bit; u32 value; if (data->hwirq == ULONG_MAX) return 0; offset = data->hwirq / 32; bit = data->hwirq % 32; if (data->hwirq >= 32) offset = PMC_WAKE2_LEVEL; else offset = PMC_WAKE_LEVEL; value = tegra_pmc_readl(pmc, offset); switch (type) { case IRQ_TYPE_EDGE_RISING: case IRQ_TYPE_LEVEL_HIGH: value |= BIT(bit); break; case IRQ_TYPE_EDGE_FALLING: case IRQ_TYPE_LEVEL_LOW: value &= ~BIT(bit); break; case IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING: value ^= BIT(bit); break; default: return -EINVAL; } tegra_pmc_writel(pmc, value, offset); return 0; } static int tegra186_pmc_irq_set_wake(struct irq_data *data, unsigned int on) { struct tegra_pmc *pmc = irq_data_get_irq_chip_data(data); Loading Loading @@ -2566,6 +2656,10 @@ static const struct pinctrl_pin_desc tegra210_pin_descs[] = { TEGRA210_IO_PAD_TABLE(TEGRA_IO_PIN_DESC) }; static const struct tegra_wake_event tegra210_wake_events[] = { TEGRA_WAKE_IRQ("rtc", 16, 2), }; static const struct tegra_pmc_soc tegra210_pmc_soc = { .num_powergates = ARRAY_SIZE(tegra210_powergates), .powergates = tegra210_powergates, Loading @@ -2583,10 +2677,14 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = { .regs = &tegra20_pmc_regs, .init = tegra20_pmc_init, .setup_irq_polarity = tegra20_pmc_setup_irq_polarity, .irq_set_wake = tegra210_pmc_irq_set_wake, .irq_set_type = tegra210_pmc_irq_set_type, .reset_sources = tegra210_reset_sources, .num_reset_sources = ARRAY_SIZE(tegra210_reset_sources), .reset_levels = NULL, .num_reset_levels = 0, .num_wake_events = ARRAY_SIZE(tegra210_wake_events), .wake_events = tegra210_wake_events, }; #define TEGRA186_IO_PAD_TABLE(_pad) \ Loading Loading
drivers/soc/tegra/pmc.c +98 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,11 @@ #define PMC_CNTRL_SYSCLK_POLARITY BIT(10) /* sys clk polarity */ #define PMC_CNTRL_MAIN_RST BIT(4) #define PMC_WAKE_MASK 0x0c #define PMC_WAKE_LEVEL 0x10 #define PMC_WAKE_STATUS 0x14 #define PMC_SW_WAKE_STATUS 0x18 #define DPD_SAMPLE 0x020 #define DPD_SAMPLE_ENABLE BIT(0) #define DPD_SAMPLE_DISABLE (0 << 0) Loading Loading @@ -87,6 +92,11 @@ #define PMC_SCRATCH41 0x140 #define PMC_WAKE2_MASK 0x160 #define PMC_WAKE2_LEVEL 0x164 #define PMC_WAKE2_STATUS 0x168 #define PMC_SW_WAKE2_STATUS 0x16c #define PMC_SENSOR_CTRL 0x1b0 #define PMC_SENSOR_CTRL_SCRATCH_WRITE BIT(2) #define PMC_SENSOR_CTRL_ENABLE_RST BIT(1) Loading Loading @@ -1948,6 +1958,86 @@ static const struct irq_domain_ops tegra_pmc_irq_domain_ops = { .alloc = tegra_pmc_irq_alloc, }; static int tegra210_pmc_irq_set_wake(struct irq_data *data, unsigned int on) { struct tegra_pmc *pmc = irq_data_get_irq_chip_data(data); unsigned int offset, bit; u32 value; if (data->hwirq == ULONG_MAX) return 0; offset = data->hwirq / 32; bit = data->hwirq % 32; /* clear wake status */ tegra_pmc_writel(pmc, 0, PMC_SW_WAKE_STATUS); tegra_pmc_writel(pmc, 0, PMC_SW_WAKE2_STATUS); tegra_pmc_writel(pmc, 0, PMC_WAKE_STATUS); tegra_pmc_writel(pmc, 0, PMC_WAKE2_STATUS); /* enable PMC wake */ if (data->hwirq >= 32) offset = PMC_WAKE2_MASK; else offset = PMC_WAKE_MASK; value = tegra_pmc_readl(pmc, offset); if (on) value |= BIT(bit); else value &= ~BIT(bit); tegra_pmc_writel(pmc, value, offset); return 0; } static int tegra210_pmc_irq_set_type(struct irq_data *data, unsigned int type) { struct tegra_pmc *pmc = irq_data_get_irq_chip_data(data); unsigned int offset, bit; u32 value; if (data->hwirq == ULONG_MAX) return 0; offset = data->hwirq / 32; bit = data->hwirq % 32; if (data->hwirq >= 32) offset = PMC_WAKE2_LEVEL; else offset = PMC_WAKE_LEVEL; value = tegra_pmc_readl(pmc, offset); switch (type) { case IRQ_TYPE_EDGE_RISING: case IRQ_TYPE_LEVEL_HIGH: value |= BIT(bit); break; case IRQ_TYPE_EDGE_FALLING: case IRQ_TYPE_LEVEL_LOW: value &= ~BIT(bit); break; case IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING: value ^= BIT(bit); break; default: return -EINVAL; } tegra_pmc_writel(pmc, value, offset); return 0; } static int tegra186_pmc_irq_set_wake(struct irq_data *data, unsigned int on) { struct tegra_pmc *pmc = irq_data_get_irq_chip_data(data); Loading Loading @@ -2566,6 +2656,10 @@ static const struct pinctrl_pin_desc tegra210_pin_descs[] = { TEGRA210_IO_PAD_TABLE(TEGRA_IO_PIN_DESC) }; static const struct tegra_wake_event tegra210_wake_events[] = { TEGRA_WAKE_IRQ("rtc", 16, 2), }; static const struct tegra_pmc_soc tegra210_pmc_soc = { .num_powergates = ARRAY_SIZE(tegra210_powergates), .powergates = tegra210_powergates, Loading @@ -2583,10 +2677,14 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = { .regs = &tegra20_pmc_regs, .init = tegra20_pmc_init, .setup_irq_polarity = tegra20_pmc_setup_irq_polarity, .irq_set_wake = tegra210_pmc_irq_set_wake, .irq_set_type = tegra210_pmc_irq_set_type, .reset_sources = tegra210_reset_sources, .num_reset_sources = ARRAY_SIZE(tegra210_reset_sources), .reset_levels = NULL, .num_reset_levels = 0, .num_wake_events = ARRAY_SIZE(tegra210_wake_events), .wake_events = tegra210_wake_events, }; #define TEGRA186_IO_PAD_TABLE(_pad) \ Loading