aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2016-11-18 21:42:33 -0500
committerOlof Johansson <olof@lixom.net>2016-11-18 21:42:33 -0500
commitb029ffe00c2886dedbf17b31744f064ba0e4b3c3 (patch)
tree4d9339288ad808d7884b88f6f7a02dce38e6fdd1
parent84f1f0c199fdbdf11eddb8da07d8cd9dcfdaeeb4 (diff)
parent4522112069a976908e32e5dd3231c9272d19794a (diff)
Merge tag 'tegra-for-4.10-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into next/drivers
soc: tegra: Core SoC changes for v4.10-rc1 This contains mostly cleanup and new feature work on the power management controller as well as the addition of a Kconfig symbol for the new Tegra186 (Parker) SoC generation. * tag 'tegra-for-4.10-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux: soc/tegra: pmc: Use consistent naming for PM domains soc/tegra: pmc: Remove genpd when adding provider fails soc/tegra: pmc: Check return code for pm_genpd_init() soc/tegra: pmc: Clean-up I/O rail error messages soc/tegra: pmc: Simplify IO rail bit handling soc/tegra: pmc: Guard against uninitialised PMC clock soc/tegra: pmc: Add I/O pad voltage support soc/tegra: pmc: Use consistent ordering of bit definitions soc/tegra: pmc: Correct type of variable for tegra_pmc_readl() soc/tegra: pmc: Use BIT macro for register field definition Signed-off-by: Olof Johansson <olof@lixom.net>
-rw-r--r--drivers/soc/tegra/pmc.c398
-rw-r--r--include/soc/tegra/pmc.h126
2 files changed, 400 insertions, 124 deletions
diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 7792ed88d80b..e233dd5dcab3 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -45,29 +45,31 @@
45#include <soc/tegra/pmc.h> 45#include <soc/tegra/pmc.h>
46 46
47#define PMC_CNTRL 0x0 47#define PMC_CNTRL 0x0
48#define PMC_CNTRL_SYSCLK_POLARITY (1 << 10) /* sys clk polarity */ 48#define PMC_CNTRL_INTR_POLARITY BIT(17) /* inverts INTR polarity */
49#define PMC_CNTRL_SYSCLK_OE (1 << 11) /* system clock enable */ 49#define PMC_CNTRL_CPU_PWRREQ_OE BIT(16) /* CPU pwr req enable */
50#define PMC_CNTRL_SIDE_EFFECT_LP0 (1 << 14) /* LP0 when CPU pwr gated */ 50#define PMC_CNTRL_CPU_PWRREQ_POLARITY BIT(15) /* CPU pwr req polarity */
51#define PMC_CNTRL_CPU_PWRREQ_POLARITY (1 << 15) /* CPU pwr req polarity */ 51#define PMC_CNTRL_SIDE_EFFECT_LP0 BIT(14) /* LP0 when CPU pwr gated */
52#define PMC_CNTRL_CPU_PWRREQ_OE (1 << 16) /* CPU pwr req enable */ 52#define PMC_CNTRL_SYSCLK_OE BIT(11) /* system clock enable */
53#define PMC_CNTRL_INTR_POLARITY (1 << 17) /* inverts INTR polarity */ 53#define PMC_CNTRL_SYSCLK_POLARITY BIT(10) /* sys clk polarity */
54#define PMC_CNTRL_MAIN_RST (1 << 4) 54#define PMC_CNTRL_MAIN_RST BIT(4)
55 55
56#define DPD_SAMPLE 0x020 56#define DPD_SAMPLE 0x020
57#define DPD_SAMPLE_ENABLE (1 << 0) 57#define DPD_SAMPLE_ENABLE BIT(0)
58#define DPD_SAMPLE_DISABLE (0 << 0) 58#define DPD_SAMPLE_DISABLE (0 << 0)
59 59
60#define PWRGATE_TOGGLE 0x30 60#define PWRGATE_TOGGLE 0x30
61#define PWRGATE_TOGGLE_START (1 << 8) 61#define PWRGATE_TOGGLE_START BIT(8)
62 62
63#define REMOVE_CLAMPING 0x34 63#define REMOVE_CLAMPING 0x34
64 64
65#define PWRGATE_STATUS 0x38 65#define PWRGATE_STATUS 0x38
66 66
67#define PMC_PWR_DET 0x48
68
67#define PMC_SCRATCH0 0x50 69#define PMC_SCRATCH0 0x50
68#define PMC_SCRATCH0_MODE_RECOVERY (1 << 31) 70#define PMC_SCRATCH0_MODE_RECOVERY BIT(31)
69#define PMC_SCRATCH0_MODE_BOOTLOADER (1 << 30) 71#define PMC_SCRATCH0_MODE_BOOTLOADER BIT(30)
70#define PMC_SCRATCH0_MODE_RCM (1 << 1) 72#define PMC_SCRATCH0_MODE_RCM BIT(1)
71#define PMC_SCRATCH0_MODE_MASK (PMC_SCRATCH0_MODE_RECOVERY | \ 73#define PMC_SCRATCH0_MODE_MASK (PMC_SCRATCH0_MODE_RECOVERY | \
72 PMC_SCRATCH0_MODE_BOOTLOADER | \ 74 PMC_SCRATCH0_MODE_BOOTLOADER | \
73 PMC_SCRATCH0_MODE_RCM) 75 PMC_SCRATCH0_MODE_RCM)
@@ -75,11 +77,13 @@
75#define PMC_CPUPWRGOOD_TIMER 0xc8 77#define PMC_CPUPWRGOOD_TIMER 0xc8
76#define PMC_CPUPWROFF_TIMER 0xcc 78#define PMC_CPUPWROFF_TIMER 0xcc
77 79
80#define PMC_PWR_DET_VALUE 0xe4
81
78#define PMC_SCRATCH41 0x140 82#define PMC_SCRATCH41 0x140
79 83
80#define PMC_SENSOR_CTRL 0x1b0 84#define PMC_SENSOR_CTRL 0x1b0
81#define PMC_SENSOR_CTRL_SCRATCH_WRITE (1 << 2) 85#define PMC_SENSOR_CTRL_SCRATCH_WRITE BIT(2)
82#define PMC_SENSOR_CTRL_ENABLE_RST (1 << 1) 86#define PMC_SENSOR_CTRL_ENABLE_RST BIT(1)
83 87
84#define PMC_RST_STATUS 0x1b4 88#define PMC_RST_STATUS 0x1b4
85#define PMC_RST_STATUS_POR 0 89#define PMC_RST_STATUS_POR 0
@@ -90,10 +94,10 @@
90#define PMC_RST_STATUS_AOTAG 5 94#define PMC_RST_STATUS_AOTAG 5
91 95
92#define IO_DPD_REQ 0x1b8 96#define IO_DPD_REQ 0x1b8
93#define IO_DPD_REQ_CODE_IDLE (0 << 30) 97#define IO_DPD_REQ_CODE_IDLE (0U << 30)
94#define IO_DPD_REQ_CODE_OFF (1 << 30) 98#define IO_DPD_REQ_CODE_OFF (1U << 30)
95#define IO_DPD_REQ_CODE_ON (2 << 30) 99#define IO_DPD_REQ_CODE_ON (2U << 30)
96#define IO_DPD_REQ_CODE_MASK (3 << 30) 100#define IO_DPD_REQ_CODE_MASK (3U << 30)
97 101
98#define IO_DPD_STATUS 0x1bc 102#define IO_DPD_STATUS 0x1bc
99#define IO_DPD2_REQ 0x1c0 103#define IO_DPD2_REQ 0x1c0
@@ -101,16 +105,16 @@
101#define SEL_DPD_TIM 0x1c8 105#define SEL_DPD_TIM 0x1c8
102 106
103#define PMC_SCRATCH54 0x258 107#define PMC_SCRATCH54 0x258
104#define PMC_SCRATCH54_DATA_SHIFT 8 108#define PMC_SCRATCH54_DATA_SHIFT 8
105#define PMC_SCRATCH54_ADDR_SHIFT 0 109#define PMC_SCRATCH54_ADDR_SHIFT 0
106 110
107#define PMC_SCRATCH55 0x25c 111#define PMC_SCRATCH55 0x25c
108#define PMC_SCRATCH55_RESET_TEGRA (1 << 31) 112#define PMC_SCRATCH55_RESET_TEGRA BIT(31)
109#define PMC_SCRATCH55_CNTRL_ID_SHIFT 27 113#define PMC_SCRATCH55_CNTRL_ID_SHIFT 27
110#define PMC_SCRATCH55_PINMUX_SHIFT 24 114#define PMC_SCRATCH55_PINMUX_SHIFT 24
111#define PMC_SCRATCH55_16BITOP (1 << 15) 115#define PMC_SCRATCH55_16BITOP BIT(15)
112#define PMC_SCRATCH55_CHECKSUM_SHIFT 16 116#define PMC_SCRATCH55_CHECKSUM_SHIFT 16
113#define PMC_SCRATCH55_I2CSLV1_SHIFT 0 117#define PMC_SCRATCH55_I2CSLV1_SHIFT 0
114 118
115#define GPU_RG_CNTRL 0x2d4 119#define GPU_RG_CNTRL 0x2d4
116 120
@@ -124,6 +128,12 @@ struct tegra_powergate {
124 unsigned int num_resets; 128 unsigned int num_resets;
125}; 129};
126 130
131struct tegra_io_pad_soc {
132 enum tegra_io_pad id;
133 unsigned int dpd;
134 unsigned int voltage;
135};
136
127struct tegra_pmc_soc { 137struct tegra_pmc_soc {
128 unsigned int num_powergates; 138 unsigned int num_powergates;
129 const char *const *powergates; 139 const char *const *powergates;
@@ -132,6 +142,9 @@ struct tegra_pmc_soc {
132 142
133 bool has_tsense_reset; 143 bool has_tsense_reset;
134 bool has_gpu_clamps; 144 bool has_gpu_clamps;
145
146 const struct tegra_io_pad_soc *io_pads;
147 unsigned int num_io_pads;
135}; 148};
136 149
137/** 150/**
@@ -238,8 +251,6 @@ static int tegra_powergate_lookup(struct tegra_pmc *pmc, const char *name)
238 return i; 251 return i;
239 } 252 }
240 253
241 dev_err(pmc->dev, "powergate %s not found\n", name);
242
243 return -ENODEV; 254 return -ENODEV;
244} 255}
245 256
@@ -456,13 +467,12 @@ disable_clks:
456static int tegra_genpd_power_on(struct generic_pm_domain *domain) 467static int tegra_genpd_power_on(struct generic_pm_domain *domain)
457{ 468{
458 struct tegra_powergate *pg = to_powergate(domain); 469 struct tegra_powergate *pg = to_powergate(domain);
459 struct tegra_pmc *pmc = pg->pmc;
460 int err; 470 int err;
461 471
462 err = tegra_powergate_power_up(pg, true); 472 err = tegra_powergate_power_up(pg, true);
463 if (err) 473 if (err)
464 dev_err(pmc->dev, "failed to turn on PM domain %s: %d\n", 474 pr_err("failed to turn on PM domain %s: %d\n", pg->genpd.name,
465 pg->genpd.name, err); 475 err);
466 476
467 return err; 477 return err;
468} 478}
@@ -470,13 +480,12 @@ static int tegra_genpd_power_on(struct generic_pm_domain *domain)
470static int tegra_genpd_power_off(struct generic_pm_domain *domain) 480static int tegra_genpd_power_off(struct generic_pm_domain *domain)
471{ 481{
472 struct tegra_powergate *pg = to_powergate(domain); 482 struct tegra_powergate *pg = to_powergate(domain);
473 struct tegra_pmc *pmc = pg->pmc;
474 int err; 483 int err;
475 484
476 err = tegra_powergate_power_down(pg); 485 err = tegra_powergate_power_down(pg);
477 if (err) 486 if (err)
478 dev_err(pmc->dev, "failed to turn off PM domain %s: %d\n", 487 pr_err("failed to turn off PM domain %s: %d\n",
479 pg->genpd.name, err); 488 pg->genpd.name, err);
480 489
481 return err; 490 return err;
482} 491}
@@ -801,8 +810,7 @@ static void tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np)
801 810
802 id = tegra_powergate_lookup(pmc, np->name); 811 id = tegra_powergate_lookup(pmc, np->name);
803 if (id < 0) { 812 if (id < 0) {
804 dev_err(pmc->dev, "powergate lookup failed for %s: %d\n", 813 pr_err("powergate lookup failed for %s: %d\n", np->name, id);
805 np->name, id);
806 goto free_mem; 814 goto free_mem;
807 } 815 }
808 816
@@ -822,20 +830,22 @@ static void tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np)
822 830
823 err = tegra_powergate_of_get_clks(pg, np); 831 err = tegra_powergate_of_get_clks(pg, np);
824 if (err < 0) { 832 if (err < 0) {
825 dev_err(pmc->dev, "failed to get clocks for %s: %d\n", 833 pr_err("failed to get clocks for %s: %d\n", np->name, err);
826 np->name, err);
827 goto set_available; 834 goto set_available;
828 } 835 }
829 836
830 err = tegra_powergate_of_get_resets(pg, np, off); 837 err = tegra_powergate_of_get_resets(pg, np, off);
831 if (err < 0) { 838 if (err < 0) {
832 dev_err(pmc->dev, "failed to get resets for %s: %d\n", 839 pr_err("failed to get resets for %s: %d\n", np->name, err);
833 np->name, err);
834 goto remove_clks; 840 goto remove_clks;
835 } 841 }
836 842
837 if (!IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS)) 843 if (!IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS)) {
838 goto power_on_cleanup; 844 if (off)
845 WARN_ON(tegra_powergate_power_up(pg, true));
846
847 goto remove_resets;
848 }
839 849
840 /* 850 /*
841 * FIXME: If XHCI is enabled for Tegra, then power-up the XUSB 851 * FIXME: If XHCI is enabled for Tegra, then power-up the XUSB
@@ -846,25 +856,33 @@ static void tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np)
846 * to be unused. 856 * to be unused.
847 */ 857 */
848 if (IS_ENABLED(CONFIG_USB_XHCI_TEGRA) && 858 if (IS_ENABLED(CONFIG_USB_XHCI_TEGRA) &&
849 (id == TEGRA_POWERGATE_XUSBA || id == TEGRA_POWERGATE_XUSBC)) 859 (id == TEGRA_POWERGATE_XUSBA || id == TEGRA_POWERGATE_XUSBC)) {
850 goto power_on_cleanup; 860 if (off)
861 WARN_ON(tegra_powergate_power_up(pg, true));
862
863 goto remove_resets;
864 }
851 865
852 pm_genpd_init(&pg->genpd, NULL, off); 866 err = pm_genpd_init(&pg->genpd, NULL, off);
867 if (err < 0) {
868 pr_err("failed to initialise PM domain %s: %d\n", np->name,
869 err);
870 goto remove_resets;
871 }
853 872
854 err = of_genpd_add_provider_simple(np, &pg->genpd); 873 err = of_genpd_add_provider_simple(np, &pg->genpd);
855 if (err < 0) { 874 if (err < 0) {
856 dev_err(pmc->dev, "failed to add genpd provider for %s: %d\n", 875 pr_err("failed to add PM domain provider for %s: %d\n",
857 np->name, err); 876 np->name, err);
858 goto remove_resets; 877 goto remove_genpd;
859 } 878 }
860 879
861 dev_dbg(pmc->dev, "added power domain %s\n", pg->genpd.name); 880 pr_debug("added PM domain %s\n", pg->genpd.name);
862 881
863 return; 882 return;
864 883
865power_on_cleanup: 884remove_genpd:
866 if (off) 885 pm_genpd_remove(&pg->genpd);
867 WARN_ON(tegra_powergate_power_up(pg, true));
868 886
869remove_resets: 887remove_resets:
870 while (pg->num_resets--) 888 while (pg->num_resets--)
@@ -908,21 +926,36 @@ static void tegra_powergate_init(struct tegra_pmc *pmc,
908 of_node_put(np); 926 of_node_put(np);
909} 927}
910 928
911static int tegra_io_rail_prepare(unsigned int id, unsigned long *request, 929static const struct tegra_io_pad_soc *
912 unsigned long *status, unsigned int *bit) 930tegra_io_pad_find(struct tegra_pmc *pmc, enum tegra_io_pad id)
913{ 931{
932 unsigned int i;
933
934 for (i = 0; i < pmc->soc->num_io_pads; i++)
935 if (pmc->soc->io_pads[i].id == id)
936 return &pmc->soc->io_pads[i];
937
938 return NULL;
939}
940
941static int tegra_io_pad_prepare(enum tegra_io_pad id, unsigned long *request,
942 unsigned long *status, u32 *mask)
943{
944 const struct tegra_io_pad_soc *pad;
914 unsigned long rate, value; 945 unsigned long rate, value;
915 946
916 *bit = id % 32; 947 pad = tegra_io_pad_find(pmc, id);
948 if (!pad) {
949 pr_err("invalid I/O pad ID %u\n", id);
950 return -ENOENT;
951 }
917 952
918 /* 953 if (pad->dpd == UINT_MAX)
919 * There are two sets of 30 bits to select IO rails, but bits 30 and 954 return -ENOTSUPP;
920 * 31 are control bits rather than IO rail selection bits.
921 */
922 if (id > 63 || *bit == 30 || *bit == 31)
923 return -EINVAL;
924 955
925 if (id < 32) { 956 *mask = BIT(pad->dpd % 32);
957
958 if (pad->dpd < 32) {
926 *status = IO_DPD_STATUS; 959 *status = IO_DPD_STATUS;
927 *request = IO_DPD_REQ; 960 *request = IO_DPD_REQ;
928 } else { 961 } else {
@@ -931,6 +964,10 @@ static int tegra_io_rail_prepare(unsigned int id, unsigned long *request,
931 } 964 }
932 965
933 rate = clk_get_rate(pmc->clk); 966 rate = clk_get_rate(pmc->clk);
967 if (!rate) {
968 pr_err("failed to get clock rate\n");
969 return -ENODEV;
970 }
934 971
935 tegra_pmc_writel(DPD_SAMPLE_ENABLE, DPD_SAMPLE); 972 tegra_pmc_writel(DPD_SAMPLE_ENABLE, DPD_SAMPLE);
936 973
@@ -942,10 +979,10 @@ static int tegra_io_rail_prepare(unsigned int id, unsigned long *request,
942 return 0; 979 return 0;
943} 980}
944 981
945static int tegra_io_rail_poll(unsigned long offset, unsigned long mask, 982static int tegra_io_pad_poll(unsigned long offset, u32 mask,
946 unsigned long val, unsigned long timeout) 983 u32 val, unsigned long timeout)
947{ 984{
948 unsigned long value; 985 u32 value;
949 986
950 timeout = jiffies + msecs_to_jiffies(timeout); 987 timeout = jiffies + msecs_to_jiffies(timeout);
951 988
@@ -960,67 +997,164 @@ static int tegra_io_rail_poll(unsigned long offset, unsigned long mask,
960 return -ETIMEDOUT; 997 return -ETIMEDOUT;
961} 998}
962 999
963static void tegra_io_rail_unprepare(void) 1000static void tegra_io_pad_unprepare(void)
964{ 1001{
965 tegra_pmc_writel(DPD_SAMPLE_DISABLE, DPD_SAMPLE); 1002 tegra_pmc_writel(DPD_SAMPLE_DISABLE, DPD_SAMPLE);
966} 1003}
967 1004
968int tegra_io_rail_power_on(unsigned int id) 1005/**
1006 * tegra_io_pad_power_enable() - enable power to I/O pad
1007 * @id: Tegra I/O pad ID for which to enable power
1008 *
1009 * Returns: 0 on success or a negative error code on failure.
1010 */
1011int tegra_io_pad_power_enable(enum tegra_io_pad id)
969{ 1012{
970 unsigned long request, status; 1013 unsigned long request, status;
971 unsigned int bit; 1014 u32 mask;
972 int err; 1015 int err;
973 1016
974 mutex_lock(&pmc->powergates_lock); 1017 mutex_lock(&pmc->powergates_lock);
975 1018
976 err = tegra_io_rail_prepare(id, &request, &status, &bit); 1019 err = tegra_io_pad_prepare(id, &request, &status, &mask);
977 if (err) 1020 if (err < 0) {
978 goto error; 1021 pr_err("failed to prepare I/O pad: %d\n", err);
1022 goto unlock;
1023 }
979 1024
980 tegra_pmc_writel(IO_DPD_REQ_CODE_OFF | BIT(bit), request); 1025 tegra_pmc_writel(IO_DPD_REQ_CODE_OFF | mask, request);
981 1026
982 err = tegra_io_rail_poll(status, BIT(bit), 0, 250); 1027 err = tegra_io_pad_poll(status, mask, 0, 250);
983 if (err) { 1028 if (err < 0) {
984 pr_info("tegra_io_rail_poll() failed: %d\n", err); 1029 pr_err("failed to enable I/O pad: %d\n", err);
985 goto error; 1030 goto unlock;
986 } 1031 }
987 1032
988 tegra_io_rail_unprepare(); 1033 tegra_io_pad_unprepare();
989 1034
990error: 1035unlock:
991 mutex_unlock(&pmc->powergates_lock); 1036 mutex_unlock(&pmc->powergates_lock);
992
993 return err; 1037 return err;
994} 1038}
995EXPORT_SYMBOL(tegra_io_rail_power_on); 1039EXPORT_SYMBOL(tegra_io_pad_power_enable);
996 1040
997int tegra_io_rail_power_off(unsigned int id) 1041/**
1042 * tegra_io_pad_power_disable() - disable power to I/O pad
1043 * @id: Tegra I/O pad ID for which to disable power
1044 *
1045 * Returns: 0 on success or a negative error code on failure.
1046 */
1047int tegra_io_pad_power_disable(enum tegra_io_pad id)
998{ 1048{
999 unsigned long request, status; 1049 unsigned long request, status;
1000 unsigned int bit; 1050 u32 mask;
1001 int err; 1051 int err;
1002 1052
1003 mutex_lock(&pmc->powergates_lock); 1053 mutex_lock(&pmc->powergates_lock);
1004 1054
1005 err = tegra_io_rail_prepare(id, &request, &status, &bit); 1055 err = tegra_io_pad_prepare(id, &request, &status, &mask);
1006 if (err) { 1056 if (err < 0) {
1007 pr_info("tegra_io_rail_prepare() failed: %d\n", err); 1057 pr_err("failed to prepare I/O pad: %d\n", err);
1008 goto error; 1058 goto unlock;
1009 } 1059 }
1010 1060
1011 tegra_pmc_writel(IO_DPD_REQ_CODE_ON | BIT(bit), request); 1061 tegra_pmc_writel(IO_DPD_REQ_CODE_ON | mask, request);
1012 1062
1013 err = tegra_io_rail_poll(status, BIT(bit), BIT(bit), 250); 1063 err = tegra_io_pad_poll(status, mask, mask, 250);
1014 if (err) 1064 if (err < 0) {
1015 goto error; 1065 pr_err("failed to disable I/O pad: %d\n", err);
1066 goto unlock;
1067 }
1016 1068
1017 tegra_io_rail_unprepare(); 1069 tegra_io_pad_unprepare();
1018 1070
1019error: 1071unlock:
1020 mutex_unlock(&pmc->powergates_lock); 1072 mutex_unlock(&pmc->powergates_lock);
1021
1022 return err; 1073 return err;
1023} 1074}
1075EXPORT_SYMBOL(tegra_io_pad_power_disable);
1076
1077int tegra_io_pad_set_voltage(enum tegra_io_pad id,
1078 enum tegra_io_pad_voltage voltage)
1079{
1080 const struct tegra_io_pad_soc *pad;
1081 u32 value;
1082
1083 pad = tegra_io_pad_find(pmc, id);
1084 if (!pad)
1085 return -ENOENT;
1086
1087 if (pad->voltage == UINT_MAX)
1088 return -ENOTSUPP;
1089
1090 mutex_lock(&pmc->powergates_lock);
1091
1092 /* write-enable PMC_PWR_DET_VALUE[pad->voltage] */
1093 value = tegra_pmc_readl(PMC_PWR_DET);
1094 value |= BIT(pad->voltage);
1095 tegra_pmc_writel(value, PMC_PWR_DET);
1096
1097 /* update I/O voltage */
1098 value = tegra_pmc_readl(PMC_PWR_DET_VALUE);
1099
1100 if (voltage == TEGRA_IO_PAD_1800000UV)
1101 value &= ~BIT(pad->voltage);
1102 else
1103 value |= BIT(pad->voltage);
1104
1105 tegra_pmc_writel(value, PMC_PWR_DET_VALUE);
1106
1107 mutex_unlock(&pmc->powergates_lock);
1108
1109 usleep_range(100, 250);
1110
1111 return 0;
1112}
1113EXPORT_SYMBOL(tegra_io_pad_set_voltage);
1114
1115int tegra_io_pad_get_voltage(enum tegra_io_pad id)
1116{
1117 const struct tegra_io_pad_soc *pad;
1118 u32 value;
1119
1120 pad = tegra_io_pad_find(pmc, id);
1121 if (!pad)
1122 return -ENOENT;
1123
1124 if (pad->voltage == UINT_MAX)
1125 return -ENOTSUPP;
1126
1127 value = tegra_pmc_readl(PMC_PWR_DET_VALUE);
1128
1129 if ((value & BIT(pad->voltage)) == 0)
1130 return TEGRA_IO_PAD_1800000UV;
1131
1132 return TEGRA_IO_PAD_3300000UV;
1133}
1134EXPORT_SYMBOL(tegra_io_pad_get_voltage);
1135
1136/**
1137 * tegra_io_rail_power_on() - enable power to I/O rail
1138 * @id: Tegra I/O pad ID for which to enable power
1139 *
1140 * See also: tegra_io_pad_power_enable()
1141 */
1142int tegra_io_rail_power_on(unsigned int id)
1143{
1144 return tegra_io_pad_power_enable(id);
1145}
1146EXPORT_SYMBOL(tegra_io_rail_power_on);
1147
1148/**
1149 * tegra_io_rail_power_off() - disable power to I/O rail
1150 * @id: Tegra I/O pad ID for which to disable power
1151 *
1152 * See also: tegra_io_pad_power_disable()
1153 */
1154int tegra_io_rail_power_off(unsigned int id)
1155{
1156 return tegra_io_pad_power_disable(id);
1157}
1024EXPORT_SYMBOL(tegra_io_rail_power_off); 1158EXPORT_SYMBOL(tegra_io_rail_power_off);
1025 1159
1026#ifdef CONFIG_PM_SLEEP 1160#ifdef CONFIG_PM_SLEEP
@@ -1454,6 +1588,39 @@ static const u8 tegra124_cpu_powergates[] = {
1454 TEGRA_POWERGATE_CPU3, 1588 TEGRA_POWERGATE_CPU3,
1455}; 1589};
1456 1590
1591static const struct tegra_io_pad_soc tegra124_io_pads[] = {
1592 { .id = TEGRA_IO_PAD_AUDIO, .dpd = 17, .voltage = UINT_MAX },
1593 { .id = TEGRA_IO_PAD_BB, .dpd = 15, .voltage = UINT_MAX },
1594 { .id = TEGRA_IO_PAD_CAM, .dpd = 36, .voltage = UINT_MAX },
1595 { .id = TEGRA_IO_PAD_COMP, .dpd = 22, .voltage = UINT_MAX },
1596 { .id = TEGRA_IO_PAD_CSIA, .dpd = 0, .voltage = UINT_MAX },
1597 { .id = TEGRA_IO_PAD_CSIB, .dpd = 1, .voltage = UINT_MAX },
1598 { .id = TEGRA_IO_PAD_CSIE, .dpd = 44, .voltage = UINT_MAX },
1599 { .id = TEGRA_IO_PAD_DSI, .dpd = 2, .voltage = UINT_MAX },
1600 { .id = TEGRA_IO_PAD_DSIB, .dpd = 39, .voltage = UINT_MAX },
1601 { .id = TEGRA_IO_PAD_DSIC, .dpd = 40, .voltage = UINT_MAX },
1602 { .id = TEGRA_IO_PAD_DSID, .dpd = 41, .voltage = UINT_MAX },
1603 { .id = TEGRA_IO_PAD_HDMI, .dpd = 28, .voltage = UINT_MAX },
1604 { .id = TEGRA_IO_PAD_HSIC, .dpd = 19, .voltage = UINT_MAX },
1605 { .id = TEGRA_IO_PAD_HV, .dpd = 38, .voltage = UINT_MAX },
1606 { .id = TEGRA_IO_PAD_LVDS, .dpd = 57, .voltage = UINT_MAX },
1607 { .id = TEGRA_IO_PAD_MIPI_BIAS, .dpd = 3, .voltage = UINT_MAX },
1608 { .id = TEGRA_IO_PAD_NAND, .dpd = 13, .voltage = UINT_MAX },
1609 { .id = TEGRA_IO_PAD_PEX_BIAS, .dpd = 4, .voltage = UINT_MAX },
1610 { .id = TEGRA_IO_PAD_PEX_CLK1, .dpd = 5, .voltage = UINT_MAX },
1611 { .id = TEGRA_IO_PAD_PEX_CLK2, .dpd = 6, .voltage = UINT_MAX },
1612 { .id = TEGRA_IO_PAD_PEX_CNTRL, .dpd = 32, .voltage = UINT_MAX },
1613 { .id = TEGRA_IO_PAD_SDMMC1, .dpd = 33, .voltage = UINT_MAX },
1614 { .id = TEGRA_IO_PAD_SDMMC3, .dpd = 34, .voltage = UINT_MAX },
1615 { .id = TEGRA_IO_PAD_SDMMC4, .dpd = 35, .voltage = UINT_MAX },
1616 { .id = TEGRA_IO_PAD_SYS_DDC, .dpd = 58, .voltage = UINT_MAX },
1617 { .id = TEGRA_IO_PAD_UART, .dpd = 14, .voltage = UINT_MAX },
1618 { .id = TEGRA_IO_PAD_USB0, .dpd = 9, .voltage = UINT_MAX },
1619 { .id = TEGRA_IO_PAD_USB1, .dpd = 10, .voltage = UINT_MAX },
1620 { .id = TEGRA_IO_PAD_USB2, .dpd = 11, .voltage = UINT_MAX },
1621 { .id = TEGRA_IO_PAD_USB_BIAS, .dpd = 12, .voltage = UINT_MAX },
1622};
1623
1457static const struct tegra_pmc_soc tegra124_pmc_soc = { 1624static const struct tegra_pmc_soc tegra124_pmc_soc = {
1458 .num_powergates = ARRAY_SIZE(tegra124_powergates), 1625 .num_powergates = ARRAY_SIZE(tegra124_powergates),
1459 .powergates = tegra124_powergates, 1626 .powergates = tegra124_powergates,
@@ -1461,6 +1628,8 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = {
1461 .cpu_powergates = tegra124_cpu_powergates, 1628 .cpu_powergates = tegra124_cpu_powergates,
1462 .has_tsense_reset = true, 1629 .has_tsense_reset = true,
1463 .has_gpu_clamps = true, 1630 .has_gpu_clamps = true,
1631 .num_io_pads = ARRAY_SIZE(tegra124_io_pads),
1632 .io_pads = tegra124_io_pads,
1464}; 1633};
1465 1634
1466static const char * const tegra210_powergates[] = { 1635static const char * const tegra210_powergates[] = {
@@ -1497,6 +1666,47 @@ static const u8 tegra210_cpu_powergates[] = {
1497 TEGRA_POWERGATE_CPU3, 1666 TEGRA_POWERGATE_CPU3,
1498}; 1667};
1499 1668
1669static const struct tegra_io_pad_soc tegra210_io_pads[] = {
1670 { .id = TEGRA_IO_PAD_AUDIO, .dpd = 17, .voltage = 5 },
1671 { .id = TEGRA_IO_PAD_AUDIO_HV, .dpd = 61, .voltage = 18 },
1672 { .id = TEGRA_IO_PAD_CAM, .dpd = 36, .voltage = 10 },
1673 { .id = TEGRA_IO_PAD_CSIA, .dpd = 0, .voltage = UINT_MAX },
1674 { .id = TEGRA_IO_PAD_CSIB, .dpd = 1, .voltage = UINT_MAX },
1675 { .id = TEGRA_IO_PAD_CSIC, .dpd = 42, .voltage = UINT_MAX },
1676 { .id = TEGRA_IO_PAD_CSID, .dpd = 43, .voltage = UINT_MAX },
1677 { .id = TEGRA_IO_PAD_CSIE, .dpd = 44, .voltage = UINT_MAX },
1678 { .id = TEGRA_IO_PAD_CSIF, .dpd = 45, .voltage = UINT_MAX },
1679 { .id = TEGRA_IO_PAD_DBG, .dpd = 25, .voltage = 19 },
1680 { .id = TEGRA_IO_PAD_DEBUG_NONAO, .dpd = 26, .voltage = UINT_MAX },
1681 { .id = TEGRA_IO_PAD_DMIC, .dpd = 50, .voltage = 20 },
1682 { .id = TEGRA_IO_PAD_DP, .dpd = 51, .voltage = UINT_MAX },
1683 { .id = TEGRA_IO_PAD_DSI, .dpd = 2, .voltage = UINT_MAX },
1684 { .id = TEGRA_IO_PAD_DSIB, .dpd = 39, .voltage = UINT_MAX },
1685 { .id = TEGRA_IO_PAD_DSIC, .dpd = 40, .voltage = UINT_MAX },
1686 { .id = TEGRA_IO_PAD_DSID, .dpd = 41, .voltage = UINT_MAX },
1687 { .id = TEGRA_IO_PAD_EMMC, .dpd = 35, .voltage = UINT_MAX },
1688 { .id = TEGRA_IO_PAD_EMMC2, .dpd = 37, .voltage = UINT_MAX },
1689 { .id = TEGRA_IO_PAD_GPIO, .dpd = 27, .voltage = 21 },
1690 { .id = TEGRA_IO_PAD_HDMI, .dpd = 28, .voltage = UINT_MAX },
1691 { .id = TEGRA_IO_PAD_HSIC, .dpd = 19, .voltage = UINT_MAX },
1692 { .id = TEGRA_IO_PAD_LVDS, .dpd = 57, .voltage = UINT_MAX },
1693 { .id = TEGRA_IO_PAD_MIPI_BIAS, .dpd = 3, .voltage = UINT_MAX },
1694 { .id = TEGRA_IO_PAD_PEX_BIAS, .dpd = 4, .voltage = UINT_MAX },
1695 { .id = TEGRA_IO_PAD_PEX_CLK1, .dpd = 5, .voltage = UINT_MAX },
1696 { .id = TEGRA_IO_PAD_PEX_CLK2, .dpd = 6, .voltage = UINT_MAX },
1697 { .id = TEGRA_IO_PAD_PEX_CNTRL, .dpd = UINT_MAX, .voltage = 11 },
1698 { .id = TEGRA_IO_PAD_SDMMC1, .dpd = 33, .voltage = 12 },
1699 { .id = TEGRA_IO_PAD_SDMMC3, .dpd = 34, .voltage = 13 },
1700 { .id = TEGRA_IO_PAD_SPI, .dpd = 46, .voltage = 22 },
1701 { .id = TEGRA_IO_PAD_SPI_HV, .dpd = 47, .voltage = 23 },
1702 { .id = TEGRA_IO_PAD_UART, .dpd = 14, .voltage = 2 },
1703 { .id = TEGRA_IO_PAD_USB0, .dpd = 9, .voltage = UINT_MAX },
1704 { .id = TEGRA_IO_PAD_USB1, .dpd = 10, .voltage = UINT_MAX },
1705 { .id = TEGRA_IO_PAD_USB2, .dpd = 11, .voltage = UINT_MAX },
1706 { .id = TEGRA_IO_PAD_USB3, .dpd = 18, .voltage = UINT_MAX },
1707 { .id = TEGRA_IO_PAD_USB_BIAS, .dpd = 12, .voltage = UINT_MAX },
1708};
1709
1500static const struct tegra_pmc_soc tegra210_pmc_soc = { 1710static const struct tegra_pmc_soc tegra210_pmc_soc = {
1501 .num_powergates = ARRAY_SIZE(tegra210_powergates), 1711 .num_powergates = ARRAY_SIZE(tegra210_powergates),
1502 .powergates = tegra210_powergates, 1712 .powergates = tegra210_powergates,
@@ -1504,6 +1714,8 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = {
1504 .cpu_powergates = tegra210_cpu_powergates, 1714 .cpu_powergates = tegra210_cpu_powergates,
1505 .has_tsense_reset = true, 1715 .has_tsense_reset = true,
1506 .has_gpu_clamps = true, 1716 .has_gpu_clamps = true,
1717 .num_io_pads = ARRAY_SIZE(tegra210_io_pads),
1718 .io_pads = tegra210_io_pads,
1507}; 1719};
1508 1720
1509static const struct of_device_id tegra_pmc_match[] = { 1721static const struct of_device_id tegra_pmc_match[] = {
diff --git a/include/soc/tegra/pmc.h b/include/soc/tegra/pmc.h
index e9e53473a63e..2f271d1b9cea 100644
--- a/include/soc/tegra/pmc.h
+++ b/include/soc/tegra/pmc.h
@@ -76,37 +76,73 @@ int tegra_pmc_cpu_remove_clamping(unsigned int cpuid);
76 76
77#define TEGRA_POWERGATE_3D0 TEGRA_POWERGATE_3D 77#define TEGRA_POWERGATE_3D0 TEGRA_POWERGATE_3D
78 78
79#define TEGRA_IO_RAIL_CSIA 0 79/**
80#define TEGRA_IO_RAIL_CSIB 1 80 * enum tegra_io_pad - I/O pad group identifier
81#define TEGRA_IO_RAIL_DSI 2 81 *
82#define TEGRA_IO_RAIL_MIPI_BIAS 3 82 * I/O pins on Tegra SoCs are grouped into so-called I/O pads. Each such pad
83#define TEGRA_IO_RAIL_PEX_BIAS 4 83 * can be used to control the common voltage signal level and power state of
84#define TEGRA_IO_RAIL_PEX_CLK1 5 84 * the pins of the given pad.
85#define TEGRA_IO_RAIL_PEX_CLK2 6 85 */
86#define TEGRA_IO_RAIL_USB0 9 86enum tegra_io_pad {
87#define TEGRA_IO_RAIL_USB1 10 87 TEGRA_IO_PAD_AUDIO,
88#define TEGRA_IO_RAIL_USB2 11 88 TEGRA_IO_PAD_AUDIO_HV,
89#define TEGRA_IO_RAIL_USB_BIAS 12 89 TEGRA_IO_PAD_BB,
90#define TEGRA_IO_RAIL_NAND 13 90 TEGRA_IO_PAD_CAM,
91#define TEGRA_IO_RAIL_UART 14 91 TEGRA_IO_PAD_COMP,
92#define TEGRA_IO_RAIL_BB 15 92 TEGRA_IO_PAD_CSIA,
93#define TEGRA_IO_RAIL_AUDIO 17 93 TEGRA_IO_PAD_CSIB,
94#define TEGRA_IO_RAIL_HSIC 19 94 TEGRA_IO_PAD_CSIC,
95#define TEGRA_IO_RAIL_COMP 22 95 TEGRA_IO_PAD_CSID,
96#define TEGRA_IO_RAIL_HDMI 28 96 TEGRA_IO_PAD_CSIE,
97#define TEGRA_IO_RAIL_PEX_CNTRL 32 97 TEGRA_IO_PAD_CSIF,
98#define TEGRA_IO_RAIL_SDMMC1 33 98 TEGRA_IO_PAD_DBG,
99#define TEGRA_IO_RAIL_SDMMC3 34 99 TEGRA_IO_PAD_DEBUG_NONAO,
100#define TEGRA_IO_RAIL_SDMMC4 35 100 TEGRA_IO_PAD_DMIC,
101#define TEGRA_IO_RAIL_CAM 36 101 TEGRA_IO_PAD_DP,
102#define TEGRA_IO_RAIL_RES 37 102 TEGRA_IO_PAD_DSI,
103#define TEGRA_IO_RAIL_HV 38 103 TEGRA_IO_PAD_DSIB,
104#define TEGRA_IO_RAIL_DSIB 39 104 TEGRA_IO_PAD_DSIC,
105#define TEGRA_IO_RAIL_DSIC 40 105 TEGRA_IO_PAD_DSID,
106#define TEGRA_IO_RAIL_DSID 41 106 TEGRA_IO_PAD_EMMC,
107#define TEGRA_IO_RAIL_CSIE 44 107 TEGRA_IO_PAD_EMMC2,
108#define TEGRA_IO_RAIL_LVDS 57 108 TEGRA_IO_PAD_GPIO,
109#define TEGRA_IO_RAIL_SYS_DDC 58 109 TEGRA_IO_PAD_HDMI,
110 TEGRA_IO_PAD_HSIC,
111 TEGRA_IO_PAD_HV,
112 TEGRA_IO_PAD_LVDS,
113 TEGRA_IO_PAD_MIPI_BIAS,
114 TEGRA_IO_PAD_NAND,
115 TEGRA_IO_PAD_PEX_BIAS,
116 TEGRA_IO_PAD_PEX_CLK1,
117 TEGRA_IO_PAD_PEX_CLK2,
118 TEGRA_IO_PAD_PEX_CNTRL,
119 TEGRA_IO_PAD_SDMMC1,
120 TEGRA_IO_PAD_SDMMC3,
121 TEGRA_IO_PAD_SDMMC4,
122 TEGRA_IO_PAD_SPI,
123 TEGRA_IO_PAD_SPI_HV,
124 TEGRA_IO_PAD_SYS_DDC,
125 TEGRA_IO_PAD_UART,
126 TEGRA_IO_PAD_USB0,
127 TEGRA_IO_PAD_USB1,
128 TEGRA_IO_PAD_USB2,
129 TEGRA_IO_PAD_USB3,
130 TEGRA_IO_PAD_USB_BIAS,
131};
132
133/* deprecated, use TEGRA_IO_PAD_{HDMI,LVDS} instead */
134#define TEGRA_IO_RAIL_HDMI TEGRA_IO_PAD_HDMI
135#define TEGRA_IO_RAIL_LVDS TEGRA_IO_PAD_LVDS
136
137/**
138 * enum tegra_io_pad_voltage - voltage level of the I/O pad's source rail
139 * @TEGRA_IO_PAD_1800000UV: 1.8 V
140 * @TEGRA_IO_PAD_3300000UV: 3.3 V
141 */
142enum tegra_io_pad_voltage {
143 TEGRA_IO_PAD_1800000UV,
144 TEGRA_IO_PAD_3300000UV,
145};
110 146
111#ifdef CONFIG_ARCH_TEGRA 147#ifdef CONFIG_ARCH_TEGRA
112int tegra_powergate_is_powered(unsigned int id); 148int tegra_powergate_is_powered(unsigned int id);
@@ -118,6 +154,13 @@ int tegra_powergate_remove_clamping(unsigned int id);
118int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk, 154int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk,
119 struct reset_control *rst); 155 struct reset_control *rst);
120 156
157int tegra_io_pad_power_enable(enum tegra_io_pad id);
158int tegra_io_pad_power_disable(enum tegra_io_pad id);
159int tegra_io_pad_set_voltage(enum tegra_io_pad id,
160 enum tegra_io_pad_voltage voltage);
161int tegra_io_pad_get_voltage(enum tegra_io_pad id);
162
163/* deprecated, use tegra_io_pad_power_{enable,disable}() instead */
121int tegra_io_rail_power_on(unsigned int id); 164int tegra_io_rail_power_on(unsigned int id);
122int tegra_io_rail_power_off(unsigned int id); 165int tegra_io_rail_power_off(unsigned int id);
123#else 166#else
@@ -148,6 +191,27 @@ static inline int tegra_powergate_sequence_power_up(unsigned int id,
148 return -ENOSYS; 191 return -ENOSYS;
149} 192}
150 193
194static inline int tegra_io_pad_power_enable(enum tegra_io_pad id)
195{
196 return -ENOSYS;
197}
198
199static inline int tegra_io_pad_power_disable(enum tegra_io_pad id)
200{
201 return -ENOSYS;
202}
203
204static inline int tegra_io_pad_set_voltage(enum tegra_io_pad id,
205 enum tegra_io_pad_voltage voltage)
206{
207 return -ENOSYS;
208}
209
210static inline int tegra_io_pad_get_voltage(enum tegra_io_pad id)
211{
212 return -ENOSYS;
213}
214
151static inline int tegra_io_rail_power_on(unsigned int id) 215static inline int tegra_io_rail_power_on(unsigned int id)
152{ 216{
153 return -ENOSYS; 217 return -ENOSYS;