diff options
author | Jason Cooper <jason@lakedaemon.net> | 2014-03-01 02:03:36 -0500 |
---|---|---|
committer | Jason Cooper <jason@lakedaemon.net> | 2014-03-01 02:03:36 -0500 |
commit | 08d4f0c8b131ee9d89b7c778ff259b8d4e701463 (patch) | |
tree | cde9f2c4c42cb6e8b1030da0b6a06bc020a3cd22 | |
parent | 55387764c4e8c2b0657acbdedd8df465eb856f82 (diff) | |
parent | 6da67cab4b7dd1bf49392886f0809292470b70e7 (diff) |
Merge remote-tracking branch 'shesselba/for-mvebu/pinctrl-dove' into mvebu/pinctrl
8 files changed, 202 insertions, 113 deletions
diff --git a/Documentation/devicetree/bindings/arm/marvell,dove.txt b/Documentation/devicetree/bindings/arm/marvell,dove.txt new file mode 100644 index 000000000000..aaaf64c56e44 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/marvell,dove.txt | |||
@@ -0,0 +1,22 @@ | |||
1 | Marvell Dove Platforms Device Tree Bindings | ||
2 | ----------------------------------------------- | ||
3 | |||
4 | Boards with a Marvell Dove SoC shall have the following properties: | ||
5 | |||
6 | Required root node property: | ||
7 | - compatible: must contain "marvell,dove"; | ||
8 | |||
9 | * Global Configuration registers | ||
10 | |||
11 | Global Configuration registers of Dove SoC are shared by a syscon node. | ||
12 | |||
13 | Required properties: | ||
14 | - compatible: must contain "marvell,dove-global-config" and "syscon". | ||
15 | - reg: base address and size of the Global Configuration registers. | ||
16 | |||
17 | Example: | ||
18 | |||
19 | gconf: global-config@e802c { | ||
20 | compatible = "marvell,dove-global-config", "syscon"; | ||
21 | reg = <0xe802c 0x14>; | ||
22 | }; | ||
diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt index 01ef408e205f..adda2a8d1d52 100644 --- a/Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt | |||
@@ -5,6 +5,7 @@ part and usage. | |||
5 | 5 | ||
6 | Required properties: | 6 | Required properties: |
7 | - compatible: "marvell,88f6710-pinctrl" | 7 | - compatible: "marvell,88f6710-pinctrl" |
8 | - reg: register specifier of MPP registers | ||
8 | 9 | ||
9 | Available mpp pins/groups and functions: | 10 | Available mpp pins/groups and functions: |
10 | Note: brackets (x) are not part of the mpp name for marvell,function and given | 11 | Note: brackets (x) are not part of the mpp name for marvell,function and given |
diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,armada-xp-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,armada-xp-pinctrl.txt index bfa0a2e5e0cb..373dbccd7ab0 100644 --- a/Documentation/devicetree/bindings/pinctrl/marvell,armada-xp-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/marvell,armada-xp-pinctrl.txt | |||
@@ -6,6 +6,7 @@ part and usage. | |||
6 | Required properties: | 6 | Required properties: |
7 | - compatible: "marvell,mv78230-pinctrl", "marvell,mv78260-pinctrl", | 7 | - compatible: "marvell,mv78230-pinctrl", "marvell,mv78260-pinctrl", |
8 | "marvell,mv78460-pinctrl" | 8 | "marvell,mv78460-pinctrl" |
9 | - reg: register specifier of MPP registers | ||
9 | 10 | ||
10 | This driver supports all Armada XP variants, i.e. mv78230, mv78260, and mv78460. | 11 | This driver supports all Armada XP variants, i.e. mv78230, mv78260, and mv78460. |
11 | 12 | ||
diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,dove-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,dove-pinctrl.txt index 50ec3512a292..cf52477cc7ee 100644 --- a/Documentation/devicetree/bindings/pinctrl/marvell,dove-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/marvell,dove-pinctrl.txt | |||
@@ -6,6 +6,7 @@ part and usage. | |||
6 | Required properties: | 6 | Required properties: |
7 | - compatible: "marvell,dove-pinctrl" | 7 | - compatible: "marvell,dove-pinctrl" |
8 | - clocks: (optional) phandle of pdma clock | 8 | - clocks: (optional) phandle of pdma clock |
9 | - reg: register specifiers of MPP, MPP4, and PMU MPP registers | ||
9 | 10 | ||
10 | Available mpp pins/groups and functions: | 11 | Available mpp pins/groups and functions: |
11 | Note: brackets (x) are not part of the mpp name for marvell,function and given | 12 | Note: brackets (x) are not part of the mpp name for marvell,function and given |
diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,kirkwood-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,kirkwood-pinctrl.txt index 95daf6335c37..730444a9a4de 100644 --- a/Documentation/devicetree/bindings/pinctrl/marvell,kirkwood-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/marvell,kirkwood-pinctrl.txt | |||
@@ -8,6 +8,7 @@ Required properties: | |||
8 | "marvell,88f6190-pinctrl", "marvell,88f6192-pinctrl", | 8 | "marvell,88f6190-pinctrl", "marvell,88f6192-pinctrl", |
9 | "marvell,88f6281-pinctrl", "marvell,88f6282-pinctrl" | 9 | "marvell,88f6281-pinctrl", "marvell,88f6282-pinctrl" |
10 | "marvell,98dx4122-pinctrl" | 10 | "marvell,98dx4122-pinctrl" |
11 | - reg: register specifier of MPP registers | ||
11 | 12 | ||
12 | This driver supports all kirkwood variants, i.e. 88f6180, 88f619x, and 88f628x. | 13 | This driver supports all kirkwood variants, i.e. 88f6180, 88f619x, and 88f628x. |
13 | It also support the 88f6281-based variant in the 98dx412x Bobcat SoCs. | 14 | It also support the 88f6281-based variant in the 98dx412x Bobcat SoCs. |
diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,mvebu-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,mvebu-pinctrl.txt index 0a26c3aa4e6d..0c09f4eb2af0 100644 --- a/Documentation/devicetree/bindings/pinctrl/marvell,mvebu-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/marvell,mvebu-pinctrl.txt | |||
@@ -37,7 +37,7 @@ uart1: serial@12100 { | |||
37 | 37 | ||
38 | pinctrl: pinctrl@d0200 { | 38 | pinctrl: pinctrl@d0200 { |
39 | compatible = "marvell,dove-pinctrl"; | 39 | compatible = "marvell,dove-pinctrl"; |
40 | reg = <0xd0200 0x20>; | 40 | reg = <0xd0200 0x14>, <0xd0440 0x04>, <0xd802c 0x08>; |
41 | 41 | ||
42 | pmx_uart1_sw: pmx-uart1-sw { | 42 | pmx_uart1_sw: pmx-uart1-sw { |
43 | marvell,pins = "mpp_uart1"; | 43 | marvell,pins = "mpp_uart1"; |
diff --git a/drivers/pinctrl/mvebu/Kconfig b/drivers/pinctrl/mvebu/Kconfig index 366fa541ee91..8dc4948c1202 100644 --- a/drivers/pinctrl/mvebu/Kconfig +++ b/drivers/pinctrl/mvebu/Kconfig | |||
@@ -8,6 +8,7 @@ config PINCTRL_MVEBU | |||
8 | config PINCTRL_DOVE | 8 | config PINCTRL_DOVE |
9 | bool | 9 | bool |
10 | select PINCTRL_MVEBU | 10 | select PINCTRL_MVEBU |
11 | select MFD_SYSCON | ||
11 | 12 | ||
12 | config PINCTRL_KIRKWOOD | 13 | config PINCTRL_KIRKWOOD |
13 | bool | 14 | bool |
diff --git a/drivers/pinctrl/mvebu/pinctrl-dove.c b/drivers/pinctrl/mvebu/pinctrl-dove.c index da9ca26360fd..9e7ff651c018 100644 --- a/drivers/pinctrl/mvebu/pinctrl-dove.c +++ b/drivers/pinctrl/mvebu/pinctrl-dove.c | |||
@@ -18,40 +18,53 @@ | |||
18 | #include <linux/clk.h> | 18 | #include <linux/clk.h> |
19 | #include <linux/of.h> | 19 | #include <linux/of.h> |
20 | #include <linux/of_device.h> | 20 | #include <linux/of_device.h> |
21 | #include <linux/mfd/syscon.h> | ||
21 | #include <linux/pinctrl/pinctrl.h> | 22 | #include <linux/pinctrl/pinctrl.h> |
23 | #include <linux/regmap.h> | ||
22 | 24 | ||
23 | #include "pinctrl-mvebu.h" | 25 | #include "pinctrl-mvebu.h" |
24 | 26 | ||
25 | #define DOVE_SB_REGS_VIRT_BASE IOMEM(0xfde00000) | 27 | /* Internal registers can be configured at any 1 MiB aligned address */ |
26 | #define DOVE_MPP_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0xd0200) | 28 | #define INT_REGS_MASK ~(SZ_1M - 1) |
27 | #define DOVE_PMU_MPP_GENERAL_CTRL (DOVE_MPP_VIRT_BASE + 0x10) | 29 | #define MPP4_REGS_OFFS 0xd0440 |
28 | #define DOVE_AU0_AC97_SEL BIT(16) | 30 | #define PMU_REGS_OFFS 0xd802c |
29 | #define DOVE_PMU_SIGNAL_SELECT_0 (DOVE_SB_REGS_VIRT_BASE + 0xd802C) | 31 | #define GC_REGS_OFFS 0xe802c |
30 | #define DOVE_PMU_SIGNAL_SELECT_1 (DOVE_SB_REGS_VIRT_BASE + 0xd8030) | 32 | |
31 | #define DOVE_GLOBAL_CONFIG_1 (DOVE_SB_REGS_VIRT_BASE + 0xe802C) | 33 | /* MPP Base registers */ |
32 | #define DOVE_GLOBAL_CONFIG_1 (DOVE_SB_REGS_VIRT_BASE + 0xe802C) | 34 | #define PMU_MPP_GENERAL_CTRL 0x10 |
33 | #define DOVE_TWSI_ENABLE_OPTION1 BIT(7) | 35 | #define AU0_AC97_SEL BIT(16) |
34 | #define DOVE_GLOBAL_CONFIG_2 (DOVE_SB_REGS_VIRT_BASE + 0xe8030) | 36 | |
35 | #define DOVE_TWSI_ENABLE_OPTION2 BIT(20) | 37 | /* MPP Control 4 register */ |
36 | #define DOVE_TWSI_ENABLE_OPTION3 BIT(21) | 38 | #define SPI_GPIO_SEL BIT(5) |
37 | #define DOVE_TWSI_OPTION3_GPIO BIT(22) | 39 | #define UART1_GPIO_SEL BIT(4) |
38 | #define DOVE_SSP_CTRL_STATUS_1 (DOVE_SB_REGS_VIRT_BASE + 0xe8034) | 40 | #define AU1_GPIO_SEL BIT(3) |
39 | #define DOVE_SSP_ON_AU1 BIT(0) | 41 | #define CAM_GPIO_SEL BIT(2) |
40 | #define DOVE_MPP_GENERAL_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0xe803c) | 42 | #define SD1_GPIO_SEL BIT(1) |
41 | #define DOVE_AU1_SPDIFO_GPIO_EN BIT(1) | 43 | #define SD0_GPIO_SEL BIT(0) |
42 | #define DOVE_NAND_GPIO_EN BIT(0) | 44 | |
43 | #define DOVE_GPIO_LO_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0xd0400) | 45 | /* PMU Signal Select registers */ |
44 | #define DOVE_MPP_CTRL4_VIRT_BASE (DOVE_GPIO_LO_VIRT_BASE + 0x40) | 46 | #define PMU_SIGNAL_SELECT_0 0x00 |
45 | #define DOVE_SPI_GPIO_SEL BIT(5) | 47 | #define PMU_SIGNAL_SELECT_1 0x04 |
46 | #define DOVE_UART1_GPIO_SEL BIT(4) | 48 | |
47 | #define DOVE_AU1_GPIO_SEL BIT(3) | 49 | /* Global Config regmap registers */ |
48 | #define DOVE_CAM_GPIO_SEL BIT(2) | 50 | #define GLOBAL_CONFIG_1 0x00 |
49 | #define DOVE_SD1_GPIO_SEL BIT(1) | 51 | #define TWSI_ENABLE_OPTION1 BIT(7) |
50 | #define DOVE_SD0_GPIO_SEL BIT(0) | 52 | #define GLOBAL_CONFIG_2 0x04 |
53 | #define TWSI_ENABLE_OPTION2 BIT(20) | ||
54 | #define TWSI_ENABLE_OPTION3 BIT(21) | ||
55 | #define TWSI_OPTION3_GPIO BIT(22) | ||
56 | #define SSP_CTRL_STATUS_1 0x08 | ||
57 | #define SSP_ON_AU1 BIT(0) | ||
58 | #define MPP_GENERAL_CONFIG 0x10 | ||
59 | #define AU1_SPDIFO_GPIO_EN BIT(1) | ||
60 | #define NAND_GPIO_EN BIT(0) | ||
51 | 61 | ||
52 | #define CONFIG_PMU BIT(4) | 62 | #define CONFIG_PMU BIT(4) |
53 | 63 | ||
54 | static void __iomem *mpp_base; | 64 | static void __iomem *mpp_base; |
65 | static void __iomem *mpp4_base; | ||
66 | static void __iomem *pmu_base; | ||
67 | static struct regmap *gconfmap; | ||
55 | 68 | ||
56 | static int dove_mpp_ctrl_get(unsigned pid, unsigned long *config) | 69 | static int dove_mpp_ctrl_get(unsigned pid, unsigned long *config) |
57 | { | 70 | { |
@@ -67,13 +80,13 @@ static int dove_pmu_mpp_ctrl_get(unsigned pid, unsigned long *config) | |||
67 | { | 80 | { |
68 | unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS; | 81 | unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS; |
69 | unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS; | 82 | unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS; |
70 | unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL); | 83 | unsigned long pmu = readl(mpp_base + PMU_MPP_GENERAL_CTRL); |
71 | unsigned long func; | 84 | unsigned long func; |
72 | 85 | ||
73 | if ((pmu & BIT(pid)) == 0) | 86 | if ((pmu & BIT(pid)) == 0) |
74 | return default_mpp_ctrl_get(mpp_base, pid, config); | 87 | return default_mpp_ctrl_get(mpp_base, pid, config); |
75 | 88 | ||
76 | func = readl(DOVE_PMU_SIGNAL_SELECT_0 + off); | 89 | func = readl(pmu_base + PMU_SIGNAL_SELECT_0 + off); |
77 | *config = (func >> shift) & MVEBU_MPP_MASK; | 90 | *config = (func >> shift) & MVEBU_MPP_MASK; |
78 | *config |= CONFIG_PMU; | 91 | *config |= CONFIG_PMU; |
79 | 92 | ||
@@ -84,43 +97,43 @@ static int dove_pmu_mpp_ctrl_set(unsigned pid, unsigned long config) | |||
84 | { | 97 | { |
85 | unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS; | 98 | unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS; |
86 | unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS; | 99 | unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS; |
87 | unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL); | 100 | unsigned long pmu = readl(mpp_base + PMU_MPP_GENERAL_CTRL); |
88 | unsigned long func; | 101 | unsigned long func; |
89 | 102 | ||
90 | if ((config & CONFIG_PMU) == 0) { | 103 | if ((config & CONFIG_PMU) == 0) { |
91 | writel(pmu & ~BIT(pid), DOVE_PMU_MPP_GENERAL_CTRL); | 104 | writel(pmu & ~BIT(pid), mpp_base + PMU_MPP_GENERAL_CTRL); |
92 | return default_mpp_ctrl_set(mpp_base, pid, config); | 105 | return default_mpp_ctrl_set(mpp_base, pid, config); |
93 | } | 106 | } |
94 | 107 | ||
95 | writel(pmu | BIT(pid), DOVE_PMU_MPP_GENERAL_CTRL); | 108 | writel(pmu | BIT(pid), mpp_base + PMU_MPP_GENERAL_CTRL); |
96 | func = readl(DOVE_PMU_SIGNAL_SELECT_0 + off); | 109 | func = readl(pmu_base + PMU_SIGNAL_SELECT_0 + off); |
97 | func &= ~(MVEBU_MPP_MASK << shift); | 110 | func &= ~(MVEBU_MPP_MASK << shift); |
98 | func |= (config & MVEBU_MPP_MASK) << shift; | 111 | func |= (config & MVEBU_MPP_MASK) << shift; |
99 | writel(func, DOVE_PMU_SIGNAL_SELECT_0 + off); | 112 | writel(func, pmu_base + PMU_SIGNAL_SELECT_0 + off); |
100 | 113 | ||
101 | return 0; | 114 | return 0; |
102 | } | 115 | } |
103 | 116 | ||
104 | static int dove_mpp4_ctrl_get(unsigned pid, unsigned long *config) | 117 | static int dove_mpp4_ctrl_get(unsigned pid, unsigned long *config) |
105 | { | 118 | { |
106 | unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE); | 119 | unsigned long mpp4 = readl(mpp4_base); |
107 | unsigned long mask; | 120 | unsigned long mask; |
108 | 121 | ||
109 | switch (pid) { | 122 | switch (pid) { |
110 | case 24: /* mpp_camera */ | 123 | case 24: /* mpp_camera */ |
111 | mask = DOVE_CAM_GPIO_SEL; | 124 | mask = CAM_GPIO_SEL; |
112 | break; | 125 | break; |
113 | case 40: /* mpp_sdio0 */ | 126 | case 40: /* mpp_sdio0 */ |
114 | mask = DOVE_SD0_GPIO_SEL; | 127 | mask = SD0_GPIO_SEL; |
115 | break; | 128 | break; |
116 | case 46: /* mpp_sdio1 */ | 129 | case 46: /* mpp_sdio1 */ |
117 | mask = DOVE_SD1_GPIO_SEL; | 130 | mask = SD1_GPIO_SEL; |
118 | break; | 131 | break; |
119 | case 58: /* mpp_spi0 */ | 132 | case 58: /* mpp_spi0 */ |
120 | mask = DOVE_SPI_GPIO_SEL; | 133 | mask = SPI_GPIO_SEL; |
121 | break; | 134 | break; |
122 | case 62: /* mpp_uart1 */ | 135 | case 62: /* mpp_uart1 */ |
123 | mask = DOVE_UART1_GPIO_SEL; | 136 | mask = UART1_GPIO_SEL; |
124 | break; | 137 | break; |
125 | default: | 138 | default: |
126 | return -EINVAL; | 139 | return -EINVAL; |
@@ -133,24 +146,24 @@ static int dove_mpp4_ctrl_get(unsigned pid, unsigned long *config) | |||
133 | 146 | ||
134 | static int dove_mpp4_ctrl_set(unsigned pid, unsigned long config) | 147 | static int dove_mpp4_ctrl_set(unsigned pid, unsigned long config) |
135 | { | 148 | { |
136 | unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE); | 149 | unsigned long mpp4 = readl(mpp4_base); |
137 | unsigned long mask; | 150 | unsigned long mask; |
138 | 151 | ||
139 | switch (pid) { | 152 | switch (pid) { |
140 | case 24: /* mpp_camera */ | 153 | case 24: /* mpp_camera */ |
141 | mask = DOVE_CAM_GPIO_SEL; | 154 | mask = CAM_GPIO_SEL; |
142 | break; | 155 | break; |
143 | case 40: /* mpp_sdio0 */ | 156 | case 40: /* mpp_sdio0 */ |
144 | mask = DOVE_SD0_GPIO_SEL; | 157 | mask = SD0_GPIO_SEL; |
145 | break; | 158 | break; |
146 | case 46: /* mpp_sdio1 */ | 159 | case 46: /* mpp_sdio1 */ |
147 | mask = DOVE_SD1_GPIO_SEL; | 160 | mask = SD1_GPIO_SEL; |
148 | break; | 161 | break; |
149 | case 58: /* mpp_spi0 */ | 162 | case 58: /* mpp_spi0 */ |
150 | mask = DOVE_SPI_GPIO_SEL; | 163 | mask = SPI_GPIO_SEL; |
151 | break; | 164 | break; |
152 | case 62: /* mpp_uart1 */ | 165 | case 62: /* mpp_uart1 */ |
153 | mask = DOVE_UART1_GPIO_SEL; | 166 | mask = UART1_GPIO_SEL; |
154 | break; | 167 | break; |
155 | default: | 168 | default: |
156 | return -EINVAL; | 169 | return -EINVAL; |
@@ -160,69 +173,69 @@ static int dove_mpp4_ctrl_set(unsigned pid, unsigned long config) | |||
160 | if (config) | 173 | if (config) |
161 | mpp4 |= mask; | 174 | mpp4 |= mask; |
162 | 175 | ||
163 | writel(mpp4, DOVE_MPP_CTRL4_VIRT_BASE); | 176 | writel(mpp4, mpp4_base); |
164 | 177 | ||
165 | return 0; | 178 | return 0; |
166 | } | 179 | } |
167 | 180 | ||
168 | static int dove_nand_ctrl_get(unsigned pid, unsigned long *config) | 181 | static int dove_nand_ctrl_get(unsigned pid, unsigned long *config) |
169 | { | 182 | { |
170 | unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE); | 183 | unsigned int gmpp; |
171 | 184 | ||
172 | *config = ((gmpp & DOVE_NAND_GPIO_EN) != 0); | 185 | regmap_read(gconfmap, MPP_GENERAL_CONFIG, &gmpp); |
186 | *config = ((gmpp & NAND_GPIO_EN) != 0); | ||
173 | 187 | ||
174 | return 0; | 188 | return 0; |
175 | } | 189 | } |
176 | 190 | ||
177 | static int dove_nand_ctrl_set(unsigned pid, unsigned long config) | 191 | static int dove_nand_ctrl_set(unsigned pid, unsigned long config) |
178 | { | 192 | { |
179 | unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE); | 193 | regmap_update_bits(gconfmap, MPP_GENERAL_CONFIG, |
180 | 194 | NAND_GPIO_EN, | |
181 | gmpp &= ~DOVE_NAND_GPIO_EN; | 195 | (config) ? NAND_GPIO_EN : 0); |
182 | if (config) | ||
183 | gmpp |= DOVE_NAND_GPIO_EN; | ||
184 | |||
185 | writel(gmpp, DOVE_MPP_GENERAL_VIRT_BASE); | ||
186 | |||
187 | return 0; | 196 | return 0; |
188 | } | 197 | } |
189 | 198 | ||
190 | static int dove_audio0_ctrl_get(unsigned pid, unsigned long *config) | 199 | static int dove_audio0_ctrl_get(unsigned pid, unsigned long *config) |
191 | { | 200 | { |
192 | unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL); | 201 | unsigned long pmu = readl(mpp_base + PMU_MPP_GENERAL_CTRL); |
193 | 202 | ||
194 | *config = ((pmu & DOVE_AU0_AC97_SEL) != 0); | 203 | *config = ((pmu & AU0_AC97_SEL) != 0); |
195 | 204 | ||
196 | return 0; | 205 | return 0; |
197 | } | 206 | } |
198 | 207 | ||
199 | static int dove_audio0_ctrl_set(unsigned pid, unsigned long config) | 208 | static int dove_audio0_ctrl_set(unsigned pid, unsigned long config) |
200 | { | 209 | { |
201 | unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL); | 210 | unsigned long pmu = readl(mpp_base + PMU_MPP_GENERAL_CTRL); |
202 | 211 | ||
203 | pmu &= ~DOVE_AU0_AC97_SEL; | 212 | pmu &= ~AU0_AC97_SEL; |
204 | if (config) | 213 | if (config) |
205 | pmu |= DOVE_AU0_AC97_SEL; | 214 | pmu |= AU0_AC97_SEL; |
206 | writel(pmu, DOVE_PMU_MPP_GENERAL_CTRL); | 215 | writel(pmu, mpp_base + PMU_MPP_GENERAL_CTRL); |
207 | 216 | ||
208 | return 0; | 217 | return 0; |
209 | } | 218 | } |
210 | 219 | ||
211 | static int dove_audio1_ctrl_get(unsigned pid, unsigned long *config) | 220 | static int dove_audio1_ctrl_get(unsigned pid, unsigned long *config) |
212 | { | 221 | { |
213 | unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE); | 222 | unsigned int mpp4 = readl(mpp4_base); |
214 | unsigned long sspc1 = readl(DOVE_SSP_CTRL_STATUS_1); | 223 | unsigned int sspc1; |
215 | unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE); | 224 | unsigned int gmpp; |
216 | unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2); | 225 | unsigned int gcfg2; |
226 | |||
227 | regmap_read(gconfmap, SSP_CTRL_STATUS_1, &sspc1); | ||
228 | regmap_read(gconfmap, MPP_GENERAL_CONFIG, &gmpp); | ||
229 | regmap_read(gconfmap, GLOBAL_CONFIG_2, &gcfg2); | ||
217 | 230 | ||
218 | *config = 0; | 231 | *config = 0; |
219 | if (mpp4 & DOVE_AU1_GPIO_SEL) | 232 | if (mpp4 & AU1_GPIO_SEL) |
220 | *config |= BIT(3); | 233 | *config |= BIT(3); |
221 | if (sspc1 & DOVE_SSP_ON_AU1) | 234 | if (sspc1 & SSP_ON_AU1) |
222 | *config |= BIT(2); | 235 | *config |= BIT(2); |
223 | if (gmpp & DOVE_AU1_SPDIFO_GPIO_EN) | 236 | if (gmpp & AU1_SPDIFO_GPIO_EN) |
224 | *config |= BIT(1); | 237 | *config |= BIT(1); |
225 | if (gcfg2 & DOVE_TWSI_OPTION3_GPIO) | 238 | if (gcfg2 & TWSI_OPTION3_GPIO) |
226 | *config |= BIT(0); | 239 | *config |= BIT(0); |
227 | 240 | ||
228 | /* SSP/TWSI only if I2S1 not set*/ | 241 | /* SSP/TWSI only if I2S1 not set*/ |
@@ -236,32 +249,22 @@ static int dove_audio1_ctrl_get(unsigned pid, unsigned long *config) | |||
236 | 249 | ||
237 | static int dove_audio1_ctrl_set(unsigned pid, unsigned long config) | 250 | static int dove_audio1_ctrl_set(unsigned pid, unsigned long config) |
238 | { | 251 | { |
239 | unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE); | 252 | unsigned int mpp4 = readl(mpp4_base); |
240 | unsigned long sspc1 = readl(DOVE_SSP_CTRL_STATUS_1); | ||
241 | unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE); | ||
242 | unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2); | ||
243 | 253 | ||
244 | /* | 254 | mpp4 &= ~AU1_GPIO_SEL; |
245 | * clear all audio1 related bits before configure | ||
246 | */ | ||
247 | gcfg2 &= ~DOVE_TWSI_OPTION3_GPIO; | ||
248 | gmpp &= ~DOVE_AU1_SPDIFO_GPIO_EN; | ||
249 | sspc1 &= ~DOVE_SSP_ON_AU1; | ||
250 | mpp4 &= ~DOVE_AU1_GPIO_SEL; | ||
251 | |||
252 | if (config & BIT(0)) | ||
253 | gcfg2 |= DOVE_TWSI_OPTION3_GPIO; | ||
254 | if (config & BIT(1)) | ||
255 | gmpp |= DOVE_AU1_SPDIFO_GPIO_EN; | ||
256 | if (config & BIT(2)) | ||
257 | sspc1 |= DOVE_SSP_ON_AU1; | ||
258 | if (config & BIT(3)) | 255 | if (config & BIT(3)) |
259 | mpp4 |= DOVE_AU1_GPIO_SEL; | 256 | mpp4 |= AU1_GPIO_SEL; |
260 | 257 | writel(mpp4, mpp4_base); | |
261 | writel(mpp4, DOVE_MPP_CTRL4_VIRT_BASE); | 258 | |
262 | writel(sspc1, DOVE_SSP_CTRL_STATUS_1); | 259 | regmap_update_bits(gconfmap, SSP_CTRL_STATUS_1, |
263 | writel(gmpp, DOVE_MPP_GENERAL_VIRT_BASE); | 260 | SSP_ON_AU1, |
264 | writel(gcfg2, DOVE_GLOBAL_CONFIG_2); | 261 | (config & BIT(2)) ? SSP_ON_AU1 : 0); |
262 | regmap_update_bits(gconfmap, MPP_GENERAL_CONFIG, | ||
263 | AU1_SPDIFO_GPIO_EN, | ||
264 | (config & BIT(1)) ? AU1_SPDIFO_GPIO_EN : 0); | ||
265 | regmap_update_bits(gconfmap, GLOBAL_CONFIG_2, | ||
266 | TWSI_OPTION3_GPIO, | ||
267 | (config & BIT(0)) ? TWSI_OPTION3_GPIO : 0); | ||
265 | 268 | ||
266 | return 0; | 269 | return 0; |
267 | } | 270 | } |
@@ -307,15 +310,18 @@ static int dove_audio1_ctrl_gpio_dir(unsigned pid, bool input) | |||
307 | 310 | ||
308 | static int dove_twsi_ctrl_get(unsigned pid, unsigned long *config) | 311 | static int dove_twsi_ctrl_get(unsigned pid, unsigned long *config) |
309 | { | 312 | { |
310 | unsigned long gcfg1 = readl(DOVE_GLOBAL_CONFIG_1); | 313 | unsigned int gcfg1; |
311 | unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2); | 314 | unsigned int gcfg2; |
315 | |||
316 | regmap_read(gconfmap, GLOBAL_CONFIG_1, &gcfg1); | ||
317 | regmap_read(gconfmap, GLOBAL_CONFIG_2, &gcfg2); | ||
312 | 318 | ||
313 | *config = 0; | 319 | *config = 0; |
314 | if (gcfg1 & DOVE_TWSI_ENABLE_OPTION1) | 320 | if (gcfg1 & TWSI_ENABLE_OPTION1) |
315 | *config = 1; | 321 | *config = 1; |
316 | else if (gcfg2 & DOVE_TWSI_ENABLE_OPTION2) | 322 | else if (gcfg2 & TWSI_ENABLE_OPTION2) |
317 | *config = 2; | 323 | *config = 2; |
318 | else if (gcfg2 & DOVE_TWSI_ENABLE_OPTION3) | 324 | else if (gcfg2 & TWSI_ENABLE_OPTION3) |
319 | *config = 3; | 325 | *config = 3; |
320 | 326 | ||
321 | return 0; | 327 | return 0; |
@@ -323,26 +329,27 @@ static int dove_twsi_ctrl_get(unsigned pid, unsigned long *config) | |||
323 | 329 | ||
324 | static int dove_twsi_ctrl_set(unsigned pid, unsigned long config) | 330 | static int dove_twsi_ctrl_set(unsigned pid, unsigned long config) |
325 | { | 331 | { |
326 | unsigned long gcfg1 = readl(DOVE_GLOBAL_CONFIG_1); | 332 | unsigned int gcfg1 = 0; |
327 | unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2); | 333 | unsigned int gcfg2 = 0; |
328 | |||
329 | gcfg1 &= ~DOVE_TWSI_ENABLE_OPTION1; | ||
330 | gcfg2 &= ~(DOVE_TWSI_ENABLE_OPTION2 | DOVE_TWSI_ENABLE_OPTION3); | ||
331 | 334 | ||
332 | switch (config) { | 335 | switch (config) { |
333 | case 1: | 336 | case 1: |
334 | gcfg1 |= DOVE_TWSI_ENABLE_OPTION1; | 337 | gcfg1 = TWSI_ENABLE_OPTION1; |
335 | break; | 338 | break; |
336 | case 2: | 339 | case 2: |
337 | gcfg2 |= DOVE_TWSI_ENABLE_OPTION2; | 340 | gcfg2 = TWSI_ENABLE_OPTION2; |
338 | break; | 341 | break; |
339 | case 3: | 342 | case 3: |
340 | gcfg2 |= DOVE_TWSI_ENABLE_OPTION3; | 343 | gcfg2 = TWSI_ENABLE_OPTION3; |
341 | break; | 344 | break; |
342 | } | 345 | } |
343 | 346 | ||
344 | writel(gcfg1, DOVE_GLOBAL_CONFIG_1); | 347 | regmap_update_bits(gconfmap, GLOBAL_CONFIG_1, |
345 | writel(gcfg2, DOVE_GLOBAL_CONFIG_2); | 348 | TWSI_ENABLE_OPTION1, |
349 | gcfg1); | ||
350 | regmap_update_bits(gconfmap, GLOBAL_CONFIG_2, | ||
351 | TWSI_ENABLE_OPTION2 | TWSI_ENABLE_OPTION3, | ||
352 | gcfg2); | ||
346 | 353 | ||
347 | return 0; | 354 | return 0; |
348 | } | 355 | } |
@@ -749,9 +756,17 @@ static struct of_device_id dove_pinctrl_of_match[] = { | |||
749 | { } | 756 | { } |
750 | }; | 757 | }; |
751 | 758 | ||
759 | static struct regmap_config gc_regmap_config = { | ||
760 | .reg_bits = 32, | ||
761 | .val_bits = 32, | ||
762 | .reg_stride = 4, | ||
763 | .max_register = 5, | ||
764 | }; | ||
765 | |||
752 | static int dove_pinctrl_probe(struct platform_device *pdev) | 766 | static int dove_pinctrl_probe(struct platform_device *pdev) |
753 | { | 767 | { |
754 | struct resource *res; | 768 | struct resource *res, *mpp_res; |
769 | struct resource fb_res; | ||
755 | const struct of_device_id *match = | 770 | const struct of_device_id *match = |
756 | of_match_device(dove_pinctrl_of_match, &pdev->dev); | 771 | of_match_device(dove_pinctrl_of_match, &pdev->dev); |
757 | pdev->dev.platform_data = (void *)match->data; | 772 | pdev->dev.platform_data = (void *)match->data; |
@@ -767,11 +782,58 @@ static int dove_pinctrl_probe(struct platform_device *pdev) | |||
767 | } | 782 | } |
768 | clk_prepare_enable(clk); | 783 | clk_prepare_enable(clk); |
769 | 784 | ||
770 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 785 | mpp_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
771 | mpp_base = devm_ioremap_resource(&pdev->dev, res); | 786 | mpp_base = devm_ioremap_resource(&pdev->dev, mpp_res); |
772 | if (IS_ERR(mpp_base)) | 787 | if (IS_ERR(mpp_base)) |
773 | return PTR_ERR(mpp_base); | 788 | return PTR_ERR(mpp_base); |
774 | 789 | ||
790 | /* prepare fallback resource */ | ||
791 | memcpy(&fb_res, mpp_res, sizeof(struct resource)); | ||
792 | fb_res.start = 0; | ||
793 | |||
794 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
795 | if (!res) { | ||
796 | dev_warn(&pdev->dev, "falling back to hardcoded MPP4 resource\n"); | ||
797 | adjust_resource(&fb_res, | ||
798 | (mpp_res->start & INT_REGS_MASK) + MPP4_REGS_OFFS, 0x4); | ||
799 | res = &fb_res; | ||
800 | } | ||
801 | |||
802 | mpp4_base = devm_ioremap_resource(&pdev->dev, res); | ||
803 | if (IS_ERR(mpp4_base)) | ||
804 | return PTR_ERR(mpp4_base); | ||
805 | |||
806 | res = platform_get_resource(pdev, IORESOURCE_MEM, 2); | ||
807 | if (!res) { | ||
808 | dev_warn(&pdev->dev, "falling back to hardcoded PMU resource\n"); | ||
809 | adjust_resource(&fb_res, | ||
810 | (mpp_res->start & INT_REGS_MASK) + PMU_REGS_OFFS, 0x8); | ||
811 | res = &fb_res; | ||
812 | } | ||
813 | |||
814 | pmu_base = devm_ioremap_resource(&pdev->dev, res); | ||
815 | if (IS_ERR(pmu_base)) | ||
816 | return PTR_ERR(pmu_base); | ||
817 | |||
818 | gconfmap = syscon_regmap_lookup_by_compatible("marvell,dove-global-config"); | ||
819 | if (IS_ERR(gconfmap)) { | ||
820 | void __iomem *gc_base; | ||
821 | |||
822 | dev_warn(&pdev->dev, "falling back to hardcoded global registers\n"); | ||
823 | adjust_resource(&fb_res, | ||
824 | (mpp_res->start & INT_REGS_MASK) + GC_REGS_OFFS, 0x14); | ||
825 | gc_base = devm_ioremap_resource(&pdev->dev, &fb_res); | ||
826 | if (IS_ERR(gc_base)) | ||
827 | return PTR_ERR(gc_base); | ||
828 | gconfmap = devm_regmap_init_mmio(&pdev->dev, | ||
829 | gc_base, &gc_regmap_config); | ||
830 | if (IS_ERR(gconfmap)) | ||
831 | return PTR_ERR(gconfmap); | ||
832 | } | ||
833 | |||
834 | /* Warn on any missing DT resource */ | ||
835 | WARN(fb_res.start, FW_BUG "Missing pinctrl regs in DTB. Please update your firmware.\n"); | ||
836 | |||
775 | return mvebu_pinctrl_probe(pdev); | 837 | return mvebu_pinctrl_probe(pdev); |
776 | } | 838 | } |
777 | 839 | ||