From 28dbe8231066850ca5eaae55abf5a967f470eccd Mon Sep 17 00:00:00 2001 From: Petlozu Pravareshwar Date: Sun, 2 Oct 2022 17:54:25 +0000 Subject: soc/tegra: pmc: Select IRQ_DOMAIN_HIERARCHY Tegra PMC driver depends on IRQ domain hierarchy support, hence select the IRQ_DOMAIN_HIERARCHY config for SOC_TEGRA_PMC. Signed-off-by: Petlozu Pravareshwar Signed-off-by: Thierry Reding --- drivers/soc/tegra/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/soc/tegra/Kconfig b/drivers/soc/tegra/Kconfig index d1ecadffa1bb..5f5324294636 100644 --- a/drivers/soc/tegra/Kconfig +++ b/drivers/soc/tegra/Kconfig @@ -143,6 +143,7 @@ config SOC_TEGRA_FLOWCTRL config SOC_TEGRA_PMC bool select GENERIC_PINCONF + select IRQ_DOMAIN_HIERARCHY select PM_OPP select PM_GENERIC_DOMAINS select REGMAP -- cgit v1.2.3 From bea06d776d8b2caeddc45f4810ac1d8dab09b006 Mon Sep 17 00:00:00 2001 From: Kartik Date: Fri, 7 Oct 2022 15:21:06 +0530 Subject: soc/tegra: fuse: Use SoC specific nvmem cells Tegra FUSE block size, availability and offsets can vary from one SoC generation to another. Signed-off-by: Kartik Signed-off-by: Thierry Reding --- drivers/soc/tegra/fuse/fuse-tegra.c | 110 +--------------- drivers/soc/tegra/fuse/fuse-tegra30.c | 240 +++++++++++++++++++++++++++++++++- drivers/soc/tegra/fuse/fuse.h | 2 + 3 files changed, 241 insertions(+), 111 deletions(-) diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c index 6542267a224d..793032f4f015 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra.c +++ b/drivers/soc/tegra/fuse/fuse-tegra.c @@ -94,112 +94,6 @@ static int tegra_fuse_read(void *priv, unsigned int offset, void *value, return 0; } -static const struct nvmem_cell_info tegra_fuse_cells[] = { - { - .name = "tsensor-cpu1", - .offset = 0x084, - .bytes = 4, - .bit_offset = 0, - .nbits = 32, - }, { - .name = "tsensor-cpu2", - .offset = 0x088, - .bytes = 4, - .bit_offset = 0, - .nbits = 32, - }, { - .name = "tsensor-cpu0", - .offset = 0x098, - .bytes = 4, - .bit_offset = 0, - .nbits = 32, - }, { - .name = "xusb-pad-calibration", - .offset = 0x0f0, - .bytes = 4, - .bit_offset = 0, - .nbits = 32, - }, { - .name = "tsensor-cpu3", - .offset = 0x12c, - .bytes = 4, - .bit_offset = 0, - .nbits = 32, - }, { - .name = "sata-calibration", - .offset = 0x124, - .bytes = 1, - .bit_offset = 0, - .nbits = 2, - }, { - .name = "tsensor-gpu", - .offset = 0x154, - .bytes = 4, - .bit_offset = 0, - .nbits = 32, - }, { - .name = "tsensor-mem0", - .offset = 0x158, - .bytes = 4, - .bit_offset = 0, - .nbits = 32, - }, { - .name = "tsensor-mem1", - .offset = 0x15c, - .bytes = 4, - .bit_offset = 0, - .nbits = 32, - }, { - .name = "tsensor-pllx", - .offset = 0x160, - .bytes = 4, - .bit_offset = 0, - .nbits = 32, - }, { - .name = "tsensor-common", - .offset = 0x180, - .bytes = 4, - .bit_offset = 0, - .nbits = 32, - }, { - .name = "gpu-gcplex-config-fuse", - .offset = 0x1c8, - .bytes = 4, - .bit_offset = 0, - .nbits = 32, - }, { - .name = "tsensor-realignment", - .offset = 0x1fc, - .bytes = 4, - .bit_offset = 0, - .nbits = 32, - }, { - .name = "gpu-calibration", - .offset = 0x204, - .bytes = 4, - .bit_offset = 0, - .nbits = 32, - }, { - .name = "xusb-pad-calibration-ext", - .offset = 0x250, - .bytes = 4, - .bit_offset = 0, - .nbits = 32, - }, { - .name = "gpu-pdi0", - .offset = 0x300, - .bytes = 4, - .bit_offset = 0, - .nbits = 32, - }, { - .name = "gpu-pdi1", - .offset = 0x304, - .bytes = 4, - .bit_offset = 0, - .nbits = 32, - }, -}; - static void tegra_fuse_restore(void *base) { fuse->base = (void __iomem *)base; @@ -253,8 +147,8 @@ static int tegra_fuse_probe(struct platform_device *pdev) nvmem.name = "fuse"; nvmem.id = -1; nvmem.owner = THIS_MODULE; - nvmem.cells = tegra_fuse_cells; - nvmem.ncells = ARRAY_SIZE(tegra_fuse_cells); + nvmem.cells = fuse->soc->cells; + nvmem.ncells = fuse->soc->num_cells; nvmem.type = NVMEM_TYPE_OTP; nvmem.read_only = true; nvmem.root_only = true; diff --git a/drivers/soc/tegra/fuse/fuse-tegra30.c b/drivers/soc/tegra/fuse/fuse-tegra30.c index f01d8a2547b6..86547be567af 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra30.c +++ b/drivers/soc/tegra/fuse/fuse-tegra30.c @@ -133,6 +133,82 @@ const struct tegra_fuse_soc tegra114_fuse_soc = { #endif #if defined(CONFIG_ARCH_TEGRA_124_SOC) || defined(CONFIG_ARCH_TEGRA_132_SOC) +static const struct nvmem_cell_info tegra124_fuse_cells[] = { + { + .name = "tsensor-cpu1", + .offset = 0x084, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "tsensor-cpu2", + .offset = 0x088, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "tsensor-cpu0", + .offset = 0x098, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "xusb-pad-calibration", + .offset = 0x0f0, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "tsensor-cpu3", + .offset = 0x12c, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "sata-calibration", + .offset = 0x124, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "tsensor-gpu", + .offset = 0x154, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "tsensor-mem0", + .offset = 0x158, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "tsensor-mem1", + .offset = 0x15c, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "tsensor-pllx", + .offset = 0x160, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "tsensor-common", + .offset = 0x180, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "tsensor-realignment", + .offset = 0x1fc, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, +}; + static const struct nvmem_cell_lookup tegra124_fuse_lookups[] = { { .nvmem_name = "fuse", @@ -209,12 +285,96 @@ const struct tegra_fuse_soc tegra124_fuse_soc = { .info = &tegra124_fuse_info, .lookups = tegra124_fuse_lookups, .num_lookups = ARRAY_SIZE(tegra124_fuse_lookups), + .cells = tegra124_fuse_cells, + .num_cells = ARRAY_SIZE(tegra124_fuse_cells), .soc_attr_group = &tegra_soc_attr_group, .clk_suspend_on = true, }; #endif #if defined(CONFIG_ARCH_TEGRA_210_SOC) +static const struct nvmem_cell_info tegra210_fuse_cells[] = { + { + .name = "tsensor-cpu1", + .offset = 0x084, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "tsensor-cpu2", + .offset = 0x088, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "tsensor-cpu0", + .offset = 0x098, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "xusb-pad-calibration", + .offset = 0x0f0, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "tsensor-cpu3", + .offset = 0x12c, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "sata-calibration", + .offset = 0x124, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "tsensor-gpu", + .offset = 0x154, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "tsensor-mem0", + .offset = 0x158, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "tsensor-mem1", + .offset = 0x15c, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "tsensor-pllx", + .offset = 0x160, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "tsensor-common", + .offset = 0x180, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "gpu-calibration", + .offset = 0x204, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "xusb-pad-calibration-ext", + .offset = 0x250, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, +}; + static const struct nvmem_cell_lookup tegra210_fuse_lookups[] = { { .nvmem_name = "fuse", @@ -295,6 +455,8 @@ const struct tegra_fuse_soc tegra210_fuse_soc = { .speedo_init = tegra210_init_speedo_data, .info = &tegra210_fuse_info, .lookups = tegra210_fuse_lookups, + .cells = tegra210_fuse_cells, + .num_cells = ARRAY_SIZE(tegra210_fuse_cells), .num_lookups = ARRAY_SIZE(tegra210_fuse_lookups), .soc_attr_group = &tegra_soc_attr_group, .clk_suspend_on = false, @@ -302,6 +464,22 @@ const struct tegra_fuse_soc tegra210_fuse_soc = { #endif #if defined(CONFIG_ARCH_TEGRA_186_SOC) +static const struct nvmem_cell_info tegra186_fuse_cells[] = { + { + .name = "xusb-pad-calibration", + .offset = 0x0f0, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "xusb-pad-calibration-ext", + .offset = 0x250, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, +}; + static const struct nvmem_cell_lookup tegra186_fuse_lookups[] = { { .nvmem_name = "fuse", @@ -318,7 +496,7 @@ static const struct nvmem_cell_lookup tegra186_fuse_lookups[] = { static const struct tegra_fuse_info tegra186_fuse_info = { .read = tegra30_fuse_read, - .size = 0x300, + .size = 0x478, .spare = 0x280, }; @@ -327,12 +505,48 @@ const struct tegra_fuse_soc tegra186_fuse_soc = { .info = &tegra186_fuse_info, .lookups = tegra186_fuse_lookups, .num_lookups = ARRAY_SIZE(tegra186_fuse_lookups), + .cells = tegra186_fuse_cells, + .num_cells = ARRAY_SIZE(tegra186_fuse_cells), .soc_attr_group = &tegra_soc_attr_group, .clk_suspend_on = false, }; #endif #if defined(CONFIG_ARCH_TEGRA_194_SOC) +static const struct nvmem_cell_info tegra194_fuse_cells[] = { + { + .name = "xusb-pad-calibration", + .offset = 0x0f0, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "gpu-gcplex-config-fuse", + .offset = 0x1c8, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "xusb-pad-calibration-ext", + .offset = 0x250, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "gpu-pdi0", + .offset = 0x300, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "gpu-pdi1", + .offset = 0x304, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, +}; + static const struct nvmem_cell_lookup tegra194_fuse_lookups[] = { { .nvmem_name = "fuse", @@ -364,7 +578,7 @@ static const struct nvmem_cell_lookup tegra194_fuse_lookups[] = { static const struct tegra_fuse_info tegra194_fuse_info = { .read = tegra30_fuse_read, - .size = 0x300, + .size = 0x650, .spare = 0x280, }; @@ -373,12 +587,30 @@ const struct tegra_fuse_soc tegra194_fuse_soc = { .info = &tegra194_fuse_info, .lookups = tegra194_fuse_lookups, .num_lookups = ARRAY_SIZE(tegra194_fuse_lookups), + .cells = tegra194_fuse_cells, + .num_cells = ARRAY_SIZE(tegra194_fuse_cells), .soc_attr_group = &tegra194_soc_attr_group, .clk_suspend_on = false, }; #endif #if defined(CONFIG_ARCH_TEGRA_234_SOC) +static const struct nvmem_cell_info tegra234_fuse_cells[] = { + { + .name = "xusb-pad-calibration", + .offset = 0x0f0, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, { + .name = "xusb-pad-calibration-ext", + .offset = 0x250, + .bytes = 4, + .bit_offset = 0, + .nbits = 32, + }, +}; + static const struct nvmem_cell_lookup tegra234_fuse_lookups[] = { { .nvmem_name = "fuse", @@ -395,7 +627,7 @@ static const struct nvmem_cell_lookup tegra234_fuse_lookups[] = { static const struct tegra_fuse_info tegra234_fuse_info = { .read = tegra30_fuse_read, - .size = 0x300, + .size = 0x98c, .spare = 0x280, }; @@ -404,6 +636,8 @@ const struct tegra_fuse_soc tegra234_fuse_soc = { .info = &tegra234_fuse_info, .lookups = tegra234_fuse_lookups, .num_lookups = ARRAY_SIZE(tegra234_fuse_lookups), + .cells = tegra234_fuse_cells, + .num_cells = ARRAY_SIZE(tegra234_fuse_cells), .soc_attr_group = &tegra194_soc_attr_group, .clk_suspend_on = false, }; diff --git a/drivers/soc/tegra/fuse/fuse.h b/drivers/soc/tegra/fuse/fuse.h index 2bb1f9d6a6e6..02442157b231 100644 --- a/drivers/soc/tegra/fuse/fuse.h +++ b/drivers/soc/tegra/fuse/fuse.h @@ -32,6 +32,8 @@ struct tegra_fuse_soc { const struct nvmem_cell_lookup *lookups; unsigned int num_lookups; + const struct nvmem_cell_info *cells; + unsigned int num_cells; const struct attribute_group *soc_attr_group; -- cgit v1.2.3 From cc5b2ad5393ec237c8697bb3989a34c0c3beb2f6 Mon Sep 17 00:00:00 2001 From: Kartik Date: Fri, 7 Oct 2022 15:21:07 +0530 Subject: soc/tegra: fuse: Add nvmem keepout list On Tegra186 and later, various FUSE offsets are restricted and cannot be accessed from CCPLEX. Currently nvmem binary interface allows reading such offsets from userspace, which results in RAS errors. Add nvmem keepout lists to avoid any reads to restricted offsets. Signed-off-by: Kartik Signed-off-by: Thierry Reding --- drivers/soc/tegra/fuse/fuse-tegra.c | 2 ++ drivers/soc/tegra/fuse/fuse-tegra30.c | 38 +++++++++++++++++++++++++++++++++++ drivers/soc/tegra/fuse/fuse.h | 2 ++ 3 files changed, 42 insertions(+) diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c index 793032f4f015..ea25a1dcafc2 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra.c +++ b/drivers/soc/tegra/fuse/fuse-tegra.c @@ -149,6 +149,8 @@ static int tegra_fuse_probe(struct platform_device *pdev) nvmem.owner = THIS_MODULE; nvmem.cells = fuse->soc->cells; nvmem.ncells = fuse->soc->num_cells; + nvmem.keepout = fuse->soc->keepouts; + nvmem.nkeepout = fuse->soc->num_keepouts; nvmem.type = NVMEM_TYPE_OTP; nvmem.read_only = true; nvmem.root_only = true; diff --git a/drivers/soc/tegra/fuse/fuse-tegra30.c b/drivers/soc/tegra/fuse/fuse-tegra30.c index 86547be567af..932a03c64534 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra30.c +++ b/drivers/soc/tegra/fuse/fuse-tegra30.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -494,6 +495,14 @@ static const struct nvmem_cell_lookup tegra186_fuse_lookups[] = { }, }; +static const struct nvmem_keepout tegra186_fuse_keepouts[] = { + { .start = 0x01c, .end = 0x0f0 }, + { .start = 0x138, .end = 0x198 }, + { .start = 0x1d8, .end = 0x250 }, + { .start = 0x280, .end = 0x290 }, + { .start = 0x340, .end = 0x344 } +}; + static const struct tegra_fuse_info tegra186_fuse_info = { .read = tegra30_fuse_read, .size = 0x478, @@ -507,6 +516,8 @@ const struct tegra_fuse_soc tegra186_fuse_soc = { .num_lookups = ARRAY_SIZE(tegra186_fuse_lookups), .cells = tegra186_fuse_cells, .num_cells = ARRAY_SIZE(tegra186_fuse_cells), + .keepouts = tegra186_fuse_keepouts, + .num_keepouts = ARRAY_SIZE(tegra186_fuse_keepouts), .soc_attr_group = &tegra_soc_attr_group, .clk_suspend_on = false, }; @@ -576,6 +587,15 @@ static const struct nvmem_cell_lookup tegra194_fuse_lookups[] = { }, }; +static const struct nvmem_keepout tegra194_fuse_keepouts[] = { + { .start = 0x01c, .end = 0x0b8 }, + { .start = 0x12c, .end = 0x198 }, + { .start = 0x1a0, .end = 0x1bc }, + { .start = 0x1d8, .end = 0x250 }, + { .start = 0x270, .end = 0x290 }, + { .start = 0x310, .end = 0x45c } +}; + static const struct tegra_fuse_info tegra194_fuse_info = { .read = tegra30_fuse_read, .size = 0x650, @@ -589,6 +609,8 @@ const struct tegra_fuse_soc tegra194_fuse_soc = { .num_lookups = ARRAY_SIZE(tegra194_fuse_lookups), .cells = tegra194_fuse_cells, .num_cells = ARRAY_SIZE(tegra194_fuse_cells), + .keepouts = tegra194_fuse_keepouts, + .num_keepouts = ARRAY_SIZE(tegra194_fuse_keepouts), .soc_attr_group = &tegra194_soc_attr_group, .clk_suspend_on = false, }; @@ -625,6 +647,20 @@ static const struct nvmem_cell_lookup tegra234_fuse_lookups[] = { }, }; +static const struct nvmem_keepout tegra234_fuse_keepouts[] = { + { .start = 0x01c, .end = 0x0c8 }, + { .start = 0x12c, .end = 0x184 }, + { .start = 0x190, .end = 0x198 }, + { .start = 0x1a0, .end = 0x204 }, + { .start = 0x21c, .end = 0x250 }, + { .start = 0x25c, .end = 0x2f0 }, + { .start = 0x310, .end = 0x3d8 }, + { .start = 0x400, .end = 0x4f0 }, + { .start = 0x4f8, .end = 0x7e8 }, + { .start = 0x8d0, .end = 0x8d8 }, + { .start = 0xacc, .end = 0xf00 } +}; + static const struct tegra_fuse_info tegra234_fuse_info = { .read = tegra30_fuse_read, .size = 0x98c, @@ -638,6 +674,8 @@ const struct tegra_fuse_soc tegra234_fuse_soc = { .num_lookups = ARRAY_SIZE(tegra234_fuse_lookups), .cells = tegra234_fuse_cells, .num_cells = ARRAY_SIZE(tegra234_fuse_cells), + .keepouts = tegra234_fuse_keepouts, + .num_keepouts = ARRAY_SIZE(tegra234_fuse_keepouts), .soc_attr_group = &tegra194_soc_attr_group, .clk_suspend_on = false, }; diff --git a/drivers/soc/tegra/fuse/fuse.h b/drivers/soc/tegra/fuse/fuse.h index 02442157b231..90f23be73894 100644 --- a/drivers/soc/tegra/fuse/fuse.h +++ b/drivers/soc/tegra/fuse/fuse.h @@ -34,6 +34,8 @@ struct tegra_fuse_soc { unsigned int num_lookups; const struct nvmem_cell_info *cells; unsigned int num_cells; + const struct nvmem_keepout *keepouts; + unsigned int num_keepouts; const struct attribute_group *soc_attr_group; -- cgit v1.2.3 From c9c4ddb20c427b19c6a2a1787bf82c7b2aac25c3 Mon Sep 17 00:00:00 2001 From: Petlozu Pravareshwar Date: Fri, 30 Sep 2022 16:02:13 +0000 Subject: soc/tegra: pmc: Add I/O pad table for Tegra234 Add I/O pad table for Tegra234 to allow configuring DPD mode and switching the pins to 1.8V or 3.3V as needed. On Tegra234, DPD registers are reorganized such that there is a DPD_REQ register and a DPD_STATUS register per pad group. Update the PMC driver accordingly. While at it, use the generated tables from tegra-pinmux-scripts to make the formatting of these tables more consistent. Signed-off-by: Petlozu Pravareshwar [treding@nvidia.com: generate tables from tegra-pinmux-scripts] Signed-off-by: Thierry Reding --- drivers/soc/tegra/pmc.c | 656 +++++++++++++++++++++++++++++------------------- include/soc/tegra/pmc.h | 6 +- 2 files changed, 406 insertions(+), 256 deletions(-) diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index 678e8bc8a45d..9a195c1e84a0 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -269,16 +269,14 @@ struct tegra_powergate { struct tegra_io_pad_soc { enum tegra_io_pad id; unsigned int dpd; + unsigned int request; + unsigned int status; unsigned int voltage; const char *name; }; struct tegra_pmc_regs { unsigned int scratch0; - unsigned int dpd_req; - unsigned int dpd_status; - unsigned int dpd2_req; - unsigned int dpd2_status; unsigned int rst_status; unsigned int rst_source_shift; unsigned int rst_source_mask; @@ -1540,46 +1538,20 @@ tegra_io_pad_find(struct tegra_pmc *pmc, enum tegra_io_pad id) return NULL; } -static int tegra_io_pad_get_dpd_register_bit(struct tegra_pmc *pmc, - enum tegra_io_pad id, - unsigned long *request, - unsigned long *status, - u32 *mask) -{ - const struct tegra_io_pad_soc *pad; - - pad = tegra_io_pad_find(pmc, id); - if (!pad) { - dev_err(pmc->dev, "invalid I/O pad ID %u\n", id); - return -ENOENT; - } - - if (pad->dpd == UINT_MAX) - return -ENOTSUPP; - - *mask = BIT(pad->dpd % 32); - - if (pad->dpd < 32) { - *status = pmc->soc->regs->dpd_status; - *request = pmc->soc->regs->dpd_req; - } else { - *status = pmc->soc->regs->dpd2_status; - *request = pmc->soc->regs->dpd2_req; - } - - return 0; -} - -static int tegra_io_pad_prepare(struct tegra_pmc *pmc, enum tegra_io_pad id, - unsigned long *request, unsigned long *status, +static int tegra_io_pad_prepare(struct tegra_pmc *pmc, + const struct tegra_io_pad_soc *pad, + unsigned long *request, + unsigned long *status, u32 *mask) { unsigned long rate, value; - int err; - err = tegra_io_pad_get_dpd_register_bit(pmc, id, request, status, mask); - if (err) - return err; + if (pad->dpd == UINT_MAX) + return -EINVAL; + + *request = pad->request; + *status = pad->status; + *mask = BIT(pad->dpd); if (pmc->clk) { rate = pmc->rate; @@ -1631,13 +1603,20 @@ static void tegra_io_pad_unprepare(struct tegra_pmc *pmc) */ int tegra_io_pad_power_enable(enum tegra_io_pad id) { + const struct tegra_io_pad_soc *pad; unsigned long request, status; u32 mask; int err; + pad = tegra_io_pad_find(pmc, id); + if (!pad) { + dev_err(pmc->dev, "invalid I/O pad ID %u\n", id); + return -ENOENT; + } + mutex_lock(&pmc->powergates_lock); - err = tegra_io_pad_prepare(pmc, id, &request, &status, &mask); + err = tegra_io_pad_prepare(pmc, pad, &request, &status, &mask); if (err < 0) { dev_err(pmc->dev, "failed to prepare I/O pad: %d\n", err); goto unlock; @@ -1667,13 +1646,20 @@ EXPORT_SYMBOL(tegra_io_pad_power_enable); */ int tegra_io_pad_power_disable(enum tegra_io_pad id) { + const struct tegra_io_pad_soc *pad; unsigned long request, status; u32 mask; int err; + pad = tegra_io_pad_find(pmc, id); + if (!pad) { + dev_err(pmc->dev, "invalid I/O pad ID %u\n", id); + return -ENOENT; + } + mutex_lock(&pmc->powergates_lock); - err = tegra_io_pad_prepare(pmc, id, &request, &status, &mask); + err = tegra_io_pad_prepare(pmc, pad, &request, &status, &mask); if (err < 0) { dev_err(pmc->dev, "failed to prepare I/O pad: %d\n", err); goto unlock; @@ -1697,14 +1683,21 @@ EXPORT_SYMBOL(tegra_io_pad_power_disable); static int tegra_io_pad_is_powered(struct tegra_pmc *pmc, enum tegra_io_pad id) { - unsigned long request, status; + const struct tegra_io_pad_soc *pad; + unsigned long status; u32 mask, value; - int err; - err = tegra_io_pad_get_dpd_register_bit(pmc, id, &request, &status, - &mask); - if (err) - return err; + pad = tegra_io_pad_find(pmc, id); + if (!pad) { + dev_err(pmc->dev, "invalid I/O pad ID %u\n", id); + return -ENOENT; + } + + if (pad->dpd == UINT_MAX) + return -EINVAL; + + status = pad->status; + mask = BIT(pad->dpd); value = tegra_pmc_readl(pmc, status); @@ -3050,10 +3043,6 @@ static const char * const tegra20_powergates[] = { static const struct tegra_pmc_regs tegra20_pmc_regs = { .scratch0 = 0x50, - .dpd_req = 0x1b8, - .dpd_status = 0x1bc, - .dpd2_req = 0x1c0, - .dpd2_status = 0x1c4, .rst_status = 0x1b4, .rst_source_shift = 0x0, .rst_source_mask = 0x7, @@ -3297,59 +3286,86 @@ static const u8 tegra124_cpu_powergates[] = { TEGRA_POWERGATE_CPU3, }; -#define TEGRA_IO_PAD(_id, _dpd, _voltage, _name) \ - ((struct tegra_io_pad_soc) { \ - .id = (_id), \ - .dpd = (_dpd), \ - .voltage = (_voltage), \ - .name = (_name), \ +#define TEGRA_IO_PAD(_id, _dpd, _request, _status, _voltage, _name) \ + ((struct tegra_io_pad_soc) { \ + .id = (_id), \ + .dpd = (_dpd), \ + .request = (_request), \ + .status = (_status), \ + .voltage = (_voltage), \ + .name = (_name), \ }) -#define TEGRA_IO_PIN_DESC(_id, _dpd, _voltage, _name) \ - ((struct pinctrl_pin_desc) { \ - .number = (_id), \ - .name = (_name) \ +#define TEGRA_IO_PIN_DESC(_id, _name) \ + ((struct pinctrl_pin_desc) { \ + .number = (_id), \ + .name = (_name), \ }) -#define TEGRA124_IO_PAD_TABLE(_pad) \ - /* .id .dpd .voltage .name */ \ - _pad(TEGRA_IO_PAD_AUDIO, 17, UINT_MAX, "audio"), \ - _pad(TEGRA_IO_PAD_BB, 15, UINT_MAX, "bb"), \ - _pad(TEGRA_IO_PAD_CAM, 36, UINT_MAX, "cam"), \ - _pad(TEGRA_IO_PAD_COMP, 22, UINT_MAX, "comp"), \ - _pad(TEGRA_IO_PAD_CSIA, 0, UINT_MAX, "csia"), \ - _pad(TEGRA_IO_PAD_CSIB, 1, UINT_MAX, "csb"), \ - _pad(TEGRA_IO_PAD_CSIE, 44, UINT_MAX, "cse"), \ - _pad(TEGRA_IO_PAD_DSI, 2, UINT_MAX, "dsi"), \ - _pad(TEGRA_IO_PAD_DSIB, 39, UINT_MAX, "dsib"), \ - _pad(TEGRA_IO_PAD_DSIC, 40, UINT_MAX, "dsic"), \ - _pad(TEGRA_IO_PAD_DSID, 41, UINT_MAX, "dsid"), \ - _pad(TEGRA_IO_PAD_HDMI, 28, UINT_MAX, "hdmi"), \ - _pad(TEGRA_IO_PAD_HSIC, 19, UINT_MAX, "hsic"), \ - _pad(TEGRA_IO_PAD_HV, 38, UINT_MAX, "hv"), \ - _pad(TEGRA_IO_PAD_LVDS, 57, UINT_MAX, "lvds"), \ - _pad(TEGRA_IO_PAD_MIPI_BIAS, 3, UINT_MAX, "mipi-bias"), \ - _pad(TEGRA_IO_PAD_NAND, 13, UINT_MAX, "nand"), \ - _pad(TEGRA_IO_PAD_PEX_BIAS, 4, UINT_MAX, "pex-bias"), \ - _pad(TEGRA_IO_PAD_PEX_CLK1, 5, UINT_MAX, "pex-clk1"), \ - _pad(TEGRA_IO_PAD_PEX_CLK2, 6, UINT_MAX, "pex-clk2"), \ - _pad(TEGRA_IO_PAD_PEX_CNTRL, 32, UINT_MAX, "pex-cntrl"), \ - _pad(TEGRA_IO_PAD_SDMMC1, 33, UINT_MAX, "sdmmc1"), \ - _pad(TEGRA_IO_PAD_SDMMC3, 34, UINT_MAX, "sdmmc3"), \ - _pad(TEGRA_IO_PAD_SDMMC4, 35, UINT_MAX, "sdmmc4"), \ - _pad(TEGRA_IO_PAD_SYS_DDC, 58, UINT_MAX, "sys_ddc"), \ - _pad(TEGRA_IO_PAD_UART, 14, UINT_MAX, "uart"), \ - _pad(TEGRA_IO_PAD_USB0, 9, UINT_MAX, "usb0"), \ - _pad(TEGRA_IO_PAD_USB1, 10, UINT_MAX, "usb1"), \ - _pad(TEGRA_IO_PAD_USB2, 11, UINT_MAX, "usb2"), \ - _pad(TEGRA_IO_PAD_USB_BIAS, 12, UINT_MAX, "usb_bias") - static const struct tegra_io_pad_soc tegra124_io_pads[] = { - TEGRA124_IO_PAD_TABLE(TEGRA_IO_PAD) + TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO, 17, 0x1b8, 0x1bc, UINT_MAX, "audio"), + TEGRA_IO_PAD(TEGRA_IO_PAD_BB, 15, 0x1b8, 0x1bc, UINT_MAX, "bb"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CAM, 4, 0x1c0, 0x1c4, UINT_MAX, "cam"), + TEGRA_IO_PAD(TEGRA_IO_PAD_COMP, 22, 0x1b8, 0x1bc, UINT_MAX, "comp"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0x1b8, 0x1bc, UINT_MAX, "csia"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0x1b8, 0x1bc, UINT_MAX, "csib"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CSIE, 12, 0x1c0, 0x1c4, UINT_MAX, "csie"), + TEGRA_IO_PAD(TEGRA_IO_PAD_DSI, 2, 0x1b8, 0x1bc, UINT_MAX, "dsi"), + TEGRA_IO_PAD(TEGRA_IO_PAD_DSIB, 7, 0x1c0, 0x1c4, UINT_MAX, "dsib"), + TEGRA_IO_PAD(TEGRA_IO_PAD_DSIC, 8, 0x1c0, 0x1c4, UINT_MAX, "dsic"), + TEGRA_IO_PAD(TEGRA_IO_PAD_DSID, 9, 0x1c0, 0x1c4, UINT_MAX, "dsid"), + TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI, 28, 0x1b8, 0x1bc, UINT_MAX, "hdmi"), + TEGRA_IO_PAD(TEGRA_IO_PAD_HSIC, 19, 0x1b8, 0x1bc, UINT_MAX, "hsic"), + TEGRA_IO_PAD(TEGRA_IO_PAD_HV, 6, 0x1c0, 0x1c4, UINT_MAX, "hv"), + TEGRA_IO_PAD(TEGRA_IO_PAD_LVDS, 25, 0x1c0, 0x1c4, UINT_MAX, "lvds"), + TEGRA_IO_PAD(TEGRA_IO_PAD_MIPI_BIAS, 3, 0x1b8, 0x1bc, UINT_MAX, "mipi-bias"), + TEGRA_IO_PAD(TEGRA_IO_PAD_NAND, 13, 0x1b8, 0x1bc, UINT_MAX, "nand"), + TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_BIAS, 4, 0x1b8, 0x1bc, UINT_MAX, "pex-bias"), + TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK1, 5, 0x1b8, 0x1bc, UINT_MAX, "pex-clk1"), + TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK2, 6, 0x1b8, 0x1bc, UINT_MAX, "pex-clk2"), + TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CNTRL, 0, 0x1c0, 0x1c4, UINT_MAX, "pex-cntrl"), + TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1, 1, 0x1c0, 0x1c4, UINT_MAX, "sdmmc1"), + TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC3, 2, 0x1c0, 0x1c4, UINT_MAX, "sdmmc3"), + TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC4, 3, 0x1c0, 0x1c4, UINT_MAX, "sdmmc4"), + TEGRA_IO_PAD(TEGRA_IO_PAD_SYS_DDC, 26, 0x1c0, 0x1c4, UINT_MAX, "sys_ddc"), + TEGRA_IO_PAD(TEGRA_IO_PAD_UART, 14, 0x1b8, 0x1bc, UINT_MAX, "uart"), + TEGRA_IO_PAD(TEGRA_IO_PAD_USB0, 9, 0x1b8, 0x1bc, UINT_MAX, "usb0"), + TEGRA_IO_PAD(TEGRA_IO_PAD_USB1, 10, 0x1b8, 0x1bc, UINT_MAX, "usb1"), + TEGRA_IO_PAD(TEGRA_IO_PAD_USB2, 11, 0x1b8, 0x1bc, UINT_MAX, "usb2"), + TEGRA_IO_PAD(TEGRA_IO_PAD_USB_BIAS, 12, 0x1b8, 0x1bc, UINT_MAX, "usb_bias"), }; static const struct pinctrl_pin_desc tegra124_pin_descs[] = { - TEGRA124_IO_PAD_TABLE(TEGRA_IO_PIN_DESC) + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_AUDIO, "audio"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_BB, "bb"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CAM, "cam"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_COMP, "comp"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIA, "csia"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIB, "csib"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIE, "csie"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_DSI, "dsi"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_DSIB, "dsib"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_DSIC, "dsic"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_DSID, "dsid"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_HDMI, "hdmi"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_HSIC, "hsic"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_HV, "hv"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_LVDS, "lvds"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_MIPI_BIAS, "mipi-bias"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_NAND, "nand"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_PEX_BIAS, "pex-bias"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_PEX_CLK1, "pex-clk1"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_PEX_CLK2, "pex-clk2"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_PEX_CNTRL, "pex-cntrl"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_SDMMC1, "sdmmc1"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_SDMMC3, "sdmmc3"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_SDMMC4, "sdmmc4"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_SYS_DDC, "sys_ddc"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_UART, "uart"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_USB0, "usb0"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_USB1, "usb1"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_USB2, "usb2"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_USB_BIAS, "usb_bias"), }; static const struct tegra_pmc_soc tegra124_pmc_soc = { @@ -3415,53 +3431,86 @@ static const u8 tegra210_cpu_powergates[] = { TEGRA_POWERGATE_CPU3, }; -#define TEGRA210_IO_PAD_TABLE(_pad) \ - /* .id .dpd .voltage .name */ \ - _pad(TEGRA_IO_PAD_AUDIO, 17, 5, "audio"), \ - _pad(TEGRA_IO_PAD_AUDIO_HV, 61, 18, "audio-hv"), \ - _pad(TEGRA_IO_PAD_CAM, 36, 10, "cam"), \ - _pad(TEGRA_IO_PAD_CSIA, 0, UINT_MAX, "csia"), \ - _pad(TEGRA_IO_PAD_CSIB, 1, UINT_MAX, "csib"), \ - _pad(TEGRA_IO_PAD_CSIC, 42, UINT_MAX, "csic"), \ - _pad(TEGRA_IO_PAD_CSID, 43, UINT_MAX, "csid"), \ - _pad(TEGRA_IO_PAD_CSIE, 44, UINT_MAX, "csie"), \ - _pad(TEGRA_IO_PAD_CSIF, 45, UINT_MAX, "csif"), \ - _pad(TEGRA_IO_PAD_DBG, 25, 19, "dbg"), \ - _pad(TEGRA_IO_PAD_DEBUG_NONAO, 26, UINT_MAX, "debug-nonao"), \ - _pad(TEGRA_IO_PAD_DMIC, 50, 20, "dmic"), \ - _pad(TEGRA_IO_PAD_DP, 51, UINT_MAX, "dp"), \ - _pad(TEGRA_IO_PAD_DSI, 2, UINT_MAX, "dsi"), \ - _pad(TEGRA_IO_PAD_DSIB, 39, UINT_MAX, "dsib"), \ - _pad(TEGRA_IO_PAD_DSIC, 40, UINT_MAX, "dsic"), \ - _pad(TEGRA_IO_PAD_DSID, 41, UINT_MAX, "dsid"), \ - _pad(TEGRA_IO_PAD_EMMC, 35, UINT_MAX, "emmc"), \ - _pad(TEGRA_IO_PAD_EMMC2, 37, UINT_MAX, "emmc2"), \ - _pad(TEGRA_IO_PAD_GPIO, 27, 21, "gpio"), \ - _pad(TEGRA_IO_PAD_HDMI, 28, UINT_MAX, "hdmi"), \ - _pad(TEGRA_IO_PAD_HSIC, 19, UINT_MAX, "hsic"), \ - _pad(TEGRA_IO_PAD_LVDS, 57, UINT_MAX, "lvds"), \ - _pad(TEGRA_IO_PAD_MIPI_BIAS, 3, UINT_MAX, "mipi-bias"), \ - _pad(TEGRA_IO_PAD_PEX_BIAS, 4, UINT_MAX, "pex-bias"), \ - _pad(TEGRA_IO_PAD_PEX_CLK1, 5, UINT_MAX, "pex-clk1"), \ - _pad(TEGRA_IO_PAD_PEX_CLK2, 6, UINT_MAX, "pex-clk2"), \ - _pad(TEGRA_IO_PAD_PEX_CNTRL, UINT_MAX, 11, "pex-cntrl"), \ - _pad(TEGRA_IO_PAD_SDMMC1, 33, 12, "sdmmc1"), \ - _pad(TEGRA_IO_PAD_SDMMC3, 34, 13, "sdmmc3"), \ - _pad(TEGRA_IO_PAD_SPI, 46, 22, "spi"), \ - _pad(TEGRA_IO_PAD_SPI_HV, 47, 23, "spi-hv"), \ - _pad(TEGRA_IO_PAD_UART, 14, 2, "uart"), \ - _pad(TEGRA_IO_PAD_USB0, 9, UINT_MAX, "usb0"), \ - _pad(TEGRA_IO_PAD_USB1, 10, UINT_MAX, "usb1"), \ - _pad(TEGRA_IO_PAD_USB2, 11, UINT_MAX, "usb2"), \ - _pad(TEGRA_IO_PAD_USB3, 18, UINT_MAX, "usb3"), \ - _pad(TEGRA_IO_PAD_USB_BIAS, 12, UINT_MAX, "usb-bias") - static const struct tegra_io_pad_soc tegra210_io_pads[] = { - TEGRA210_IO_PAD_TABLE(TEGRA_IO_PAD) + TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO, 17, 0x1b8, 0x1bc, 5, "audio"), + TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO_HV, 29, 0x1c0, 0x1c4, 18, "audio-hv"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CAM, 4, 0x1c0, 0x1c4, 10, "cam"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0x1b8, 0x1bc, UINT_MAX, "csia"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0x1b8, 0x1bc, UINT_MAX, "csib"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CSIC, 10, 0x1c0, 0x1c4, UINT_MAX, "csic"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CSID, 11, 0x1c0, 0x1c4, UINT_MAX, "csid"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CSIE, 12, 0x1c0, 0x1c4, UINT_MAX, "csie"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CSIF, 13, 0x1c0, 0x1c4, UINT_MAX, "csif"), + TEGRA_IO_PAD(TEGRA_IO_PAD_DBG, 25, 0x1b8, 0x1bc, 19, "dbg"), + TEGRA_IO_PAD(TEGRA_IO_PAD_DEBUG_NONAO, 26, 0x1b8, 0x1bc, UINT_MAX, "debug-nonao"), + TEGRA_IO_PAD(TEGRA_IO_PAD_DMIC, 18, 0x1c0, 0x1c4, 20, "dmic"), + TEGRA_IO_PAD(TEGRA_IO_PAD_DP, 19, 0x1c0, 0x1c4, UINT_MAX, "dp"), + TEGRA_IO_PAD(TEGRA_IO_PAD_DSI, 2, 0x1b8, 0x1bc, UINT_MAX, "dsi"), + TEGRA_IO_PAD(TEGRA_IO_PAD_DSIB, 7, 0x1c0, 0x1c4, UINT_MAX, "dsib"), + TEGRA_IO_PAD(TEGRA_IO_PAD_DSIC, 8, 0x1c0, 0x1c4, UINT_MAX, "dsic"), + TEGRA_IO_PAD(TEGRA_IO_PAD_DSID, 9, 0x1c0, 0x1c4, UINT_MAX, "dsid"), + TEGRA_IO_PAD(TEGRA_IO_PAD_EMMC, 3, 0x1c0, 0x1c4, UINT_MAX, "emmc"), + TEGRA_IO_PAD(TEGRA_IO_PAD_EMMC2, 5, 0x1c0, 0x1c4, UINT_MAX, "emmc2"), + TEGRA_IO_PAD(TEGRA_IO_PAD_GPIO, 27, 0x1b8, 0x1bc, 21, "gpio"), + TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI, 28, 0x1b8, 0x1bc, UINT_MAX, "hdmi"), + TEGRA_IO_PAD(TEGRA_IO_PAD_HSIC, 19, 0x1b8, 0x1bc, UINT_MAX, "hsic"), + TEGRA_IO_PAD(TEGRA_IO_PAD_LVDS, 25, 0x1c0, 0x1c4, UINT_MAX, "lvds"), + TEGRA_IO_PAD(TEGRA_IO_PAD_MIPI_BIAS, 3, 0x1b8, 0x1bc, UINT_MAX, "mipi-bias"), + TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_BIAS, 4, 0x1b8, 0x1bc, UINT_MAX, "pex-bias"), + TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK1, 5, 0x1b8, 0x1bc, UINT_MAX, "pex-clk1"), + TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK2, 6, 0x1b8, 0x1bc, UINT_MAX, "pex-clk2"), + TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CNTRL, UINT_MAX, UINT_MAX, UINT_MAX, 11, "pex-cntrl"), + TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1, 1, 0x1c0, 0x1c4, 12, "sdmmc1"), + TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC3, 2, 0x1c0, 0x1c4, 13, "sdmmc3"), + TEGRA_IO_PAD(TEGRA_IO_PAD_SPI, 14, 0x1c0, 0x1c4, 22, "spi"), + TEGRA_IO_PAD(TEGRA_IO_PAD_SPI_HV, 15, 0x1c0, 0x1c4, 23, "spi-hv"), + TEGRA_IO_PAD(TEGRA_IO_PAD_UART, 14, 0x1b8, 0x1bc, 2, "uart"), + TEGRA_IO_PAD(TEGRA_IO_PAD_USB0, 9, 0x1b8, 0x1bc, UINT_MAX, "usb0"), + TEGRA_IO_PAD(TEGRA_IO_PAD_USB1, 10, 0x1b8, 0x1bc, UINT_MAX, "usb1"), + TEGRA_IO_PAD(TEGRA_IO_PAD_USB2, 11, 0x1b8, 0x1bc, UINT_MAX, "usb2"), + TEGRA_IO_PAD(TEGRA_IO_PAD_USB3, 18, 0x1b8, 0x1bc, UINT_MAX, "usb3"), + TEGRA_IO_PAD(TEGRA_IO_PAD_USB_BIAS, 12, 0x1b8, 0x1bc, UINT_MAX, "usb-bias"), }; static const struct pinctrl_pin_desc tegra210_pin_descs[] = { - TEGRA210_IO_PAD_TABLE(TEGRA_IO_PIN_DESC) + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_AUDIO, "audio"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_AUDIO_HV, "audio-hv"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CAM, "cam"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIA, "csia"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIB, "csib"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIC, "csic"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSID, "csid"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIE, "csie"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIF, "csif"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_DBG, "dbg"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_DEBUG_NONAO, "debug-nonao"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_DMIC, "dmic"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_DP, "dp"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_DSI, "dsi"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_DSIB, "dsib"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_DSIC, "dsic"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_DSID, "dsid"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_EMMC, "emmc"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_EMMC2, "emmc2"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_GPIO, "gpio"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_HDMI, "hdmi"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_HSIC, "hsic"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_LVDS, "lvds"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_MIPI_BIAS, "mipi-bias"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_PEX_BIAS, "pex-bias"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_PEX_CLK1, "pex-clk1"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_PEX_CLK2, "pex-clk2"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_PEX_CNTRL, "pex-cntrl"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_SDMMC1, "sdmmc1"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_SDMMC3, "sdmmc3"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_SPI, "spi"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_SPI_HV, "spi-hv"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_UART, "uart"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_USB0, "usb0"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_USB1, "usb1"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_USB2, "usb2"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_USB3, "usb3"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_USB_BIAS, "usb-bias"), }; static const char * const tegra210_reset_sources[] = { @@ -3511,61 +3560,90 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = { .has_usb_sleepwalk = true, }; -#define TEGRA186_IO_PAD_TABLE(_pad) \ - /* .id .dpd .voltage .name */ \ - _pad(TEGRA_IO_PAD_CSIA, 0, UINT_MAX, "csia"), \ - _pad(TEGRA_IO_PAD_CSIB, 1, UINT_MAX, "csib"), \ - _pad(TEGRA_IO_PAD_DSI, 2, UINT_MAX, "dsi"), \ - _pad(TEGRA_IO_PAD_MIPI_BIAS, 3, UINT_MAX, "mipi-bias"), \ - _pad(TEGRA_IO_PAD_PEX_CLK_BIAS, 4, UINT_MAX, "pex-clk-bias"), \ - _pad(TEGRA_IO_PAD_PEX_CLK3, 5, UINT_MAX, "pex-clk3"), \ - _pad(TEGRA_IO_PAD_PEX_CLK2, 6, UINT_MAX, "pex-clk2"), \ - _pad(TEGRA_IO_PAD_PEX_CLK1, 7, UINT_MAX, "pex-clk1"), \ - _pad(TEGRA_IO_PAD_USB0, 9, UINT_MAX, "usb0"), \ - _pad(TEGRA_IO_PAD_USB1, 10, UINT_MAX, "usb1"), \ - _pad(TEGRA_IO_PAD_USB2, 11, UINT_MAX, "usb2"), \ - _pad(TEGRA_IO_PAD_USB_BIAS, 12, UINT_MAX, "usb-bias"), \ - _pad(TEGRA_IO_PAD_UART, 14, UINT_MAX, "uart"), \ - _pad(TEGRA_IO_PAD_AUDIO, 17, UINT_MAX, "audio"), \ - _pad(TEGRA_IO_PAD_HSIC, 19, UINT_MAX, "hsic"), \ - _pad(TEGRA_IO_PAD_DBG, 25, UINT_MAX, "dbg"), \ - _pad(TEGRA_IO_PAD_HDMI_DP0, 28, UINT_MAX, "hdmi-dp0"), \ - _pad(TEGRA_IO_PAD_HDMI_DP1, 29, UINT_MAX, "hdmi-dp1"), \ - _pad(TEGRA_IO_PAD_PEX_CNTRL, 32, UINT_MAX, "pex-cntrl"), \ - _pad(TEGRA_IO_PAD_SDMMC2_HV, 34, 5, "sdmmc2-hv"), \ - _pad(TEGRA_IO_PAD_SDMMC4, 36, UINT_MAX, "sdmmc4"), \ - _pad(TEGRA_IO_PAD_CAM, 38, UINT_MAX, "cam"), \ - _pad(TEGRA_IO_PAD_DSIB, 40, UINT_MAX, "dsib"), \ - _pad(TEGRA_IO_PAD_DSIC, 41, UINT_MAX, "dsic"), \ - _pad(TEGRA_IO_PAD_DSID, 42, UINT_MAX, "dsid"), \ - _pad(TEGRA_IO_PAD_CSIC, 43, UINT_MAX, "csic"), \ - _pad(TEGRA_IO_PAD_CSID, 44, UINT_MAX, "csid"), \ - _pad(TEGRA_IO_PAD_CSIE, 45, UINT_MAX, "csie"), \ - _pad(TEGRA_IO_PAD_CSIF, 46, UINT_MAX, "csif"), \ - _pad(TEGRA_IO_PAD_SPI, 47, UINT_MAX, "spi"), \ - _pad(TEGRA_IO_PAD_UFS, 49, UINT_MAX, "ufs"), \ - _pad(TEGRA_IO_PAD_DMIC_HV, 52, 2, "dmic-hv"), \ - _pad(TEGRA_IO_PAD_EDP, 53, UINT_MAX, "edp"), \ - _pad(TEGRA_IO_PAD_SDMMC1_HV, 55, 4, "sdmmc1-hv"), \ - _pad(TEGRA_IO_PAD_SDMMC3_HV, 56, 6, "sdmmc3-hv"), \ - _pad(TEGRA_IO_PAD_CONN, 60, UINT_MAX, "conn"), \ - _pad(TEGRA_IO_PAD_AUDIO_HV, 61, 1, "audio-hv"), \ - _pad(TEGRA_IO_PAD_AO_HV, UINT_MAX, 0, "ao-hv") - static const struct tegra_io_pad_soc tegra186_io_pads[] = { - TEGRA186_IO_PAD_TABLE(TEGRA_IO_PAD) + TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0x74, 0x78, UINT_MAX, "csia"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0x74, 0x78, UINT_MAX, "csib"), + TEGRA_IO_PAD(TEGRA_IO_PAD_DSI, 2, 0x74, 0x78, UINT_MAX, "dsi"), + TEGRA_IO_PAD(TEGRA_IO_PAD_MIPI_BIAS, 3, 0x74, 0x78, UINT_MAX, "mipi-bias"), + TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK_BIAS, 4, 0x74, 0x78, UINT_MAX, "pex-clk-bias"), + TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK3, 5, 0x74, 0x78, UINT_MAX, "pex-clk3"), + TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK2, 6, 0x74, 0x78, UINT_MAX, "pex-clk2"), + TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK1, 7, 0x74, 0x78, UINT_MAX, "pex-clk1"), + TEGRA_IO_PAD(TEGRA_IO_PAD_USB0, 9, 0x74, 0x78, UINT_MAX, "usb0"), + TEGRA_IO_PAD(TEGRA_IO_PAD_USB1, 10, 0x74, 0x78, UINT_MAX, "usb1"), + TEGRA_IO_PAD(TEGRA_IO_PAD_USB2, 11, 0x74, 0x78, UINT_MAX, "usb2"), + TEGRA_IO_PAD(TEGRA_IO_PAD_USB_BIAS, 12, 0x74, 0x78, UINT_MAX, "usb-bias"), + TEGRA_IO_PAD(TEGRA_IO_PAD_UART, 14, 0x74, 0x78, UINT_MAX, "uart"), + TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO, 17, 0x74, 0x78, UINT_MAX, "audio"), + TEGRA_IO_PAD(TEGRA_IO_PAD_HSIC, 19, 0x74, 0x78, UINT_MAX, "hsic"), + TEGRA_IO_PAD(TEGRA_IO_PAD_DBG, 25, 0x74, 0x78, UINT_MAX, "dbg"), + TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP0, 28, 0x74, 0x78, UINT_MAX, "hdmi-dp0"), + TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP1, 29, 0x74, 0x78, UINT_MAX, "hdmi-dp1"), + TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CNTRL, 0, 0x7c, 0x80, UINT_MAX, "pex-cntrl"), + TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC2_HV, 2, 0x7c, 0x80, 5, "sdmmc2-hv"), + TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC4, 4, 0x7c, 0x80, UINT_MAX, "sdmmc4"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CAM, 6, 0x7c, 0x80, UINT_MAX, "cam"), + TEGRA_IO_PAD(TEGRA_IO_PAD_DSIB, 8, 0x7c, 0x80, UINT_MAX, "dsib"), + TEGRA_IO_PAD(TEGRA_IO_PAD_DSIC, 9, 0x7c, 0x80, UINT_MAX, "dsic"), + TEGRA_IO_PAD(TEGRA_IO_PAD_DSID, 10, 0x7c, 0x80, UINT_MAX, "dsid"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CSIC, 11, 0x7c, 0x80, UINT_MAX, "csic"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CSID, 12, 0x7c, 0x80, UINT_MAX, "csid"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CSIE, 13, 0x7c, 0x80, UINT_MAX, "csie"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CSIF, 14, 0x7c, 0x80, UINT_MAX, "csif"), + TEGRA_IO_PAD(TEGRA_IO_PAD_SPI, 15, 0x7c, 0x80, UINT_MAX, "spi"), + TEGRA_IO_PAD(TEGRA_IO_PAD_UFS, 17, 0x7c, 0x80, UINT_MAX, "ufs"), + TEGRA_IO_PAD(TEGRA_IO_PAD_DMIC_HV, 20, 0x7c, 0x80, 2, "dmic-hv"), + TEGRA_IO_PAD(TEGRA_IO_PAD_EDP, 21, 0x7c, 0x80, UINT_MAX, "edp"), + TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1_HV, 23, 0x7c, 0x80, 4, "sdmmc1-hv"), + TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC3_HV, 24, 0x7c, 0x80, 6, "sdmmc3-hv"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CONN, 28, 0x7c, 0x80, UINT_MAX, "conn"), + TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO_HV, 29, 0x7c, 0x80, 1, "audio-hv"), + TEGRA_IO_PAD(TEGRA_IO_PAD_AO_HV, UINT_MAX, UINT_MAX, UINT_MAX, 0, "ao-hv"), }; static const struct pinctrl_pin_desc tegra186_pin_descs[] = { - TEGRA186_IO_PAD_TABLE(TEGRA_IO_PIN_DESC) + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIA, "csia"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIB, "csib"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_DSI, "dsi"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_MIPI_BIAS, "mipi-bias"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_PEX_CLK_BIAS, "pex-clk-bias"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_PEX_CLK3, "pex-clk3"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_PEX_CLK2, "pex-clk2"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_PEX_CLK1, "pex-clk1"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_USB0, "usb0"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_USB1, "usb1"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_USB2, "usb2"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_USB_BIAS, "usb-bias"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_UART, "uart"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_AUDIO, "audio"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_HSIC, "hsic"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_DBG, "dbg"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_HDMI_DP0, "hdmi-dp0"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_HDMI_DP1, "hdmi-dp1"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_PEX_CNTRL, "pex-cntrl"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_SDMMC2_HV, "sdmmc2-hv"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_SDMMC4, "sdmmc4"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CAM, "cam"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_DSIB, "dsib"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_DSIC, "dsic"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_DSID, "dsid"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIC, "csic"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSID, "csid"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIE, "csie"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIF, "csif"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_SPI, "spi"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_UFS, "ufs"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_DMIC_HV, "dmic-hv"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_EDP, "edp"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_SDMMC1_HV, "sdmmc1-hv"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_SDMMC3_HV, "sdmmc3-hv"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CONN, "conn"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_AUDIO_HV, "audio-hv"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_AO_HV, "ao-hv"), }; static const struct tegra_pmc_regs tegra186_pmc_regs = { .scratch0 = 0x2000, - .dpd_req = 0x74, - .dpd_status = 0x78, - .dpd2_req = 0x7c, - .dpd2_status = 0x80, .rst_status = 0x70, .rst_source_shift = 0x2, .rst_source_mask = 0x3c, @@ -3668,72 +3746,112 @@ static const struct tegra_pmc_soc tegra186_pmc_soc = { .has_usb_sleepwalk = false, }; -#define TEGRA194_IO_PAD_TABLE(_pad) \ - /* .id .dpd .voltage .name */ \ - _pad(TEGRA_IO_PAD_CSIA, 0, UINT_MAX, "csia"), \ - _pad(TEGRA_IO_PAD_CSIB, 1, UINT_MAX, "csib"), \ - _pad(TEGRA_IO_PAD_MIPI_BIAS, 3, UINT_MAX, "mipi-bias"), \ - _pad(TEGRA_IO_PAD_PEX_CLK_BIAS, 4, UINT_MAX, "pex-clk-bias"), \ - _pad(TEGRA_IO_PAD_PEX_CLK3, 5, UINT_MAX, "pex-clk3"), \ - _pad(TEGRA_IO_PAD_PEX_CLK2, 6, UINT_MAX, "pex-clk2"), \ - _pad(TEGRA_IO_PAD_PEX_CLK1, 7, UINT_MAX, "pex-clk1"), \ - _pad(TEGRA_IO_PAD_EQOS, 8, UINT_MAX, "eqos"), \ - _pad(TEGRA_IO_PAD_PEX_CLK_2_BIAS, 9, UINT_MAX, "pex-clk-2-bias"), \ - _pad(TEGRA_IO_PAD_PEX_CLK_2, 10, UINT_MAX, "pex-clk-2"), \ - _pad(TEGRA_IO_PAD_DAP3, 11, UINT_MAX, "dap3"), \ - _pad(TEGRA_IO_PAD_DAP5, 12, UINT_MAX, "dap5"), \ - _pad(TEGRA_IO_PAD_UART, 14, UINT_MAX, "uart"), \ - _pad(TEGRA_IO_PAD_PWR_CTL, 15, UINT_MAX, "pwr-ctl"), \ - _pad(TEGRA_IO_PAD_SOC_GPIO53, 16, UINT_MAX, "soc-gpio53"), \ - _pad(TEGRA_IO_PAD_AUDIO, 17, UINT_MAX, "audio"), \ - _pad(TEGRA_IO_PAD_GP_PWM2, 18, UINT_MAX, "gp-pwm2"), \ - _pad(TEGRA_IO_PAD_GP_PWM3, 19, UINT_MAX, "gp-pwm3"), \ - _pad(TEGRA_IO_PAD_SOC_GPIO12, 20, UINT_MAX, "soc-gpio12"), \ - _pad(TEGRA_IO_PAD_SOC_GPIO13, 21, UINT_MAX, "soc-gpio13"), \ - _pad(TEGRA_IO_PAD_SOC_GPIO10, 22, UINT_MAX, "soc-gpio10"), \ - _pad(TEGRA_IO_PAD_UART4, 23, UINT_MAX, "uart4"), \ - _pad(TEGRA_IO_PAD_UART5, 24, UINT_MAX, "uart5"), \ - _pad(TEGRA_IO_PAD_DBG, 25, UINT_MAX, "dbg"), \ - _pad(TEGRA_IO_PAD_HDMI_DP3, 26, UINT_MAX, "hdmi-dp3"), \ - _pad(TEGRA_IO_PAD_HDMI_DP2, 27, UINT_MAX, "hdmi-dp2"), \ - _pad(TEGRA_IO_PAD_HDMI_DP0, 28, UINT_MAX, "hdmi-dp0"), \ - _pad(TEGRA_IO_PAD_HDMI_DP1, 29, UINT_MAX, "hdmi-dp1"), \ - _pad(TEGRA_IO_PAD_PEX_CNTRL, 32, UINT_MAX, "pex-cntrl"), \ - _pad(TEGRA_IO_PAD_PEX_CTL2, 33, UINT_MAX, "pex-ctl2"), \ - _pad(TEGRA_IO_PAD_PEX_L0_RST_N, 34, UINT_MAX, "pex-l0-rst"), \ - _pad(TEGRA_IO_PAD_PEX_L1_RST_N, 35, UINT_MAX, "pex-l1-rst"), \ - _pad(TEGRA_IO_PAD_SDMMC4, 36, UINT_MAX, "sdmmc4"), \ - _pad(TEGRA_IO_PAD_PEX_L5_RST_N, 37, UINT_MAX, "pex-l5-rst"), \ - _pad(TEGRA_IO_PAD_CAM, 38, UINT_MAX, "cam"), \ - _pad(TEGRA_IO_PAD_CSIC, 43, UINT_MAX, "csic"), \ - _pad(TEGRA_IO_PAD_CSID, 44, UINT_MAX, "csid"), \ - _pad(TEGRA_IO_PAD_CSIE, 45, UINT_MAX, "csie"), \ - _pad(TEGRA_IO_PAD_CSIF, 46, UINT_MAX, "csif"), \ - _pad(TEGRA_IO_PAD_SPI, 47, UINT_MAX, "spi"), \ - _pad(TEGRA_IO_PAD_UFS, 49, UINT_MAX, "ufs"), \ - _pad(TEGRA_IO_PAD_CSIG, 50, UINT_MAX, "csig"), \ - _pad(TEGRA_IO_PAD_CSIH, 51, UINT_MAX, "csih"), \ - _pad(TEGRA_IO_PAD_EDP, 53, UINT_MAX, "edp"), \ - _pad(TEGRA_IO_PAD_SDMMC1_HV, 55, 4, "sdmmc1-hv"), \ - _pad(TEGRA_IO_PAD_SDMMC3_HV, 56, 6, "sdmmc3-hv"), \ - _pad(TEGRA_IO_PAD_CONN, 60, UINT_MAX, "conn"), \ - _pad(TEGRA_IO_PAD_AUDIO_HV, 61, 1, "audio-hv"), \ - _pad(TEGRA_IO_PAD_AO_HV, UINT_MAX, 0, "ao-hv") - static const struct tegra_io_pad_soc tegra194_io_pads[] = { - TEGRA194_IO_PAD_TABLE(TEGRA_IO_PAD) + TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0x74, 0x78, UINT_MAX, "csia"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0x74, 0x78, UINT_MAX, "csib"), + TEGRA_IO_PAD(TEGRA_IO_PAD_MIPI_BIAS, 3, 0x74, 0x78, UINT_MAX, "mipi-bias"), + TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK_BIAS, 4, 0x74, 0x78, UINT_MAX, "pex-clk-bias"), + TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK3, 5, 0x74, 0x78, UINT_MAX, "pex-clk3"), + TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK2, 6, 0x74, 0x78, UINT_MAX, "pex-clk2"), + TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK1, 7, 0x74, 0x78, UINT_MAX, "pex-clk1"), + TEGRA_IO_PAD(TEGRA_IO_PAD_EQOS, 8, 0x74, 0x78, UINT_MAX, "eqos"), + TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK_2_BIAS, 9, 0x74, 0x78, UINT_MAX, "pex-clk-2-bias"), + TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK_2, 10, 0x74, 0x78, UINT_MAX, "pex-clk-2"), + TEGRA_IO_PAD(TEGRA_IO_PAD_DAP3, 11, 0x74, 0x78, UINT_MAX, "dap3"), + TEGRA_IO_PAD(TEGRA_IO_PAD_DAP5, 12, 0x74, 0x78, UINT_MAX, "dap5"), + TEGRA_IO_PAD(TEGRA_IO_PAD_UART, 14, 0x74, 0x78, UINT_MAX, "uart"), + TEGRA_IO_PAD(TEGRA_IO_PAD_PWR_CTL, 15, 0x74, 0x78, UINT_MAX, "pwr-ctl"), + TEGRA_IO_PAD(TEGRA_IO_PAD_SOC_GPIO53, 16, 0x74, 0x78, UINT_MAX, "soc-gpio53"), + TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO, 17, 0x74, 0x78, UINT_MAX, "audio"), + TEGRA_IO_PAD(TEGRA_IO_PAD_GP_PWM2, 18, 0x74, 0x78, UINT_MAX, "gp-pwm2"), + TEGRA_IO_PAD(TEGRA_IO_PAD_GP_PWM3, 19, 0x74, 0x78, UINT_MAX, "gp-pwm3"), + TEGRA_IO_PAD(TEGRA_IO_PAD_SOC_GPIO12, 20, 0x74, 0x78, UINT_MAX, "soc-gpio12"), + TEGRA_IO_PAD(TEGRA_IO_PAD_SOC_GPIO13, 21, 0x74, 0x78, UINT_MAX, "soc-gpio13"), + TEGRA_IO_PAD(TEGRA_IO_PAD_SOC_GPIO10, 22, 0x74, 0x78, UINT_MAX, "soc-gpio10"), + TEGRA_IO_PAD(TEGRA_IO_PAD_UART4, 23, 0x74, 0x78, UINT_MAX, "uart4"), + TEGRA_IO_PAD(TEGRA_IO_PAD_UART5, 24, 0x74, 0x78, UINT_MAX, "uart5"), + TEGRA_IO_PAD(TEGRA_IO_PAD_DBG, 25, 0x74, 0x78, UINT_MAX, "dbg"), + TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP3, 26, 0x74, 0x78, UINT_MAX, "hdmi-dp3"), + TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP2, 27, 0x74, 0x78, UINT_MAX, "hdmi-dp2"), + TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP0, 28, 0x74, 0x78, UINT_MAX, "hdmi-dp0"), + TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP1, 29, 0x74, 0x78, UINT_MAX, "hdmi-dp1"), + TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CNTRL, 0, 0x7c, 0x80, UINT_MAX, "pex-cntrl"), + TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CTL2, 1, 0x7c, 0x80, UINT_MAX, "pex-ctl2"), + TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_L0_RST, 2, 0x7c, 0x80, UINT_MAX, "pex-l0-rst"), + TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_L1_RST, 3, 0x7c, 0x80, UINT_MAX, "pex-l1-rst"), + TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC4, 4, 0x7c, 0x80, UINT_MAX, "sdmmc4"), + TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_L5_RST, 5, 0x7c, 0x80, UINT_MAX, "pex-l5-rst"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CAM, 6, 0x7c, 0x80, UINT_MAX, "cam"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CSIC, 11, 0x7c, 0x80, UINT_MAX, "csic"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CSID, 12, 0x7c, 0x80, UINT_MAX, "csid"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CSIE, 13, 0x7c, 0x80, UINT_MAX, "csie"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CSIF, 14, 0x7c, 0x80, UINT_MAX, "csif"), + TEGRA_IO_PAD(TEGRA_IO_PAD_SPI, 15, 0x7c, 0x80, UINT_MAX, "spi"), + TEGRA_IO_PAD(TEGRA_IO_PAD_UFS, 17, 0x7c, 0x80, UINT_MAX, "ufs"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CSIG, 18, 0x7c, 0x80, UINT_MAX, "csig"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CSIH, 19, 0x7c, 0x80, UINT_MAX, "csih"), + TEGRA_IO_PAD(TEGRA_IO_PAD_EDP, 21, 0x7c, 0x80, UINT_MAX, "edp"), + TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1_HV, 23, 0x7c, 0x80, 4, "sdmmc1-hv"), + TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC3_HV, 24, 0x7c, 0x80, 6, "sdmmc3-hv"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CONN, 28, 0x7c, 0x80, UINT_MAX, "conn"), + TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO_HV, 29, 0x7c, 0x80, 1, "audio-hv"), + TEGRA_IO_PAD(TEGRA_IO_PAD_AO_HV, UINT_MAX, UINT_MAX, UINT_MAX, 0, "ao-hv"), }; static const struct pinctrl_pin_desc tegra194_pin_descs[] = { - TEGRA194_IO_PAD_TABLE(TEGRA_IO_PIN_DESC) + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIA, "csia"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIB, "csib"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_MIPI_BIAS, "mipi-bias"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_PEX_CLK_BIAS, "pex-clk-bias"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_PEX_CLK3, "pex-clk3"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_PEX_CLK2, "pex-clk2"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_PEX_CLK1, "pex-clk1"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_EQOS, "eqos"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_PEX_CLK_2_BIAS, "pex-clk-2-bias"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_PEX_CLK_2, "pex-clk-2"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_DAP3, "dap3"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_DAP5, "dap5"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_UART, "uart"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_PWR_CTL, "pwr-ctl"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_SOC_GPIO53, "soc-gpio53"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_AUDIO, "audio"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_GP_PWM2, "gp-pwm2"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_GP_PWM3, "gp-pwm3"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_SOC_GPIO12, "soc-gpio12"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_SOC_GPIO13, "soc-gpio13"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_SOC_GPIO10, "soc-gpio10"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_UART4, "uart4"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_UART5, "uart5"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_DBG, "dbg"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_HDMI_DP3, "hdmi-dp3"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_HDMI_DP2, "hdmi-dp2"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_HDMI_DP0, "hdmi-dp0"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_HDMI_DP1, "hdmi-dp1"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_PEX_CNTRL, "pex-cntrl"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_PEX_CTL2, "pex-ctl2"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_PEX_L0_RST, "pex-l0-rst"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_PEX_L1_RST, "pex-l1-rst"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_SDMMC4, "sdmmc4"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_PEX_L5_RST, "pex-l5-rst"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CAM, "cam"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIC, "csic"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSID, "csid"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIE, "csie"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIF, "csif"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_SPI, "spi"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_UFS, "ufs"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIG, "csig"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIH, "csih"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_EDP, "edp"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_SDMMC1_HV, "sdmmc1-hv"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_SDMMC3_HV, "sdmmc3-hv"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CONN, "conn"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_AUDIO_HV, "audio-hv"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_AO_HV, "ao-hv"), }; static const struct tegra_pmc_regs tegra194_pmc_regs = { .scratch0 = 0x2000, - .dpd_req = 0x74, - .dpd_status = 0x78, - .dpd2_req = 0x7c, - .dpd2_status = 0x80, .rst_status = 0x70, .rst_source_shift = 0x2, .rst_source_mask = 0x7c, @@ -3810,12 +3928,44 @@ static const struct tegra_pmc_soc tegra194_pmc_soc = { .has_usb_sleepwalk = false, }; +static const struct tegra_io_pad_soc tegra234_io_pads[] = { + TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0xe0c0, 0xe0c4, UINT_MAX, "csia"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0xe0c0, 0xe0c4, UINT_MAX, "csib"), + TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP0, 0, 0xe0d0, 0xe0d4, UINT_MAX, "hdmi-dp0"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CSIC, 2, 0xe0c0, 0xe0c4, UINT_MAX, "csic"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CSID, 3, 0xe0c0, 0xe0c4, UINT_MAX, "csid"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CSIE, 4, 0xe0c0, 0xe0c4, UINT_MAX, "csie"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CSIF, 5, 0xe0c0, 0xe0c4, UINT_MAX, "csif"), + TEGRA_IO_PAD(TEGRA_IO_PAD_UFS, 0, 0xe064, 0xe068, UINT_MAX, "ufs"), + TEGRA_IO_PAD(TEGRA_IO_PAD_EDP, 1, 0xe05c, 0xe060, UINT_MAX, "edp"), + TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1_HV, 0, 0xe054, 0xe058, 4, "sdmmc1-hv"), + TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC3_HV, UINT_MAX, UINT_MAX, UINT_MAX, 6, "sdmmc3-hv"), + TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO_HV, UINT_MAX, UINT_MAX, UINT_MAX, 1, "audio-hv"), + TEGRA_IO_PAD(TEGRA_IO_PAD_AO_HV, UINT_MAX, UINT_MAX, UINT_MAX, 0, "ao-hv"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CSIG, 6, 0xe0c0, 0xe0c4, UINT_MAX, "csig"), + TEGRA_IO_PAD(TEGRA_IO_PAD_CSIH, 7, 0xe0c0, 0xe0c4, UINT_MAX, "csih"), +}; + +static const struct pinctrl_pin_desc tegra234_pin_descs[] = { + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIA, "csia"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIB, "csib"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_HDMI_DP0, "hdmi-dp0"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIC, "csic"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSID, "csid"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIE, "csie"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIF, "csif"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_UFS, "ufs"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_EDP, "edp"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_SDMMC1_HV, "sdmmc1-hv"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_SDMMC3_HV, "sdmmc3-hv"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_AUDIO_HV, "audio-hv"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_AO_HV, "ao-hv"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIG, "csig"), + TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIH, "csih"), +}; + static const struct tegra_pmc_regs tegra234_pmc_regs = { .scratch0 = 0x2000, - .dpd_req = 0, - .dpd_status = 0, - .dpd2_req = 0, - .dpd2_status = 0, .rst_status = 0x70, .rst_source_shift = 0x2, .rst_source_mask = 0xfc, @@ -3880,10 +4030,10 @@ static const struct tegra_pmc_soc tegra234_pmc_soc = { .needs_mbist_war = false, .has_impl_33v_pwr = true, .maybe_tz_only = false, - .num_io_pads = 0, - .io_pads = NULL, - .num_pin_descs = 0, - .pin_descs = NULL, + .num_io_pads = ARRAY_SIZE(tegra234_io_pads), + .io_pads = tegra234_io_pads, + .num_pin_descs = ARRAY_SIZE(tegra234_pin_descs), + .pin_descs = tegra234_pin_descs, .regs = &tegra234_pmc_regs, .init = NULL, .setup_irq_polarity = tegra186_pmc_setup_irq_polarity, diff --git a/include/soc/tegra/pmc.h b/include/soc/tegra/pmc.h index d186bccd125d..aadb845d281d 100644 --- a/include/soc/tegra/pmc.h +++ b/include/soc/tegra/pmc.h @@ -118,9 +118,9 @@ enum tegra_io_pad { TEGRA_IO_PAD_PEX_CLK_2, TEGRA_IO_PAD_PEX_CNTRL, TEGRA_IO_PAD_PEX_CTL2, - TEGRA_IO_PAD_PEX_L0_RST_N, - TEGRA_IO_PAD_PEX_L1_RST_N, - TEGRA_IO_PAD_PEX_L5_RST_N, + TEGRA_IO_PAD_PEX_L0_RST, + TEGRA_IO_PAD_PEX_L1_RST, + TEGRA_IO_PAD_PEX_L5_RST, TEGRA_IO_PAD_PWR_CTL, TEGRA_IO_PAD_SDMMC1, TEGRA_IO_PAD_SDMMC1_HV, -- cgit v1.2.3 From 1ddb8f6d44ff482c9953a06f800453bc372cfead Mon Sep 17 00:00:00 2001 From: Petlozu Pravareshwar Date: Fri, 30 Sep 2022 16:14:52 +0000 Subject: soc/tegra: pmc: Fix dual edge triggered wakes When a wake event is defined to be triggered on both positive and negative edge of the input wake signal, it is crucial to know the current state of the signal when going into suspend. The intended way to obtain the current state of the wake signals is to read the WAKE_AOWAKE_SW_STATUS register, which should contains the raw state of the wake signals. However, this register is edge triggered, an edge will not be generated for signals that are already asserted prior to the assertion of WAKE_LATCH_SW. To workaround this, change the polarity of the wake level from '0' to '1' while latching the signals, as this will generate an edge for signals that are set to '1'. Signed-off-by: Stefan Kristiansson Signed-off-by: Petlozu Pravareshwar Signed-off-by: Thierry Reding --- drivers/soc/tegra/pmc.c | 181 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 176 insertions(+), 5 deletions(-) diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index 9a195c1e84a0..767f33303617 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -182,6 +183,9 @@ #define WAKE_AOWAKE_TIER0_ROUTING(x) (0x4b4 + ((x) << 2)) #define WAKE_AOWAKE_TIER1_ROUTING(x) (0x4c0 + ((x) << 2)) #define WAKE_AOWAKE_TIER2_ROUTING(x) (0x4cc + ((x) << 2)) +#define WAKE_AOWAKE_SW_STATUS_W_0 0x49c +#define WAKE_AOWAKE_SW_STATUS(x) (0x4a0 + ((x) << 2)) +#define WAKE_LATCH_SW 0x498 #define WAKE_AOWAKE_CTRL 0x4f4 #define WAKE_AOWAKE_CTRL_INTR_POLARITY BIT(0) @@ -367,6 +371,8 @@ struct tegra_pmc_soc { */ const struct tegra_wake_event *wake_events; unsigned int num_wake_events; + unsigned int max_wake_events; + unsigned int max_wake_vectors; const struct pmc_clk_init_data *pmc_clks_data; unsigned int num_pmc_clks; @@ -407,6 +413,11 @@ struct tegra_pmc_soc { * @clk_nb: pclk clock changes handler * @core_domain_state_synced: flag marking the core domain's state as synced * @core_domain_registered: flag marking the core domain as registered + * @wake_type_level_map: Bitmap indicating level type for non-dual edge wakes + * @wake_type_dual_edge_map: Bitmap indicating if a wake is dual-edge or not + * @wake_sw_status_map: Bitmap to hold raw status of wakes without mask + * @wake_cntrl_level_map: Bitmap to hold wake levels to be programmed in + * cntrl register associated with each wake during system suspend. */ struct tegra_pmc { struct device *dev; @@ -447,6 +458,12 @@ struct tegra_pmc { bool core_domain_state_synced; bool core_domain_registered; + + unsigned long *wake_type_level_map; + unsigned long *wake_type_dual_edge_map; + unsigned long *wake_sw_status_map; + unsigned long *wake_cntrl_level_map; + struct syscore_ops syscore; }; static struct tegra_pmc *pmc = &(struct tegra_pmc) { @@ -1923,10 +1940,30 @@ static int tegra_pmc_parse_dt(struct tegra_pmc *pmc, struct device_node *np) return 0; } -static void tegra_pmc_init(struct tegra_pmc *pmc) +static int tegra_pmc_init(struct tegra_pmc *pmc) { + if (pmc->soc->max_wake_events > 0) { + pmc->wake_type_level_map = bitmap_zalloc(pmc->soc->max_wake_events, GFP_KERNEL); + if (!pmc->wake_type_level_map) + return -ENOMEM; + + pmc->wake_type_dual_edge_map = bitmap_zalloc(pmc->soc->max_wake_events, GFP_KERNEL); + if (!pmc->wake_type_dual_edge_map) + return -ENOMEM; + + pmc->wake_sw_status_map = bitmap_zalloc(pmc->soc->max_wake_events, GFP_KERNEL); + if (!pmc->wake_sw_status_map) + return -ENOMEM; + + pmc->wake_cntrl_level_map = bitmap_zalloc(pmc->soc->max_wake_events, GFP_KERNEL); + if (!pmc->wake_cntrl_level_map) + return -ENOMEM; + } + if (pmc->soc->init) pmc->soc->init(pmc); + + return 0; } static void tegra_pmc_init_tsense_reset(struct tegra_pmc *pmc) @@ -2417,15 +2454,21 @@ static int tegra186_pmc_irq_set_type(struct irq_data *data, unsigned int type) case IRQ_TYPE_EDGE_RISING: case IRQ_TYPE_LEVEL_HIGH: value |= WAKE_AOWAKE_CNTRL_LEVEL; + set_bit(data->hwirq, pmc->wake_type_level_map); + clear_bit(data->hwirq, pmc->wake_type_dual_edge_map); break; case IRQ_TYPE_EDGE_FALLING: case IRQ_TYPE_LEVEL_LOW: value &= ~WAKE_AOWAKE_CNTRL_LEVEL; + clear_bit(data->hwirq, pmc->wake_type_level_map); + clear_bit(data->hwirq, pmc->wake_type_dual_edge_map); break; case IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING: value ^= WAKE_AOWAKE_CNTRL_LEVEL; + clear_bit(data->hwirq, pmc->wake_type_level_map); + set_bit(data->hwirq, pmc->wake_type_dual_edge_map); break; default: @@ -2957,7 +3000,11 @@ static int tegra_pmc_probe(struct platform_device *pdev) pmc->dev = &pdev->dev; - tegra_pmc_init(pmc); + err = tegra_pmc_init(pmc); + if (err < 0) { + dev_err(&pdev->dev, "failed to initialize PMC: %d\n", err); + return err; + } tegra_pmc_init_tsense_reset(pmc); @@ -3008,6 +3055,117 @@ cleanup_sysfs: return err; } +/* + * Ensures that sufficient time is passed for a register write to + * serialize into the 32KHz domain. + */ +static void wke_32kwritel(struct tegra_pmc *pmc, u32 value, unsigned int offset) +{ + writel(value, pmc->wake + offset); + udelay(130); +} + +static void wke_write_wake_level(struct tegra_pmc *pmc, int wake, int level) +{ + unsigned int offset = WAKE_AOWAKE_CNTRL(wake); + u32 value; + + value = readl(pmc->wake + offset); + if (level) + value |= WAKE_AOWAKE_CNTRL_LEVEL; + else + value &= ~WAKE_AOWA