644 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Marvell Armada XP pinctrl driver based on mvebu pinctrl core4 *5 * Copyright (C) 2012 Marvell6 *7 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>8 *9 * This file supports the three variants of Armada XP SoCs that are10 * available: mv78230, mv78260 and mv78460. From a pin muxing11 * perspective, the mv78230 has 49 MPP pins. The mv78260 and mv7846012 * both have 67 MPP pins (more GPIOs and address lines for the memory13 * bus mainly).14 */15 16#include <linux/err.h>17#include <linux/init.h>18#include <linux/io.h>19#include <linux/platform_device.h>20#include <linux/clk.h>21#include <linux/of.h>22#include <linux/pinctrl/pinctrl.h>23#include <linux/property.h>24#include <linux/bitops.h>25 26#include "pinctrl-mvebu.h"27 28static u32 *mpp_saved_regs;29 30enum armada_xp_variant {31 V_MV78230 = BIT(0),32 V_MV78260 = BIT(1),33 V_MV78460 = BIT(2),34 V_MV78230_PLUS = (V_MV78230 | V_MV78260 | V_MV78460),35 V_MV78260_PLUS = (V_MV78260 | V_MV78460),36 V_98DX3236 = BIT(3),37 V_98DX3336 = BIT(4),38 V_98DX4251 = BIT(5),39 V_98DX3236_PLUS = (V_98DX3236 | V_98DX3336 | V_98DX4251),40};41 42static struct mvebu_mpp_mode armada_xp_mpp_modes[] = {43 MPP_MODE(0,44 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),45 MPP_VAR_FUNCTION(0x1, "ge0", "txclkout", V_MV78230_PLUS),46 MPP_VAR_FUNCTION(0x4, "lcd", "d0", V_MV78230_PLUS)),47 MPP_MODE(1,48 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),49 MPP_VAR_FUNCTION(0x1, "ge0", "txd0", V_MV78230_PLUS),50 MPP_VAR_FUNCTION(0x4, "lcd", "d1", V_MV78230_PLUS)),51 MPP_MODE(2,52 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),53 MPP_VAR_FUNCTION(0x1, "ge0", "txd1", V_MV78230_PLUS),54 MPP_VAR_FUNCTION(0x4, "lcd", "d2", V_MV78230_PLUS)),55 MPP_MODE(3,56 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),57 MPP_VAR_FUNCTION(0x1, "ge0", "txd2", V_MV78230_PLUS),58 MPP_VAR_FUNCTION(0x4, "lcd", "d3", V_MV78230_PLUS)),59 MPP_MODE(4,60 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),61 MPP_VAR_FUNCTION(0x1, "ge0", "txd3", V_MV78230_PLUS),62 MPP_VAR_FUNCTION(0x4, "lcd", "d4", V_MV78230_PLUS)),63 MPP_MODE(5,64 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),65 MPP_VAR_FUNCTION(0x1, "ge0", "txctl", V_MV78230_PLUS),66 MPP_VAR_FUNCTION(0x4, "lcd", "d5", V_MV78230_PLUS)),67 MPP_MODE(6,68 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),69 MPP_VAR_FUNCTION(0x1, "ge0", "rxd0", V_MV78230_PLUS),70 MPP_VAR_FUNCTION(0x4, "lcd", "d6", V_MV78230_PLUS)),71 MPP_MODE(7,72 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),73 MPP_VAR_FUNCTION(0x1, "ge0", "rxd1", V_MV78230_PLUS),74 MPP_VAR_FUNCTION(0x4, "lcd", "d7", V_MV78230_PLUS)),75 MPP_MODE(8,76 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),77 MPP_VAR_FUNCTION(0x1, "ge0", "rxd2", V_MV78230_PLUS),78 MPP_VAR_FUNCTION(0x4, "lcd", "d8", V_MV78230_PLUS)),79 MPP_MODE(9,80 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),81 MPP_VAR_FUNCTION(0x1, "ge0", "rxd3", V_MV78230_PLUS),82 MPP_VAR_FUNCTION(0x4, "lcd", "d9", V_MV78230_PLUS)),83 MPP_MODE(10,84 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),85 MPP_VAR_FUNCTION(0x1, "ge0", "rxctl", V_MV78230_PLUS),86 MPP_VAR_FUNCTION(0x4, "lcd", "d10", V_MV78230_PLUS)),87 MPP_MODE(11,88 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),89 MPP_VAR_FUNCTION(0x1, "ge0", "rxclk", V_MV78230_PLUS),90 MPP_VAR_FUNCTION(0x4, "lcd", "d11", V_MV78230_PLUS)),91 MPP_MODE(12,92 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),93 MPP_VAR_FUNCTION(0x1, "ge0", "txd4", V_MV78230_PLUS),94 MPP_VAR_FUNCTION(0x2, "ge1", "txclkout", V_MV78230_PLUS),95 MPP_VAR_FUNCTION(0x4, "lcd", "d12", V_MV78230_PLUS)),96 MPP_MODE(13,97 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),98 MPP_VAR_FUNCTION(0x1, "ge0", "txd5", V_MV78230_PLUS),99 MPP_VAR_FUNCTION(0x2, "ge1", "txd0", V_MV78230_PLUS),100 MPP_VAR_FUNCTION(0x3, "spi1", "mosi", V_MV78230_PLUS),101 MPP_VAR_FUNCTION(0x4, "lcd", "d13", V_MV78230_PLUS)),102 MPP_MODE(14,103 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),104 MPP_VAR_FUNCTION(0x1, "ge0", "txd6", V_MV78230_PLUS),105 MPP_VAR_FUNCTION(0x2, "ge1", "txd1", V_MV78230_PLUS),106 MPP_VAR_FUNCTION(0x3, "spi1", "sck", V_MV78230_PLUS),107 MPP_VAR_FUNCTION(0x4, "lcd", "d14", V_MV78230_PLUS)),108 MPP_MODE(15,109 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),110 MPP_VAR_FUNCTION(0x1, "ge0", "txd7", V_MV78230_PLUS),111 MPP_VAR_FUNCTION(0x2, "ge1", "txd2", V_MV78230_PLUS),112 MPP_VAR_FUNCTION(0x4, "lcd", "d15", V_MV78230_PLUS)),113 MPP_MODE(16,114 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),115 MPP_VAR_FUNCTION(0x1, "ge0", "txclk", V_MV78230_PLUS),116 MPP_VAR_FUNCTION(0x2, "ge1", "txd3", V_MV78230_PLUS),117 MPP_VAR_FUNCTION(0x3, "spi1", "cs0", V_MV78230_PLUS),118 MPP_VAR_FUNCTION(0x4, "lcd", "d16", V_MV78230_PLUS)),119 MPP_MODE(17,120 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),121 MPP_VAR_FUNCTION(0x1, "ge0", "col", V_MV78230_PLUS),122 MPP_VAR_FUNCTION(0x2, "ge1", "txctl", V_MV78230_PLUS),123 MPP_VAR_FUNCTION(0x3, "spi1", "miso", V_MV78230_PLUS),124 MPP_VAR_FUNCTION(0x4, "lcd", "d17", V_MV78230_PLUS)),125 MPP_MODE(18,126 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),127 MPP_VAR_FUNCTION(0x1, "ge0", "rxerr", V_MV78230_PLUS),128 MPP_VAR_FUNCTION(0x2, "ge1", "rxd0", V_MV78230_PLUS),129 MPP_VAR_FUNCTION(0x3, "ptp", "trig", V_MV78230_PLUS),130 MPP_VAR_FUNCTION(0x4, "lcd", "d18", V_MV78230_PLUS)),131 MPP_MODE(19,132 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),133 MPP_VAR_FUNCTION(0x1, "ge0", "crs", V_MV78230_PLUS),134 MPP_VAR_FUNCTION(0x2, "ge1", "rxd1", V_MV78230_PLUS),135 MPP_VAR_FUNCTION(0x3, "ptp", "evreq", V_MV78230_PLUS),136 MPP_VAR_FUNCTION(0x4, "lcd", "d19", V_MV78230_PLUS)),137 MPP_MODE(20,138 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),139 MPP_VAR_FUNCTION(0x1, "ge0", "rxd4", V_MV78230_PLUS),140 MPP_VAR_FUNCTION(0x2, "ge1", "rxd2", V_MV78230_PLUS),141 MPP_VAR_FUNCTION(0x3, "ptp", "clk", V_MV78230_PLUS),142 MPP_VAR_FUNCTION(0x4, "lcd", "d20", V_MV78230_PLUS)),143 MPP_MODE(21,144 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),145 MPP_VAR_FUNCTION(0x1, "ge0", "rxd5", V_MV78230_PLUS),146 MPP_VAR_FUNCTION(0x2, "ge1", "rxd3", V_MV78230_PLUS),147 MPP_VAR_FUNCTION(0x3, "dram", "bat", V_MV78230_PLUS),148 MPP_VAR_FUNCTION(0x4, "lcd", "d21", V_MV78230_PLUS)),149 MPP_MODE(22,150 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),151 MPP_VAR_FUNCTION(0x1, "ge0", "rxd6", V_MV78230_PLUS),152 MPP_VAR_FUNCTION(0x2, "ge1", "rxctl", V_MV78230_PLUS),153 MPP_VAR_FUNCTION(0x3, "sata0", "prsnt", V_MV78230_PLUS),154 MPP_VAR_FUNCTION(0x4, "lcd", "d22", V_MV78230_PLUS)),155 MPP_MODE(23,156 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),157 MPP_VAR_FUNCTION(0x1, "ge0", "rxd7", V_MV78230_PLUS),158 MPP_VAR_FUNCTION(0x2, "ge1", "rxclk", V_MV78230_PLUS),159 MPP_VAR_FUNCTION(0x3, "sata1", "prsnt", V_MV78230_PLUS),160 MPP_VAR_FUNCTION(0x4, "lcd", "d23", V_MV78230_PLUS)),161 MPP_MODE(24,162 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),163 MPP_VAR_FUNCTION(0x1, "sata1", "prsnt", V_MV78230_PLUS),164 MPP_VAR_FUNCTION(0x3, "tdm", "rst", V_MV78230_PLUS),165 MPP_VAR_FUNCTION(0x4, "lcd", "hsync", V_MV78230_PLUS)),166 MPP_MODE(25,167 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),168 MPP_VAR_FUNCTION(0x1, "sata0", "prsnt", V_MV78230_PLUS),169 MPP_VAR_FUNCTION(0x3, "tdm", "pclk", V_MV78230_PLUS),170 MPP_VAR_FUNCTION(0x4, "lcd", "vsync", V_MV78230_PLUS)),171 MPP_MODE(26,172 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),173 MPP_VAR_FUNCTION(0x3, "tdm", "fsync", V_MV78230_PLUS),174 MPP_VAR_FUNCTION(0x4, "lcd", "clk", V_MV78230_PLUS)),175 MPP_MODE(27,176 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),177 MPP_VAR_FUNCTION(0x1, "ptp", "trig", V_MV78230_PLUS),178 MPP_VAR_FUNCTION(0x3, "tdm", "dtx", V_MV78230_PLUS),179 MPP_VAR_FUNCTION(0x4, "lcd", "e", V_MV78230_PLUS)),180 MPP_MODE(28,181 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),182 MPP_VAR_FUNCTION(0x1, "ptp", "evreq", V_MV78230_PLUS),183 MPP_VAR_FUNCTION(0x3, "tdm", "drx", V_MV78230_PLUS),184 MPP_VAR_FUNCTION(0x4, "lcd", "pwm", V_MV78230_PLUS)),185 MPP_MODE(29,186 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),187 MPP_VAR_FUNCTION(0x1, "ptp", "clk", V_MV78230_PLUS),188 MPP_VAR_FUNCTION(0x3, "tdm", "int0", V_MV78230_PLUS),189 MPP_VAR_FUNCTION(0x4, "lcd", "ref-clk", V_MV78230_PLUS)),190 MPP_MODE(30,191 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),192 MPP_VAR_FUNCTION(0x1, "sd0", "clk", V_MV78230_PLUS),193 MPP_VAR_FUNCTION(0x3, "tdm", "int1", V_MV78230_PLUS)),194 MPP_MODE(31,195 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),196 MPP_VAR_FUNCTION(0x1, "sd0", "cmd", V_MV78230_PLUS),197 MPP_VAR_FUNCTION(0x3, "tdm", "int2", V_MV78230_PLUS)),198 MPP_MODE(32,199 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),200 MPP_VAR_FUNCTION(0x1, "sd0", "d0", V_MV78230_PLUS),201 MPP_VAR_FUNCTION(0x3, "tdm", "int3", V_MV78230_PLUS)),202 MPP_MODE(33,203 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),204 MPP_VAR_FUNCTION(0x1, "sd0", "d1", V_MV78230_PLUS),205 MPP_VAR_FUNCTION(0x3, "tdm", "int4", V_MV78230_PLUS),206 MPP_VAR_FUNCTION(0x4, "dram", "bat", V_MV78230_PLUS),207 MPP_VAR_FUNCTION(0x5, "dram", "vttctrl", V_MV78230_PLUS)),208 MPP_MODE(34,209 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),210 MPP_VAR_FUNCTION(0x1, "sd0", "d2", V_MV78230_PLUS),211 MPP_VAR_FUNCTION(0x2, "sata0", "prsnt", V_MV78230_PLUS),212 MPP_VAR_FUNCTION(0x3, "tdm", "int5", V_MV78230_PLUS),213 MPP_VAR_FUNCTION(0x4, "dram", "deccerr", V_MV78230_PLUS)),214 MPP_MODE(35,215 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),216 MPP_VAR_FUNCTION(0x1, "sd0", "d3", V_MV78230_PLUS),217 MPP_VAR_FUNCTION(0x2, "sata1", "prsnt", V_MV78230_PLUS),218 MPP_VAR_FUNCTION(0x3, "tdm", "int6", V_MV78230_PLUS)),219 MPP_MODE(36,220 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),221 MPP_VAR_FUNCTION(0x1, "spi0", "mosi", V_MV78230_PLUS)),222 MPP_MODE(37,223 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),224 MPP_VAR_FUNCTION(0x1, "spi0", "miso", V_MV78230_PLUS)),225 MPP_MODE(38,226 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),227 MPP_VAR_FUNCTION(0x1, "spi0", "sck", V_MV78230_PLUS)),228 MPP_MODE(39,229 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),230 MPP_VAR_FUNCTION(0x1, "spi0", "cs0", V_MV78230_PLUS)),231 MPP_MODE(40,232 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),233 MPP_VAR_FUNCTION(0x1, "spi0", "cs1", V_MV78230_PLUS),234 MPP_VAR_FUNCTION(0x2, "uart2", "cts", V_MV78230_PLUS),235 MPP_VAR_FUNCTION(0x4, "lcd", "vga-hsync", V_MV78230_PLUS),236 MPP_VAR_FUNCTION(0x5, "pcie", "clkreq0", V_MV78230_PLUS),237 MPP_VAR_FUNCTION(0x6, "spi1", "cs1", V_MV78230_PLUS)),238 MPP_MODE(41,239 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),240 MPP_VAR_FUNCTION(0x1, "spi0", "cs2", V_MV78230_PLUS),241 MPP_VAR_FUNCTION(0x2, "uart2", "rts", V_MV78230_PLUS),242 MPP_VAR_FUNCTION(0x3, "sata1", "prsnt", V_MV78230_PLUS),243 MPP_VAR_FUNCTION(0x4, "lcd", "vga-vsync", V_MV78230_PLUS),244 MPP_VAR_FUNCTION(0x5, "pcie", "clkreq1", V_MV78230_PLUS),245 MPP_VAR_FUNCTION(0x6, "spi1", "cs2", V_MV78230_PLUS)),246 MPP_MODE(42,247 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),248 MPP_VAR_FUNCTION(0x1, "uart2", "rxd", V_MV78230_PLUS),249 MPP_VAR_FUNCTION(0x2, "uart0", "cts", V_MV78230_PLUS),250 MPP_VAR_FUNCTION(0x3, "tdm", "int7", V_MV78230_PLUS),251 MPP_VAR_FUNCTION(0x4, "tdm", "timer", V_MV78230_PLUS)),252 MPP_MODE(43,253 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),254 MPP_VAR_FUNCTION(0x1, "uart2", "txd", V_MV78230_PLUS),255 MPP_VAR_FUNCTION(0x2, "uart0", "rts", V_MV78230_PLUS),256 MPP_VAR_FUNCTION(0x3, "spi0", "cs3", V_MV78230_PLUS),257 MPP_VAR_FUNCTION(0x4, "pcie", "rstout", V_MV78230_PLUS),258 MPP_VAR_FUNCTION(0x6, "spi1", "cs3", V_MV78230_PLUS)),259 MPP_MODE(44,260 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),261 MPP_VAR_FUNCTION(0x1, "uart2", "cts", V_MV78230_PLUS),262 MPP_VAR_FUNCTION(0x2, "uart3", "rxd", V_MV78230_PLUS),263 MPP_VAR_FUNCTION(0x3, "spi0", "cs4", V_MV78230_PLUS),264 MPP_VAR_FUNCTION(0x4, "dram", "bat", V_MV78230_PLUS),265 MPP_VAR_FUNCTION(0x5, "pcie", "clkreq2", V_MV78230_PLUS),266 MPP_VAR_FUNCTION(0x6, "spi1", "cs4", V_MV78230_PLUS)),267 MPP_MODE(45,268 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),269 MPP_VAR_FUNCTION(0x1, "uart2", "rts", V_MV78230_PLUS),270 MPP_VAR_FUNCTION(0x2, "uart3", "txd", V_MV78230_PLUS),271 MPP_VAR_FUNCTION(0x3, "spi0", "cs5", V_MV78230_PLUS),272 MPP_VAR_FUNCTION(0x4, "sata1", "prsnt", V_MV78230_PLUS),273 MPP_VAR_FUNCTION(0x5, "dram", "vttctrl", V_MV78230_PLUS),274 MPP_VAR_FUNCTION(0x6, "spi1", "cs5", V_MV78230_PLUS)),275 MPP_MODE(46,276 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),277 MPP_VAR_FUNCTION(0x1, "uart3", "rts", V_MV78230_PLUS),278 MPP_VAR_FUNCTION(0x2, "uart1", "rts", V_MV78230_PLUS),279 MPP_VAR_FUNCTION(0x3, "spi0", "cs6", V_MV78230_PLUS),280 MPP_VAR_FUNCTION(0x4, "sata0", "prsnt", V_MV78230_PLUS),281 MPP_VAR_FUNCTION(0x6, "spi1", "cs6", V_MV78230_PLUS)),282 MPP_MODE(47,283 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),284 MPP_VAR_FUNCTION(0x1, "uart3", "cts", V_MV78230_PLUS),285 MPP_VAR_FUNCTION(0x2, "uart1", "cts", V_MV78230_PLUS),286 MPP_VAR_FUNCTION(0x3, "spi0", "cs7", V_MV78230_PLUS),287 MPP_VAR_FUNCTION(0x4, "ref", "clkout", V_MV78230_PLUS),288 MPP_VAR_FUNCTION(0x5, "pcie", "clkreq3", V_MV78230_PLUS),289 MPP_VAR_FUNCTION(0x6, "spi1", "cs7", V_MV78230_PLUS)),290 MPP_MODE(48,291 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),292 MPP_VAR_FUNCTION(0x1, "dev", "clkout", V_MV78230_PLUS),293 MPP_VAR_FUNCTION(0x2, "dev", "burst/last", V_MV78230_PLUS),294 MPP_VAR_FUNCTION(0x3, "nand", "rb", V_MV78230_PLUS)),295 MPP_MODE(49,296 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),297 MPP_VAR_FUNCTION(0x1, "dev", "we3", V_MV78260_PLUS)),298 MPP_MODE(50,299 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),300 MPP_VAR_FUNCTION(0x1, "dev", "we2", V_MV78260_PLUS)),301 MPP_MODE(51,302 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),303 MPP_VAR_FUNCTION(0x1, "dev", "ad16", V_MV78260_PLUS)),304 MPP_MODE(52,305 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),306 MPP_VAR_FUNCTION(0x1, "dev", "ad17", V_MV78260_PLUS)),307 MPP_MODE(53,308 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),309 MPP_VAR_FUNCTION(0x1, "dev", "ad18", V_MV78260_PLUS)),310 MPP_MODE(54,311 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),312 MPP_VAR_FUNCTION(0x1, "dev", "ad19", V_MV78260_PLUS)),313 MPP_MODE(55,314 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),315 MPP_VAR_FUNCTION(0x1, "dev", "ad20", V_MV78260_PLUS)),316 MPP_MODE(56,317 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),318 MPP_VAR_FUNCTION(0x1, "dev", "ad21", V_MV78260_PLUS)),319 MPP_MODE(57,320 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),321 MPP_VAR_FUNCTION(0x1, "dev", "ad22", V_MV78260_PLUS)),322 MPP_MODE(58,323 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),324 MPP_VAR_FUNCTION(0x1, "dev", "ad23", V_MV78260_PLUS)),325 MPP_MODE(59,326 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),327 MPP_VAR_FUNCTION(0x1, "dev", "ad24", V_MV78260_PLUS)),328 MPP_MODE(60,329 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),330 MPP_VAR_FUNCTION(0x1, "dev", "ad25", V_MV78260_PLUS)),331 MPP_MODE(61,332 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),333 MPP_VAR_FUNCTION(0x1, "dev", "ad26", V_MV78260_PLUS)),334 MPP_MODE(62,335 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),336 MPP_VAR_FUNCTION(0x1, "dev", "ad27", V_MV78260_PLUS)),337 MPP_MODE(63,338 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),339 MPP_VAR_FUNCTION(0x1, "dev", "ad28", V_MV78260_PLUS)),340 MPP_MODE(64,341 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),342 MPP_VAR_FUNCTION(0x1, "dev", "ad29", V_MV78260_PLUS)),343 MPP_MODE(65,344 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),345 MPP_VAR_FUNCTION(0x1, "dev", "ad30", V_MV78260_PLUS)),346 MPP_MODE(66,347 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),348 MPP_VAR_FUNCTION(0x1, "dev", "ad31", V_MV78260_PLUS)),349};350 351static struct mvebu_mpp_mode mv98dx3236_mpp_modes[] = {352 MPP_MODE(0,353 MPP_VAR_FUNCTION(0x0, "gpo", NULL, V_98DX3236_PLUS),354 MPP_VAR_FUNCTION(0x2, "spi0", "mosi", V_98DX3236_PLUS),355 MPP_VAR_FUNCTION(0x4, "dev", "ad8", V_98DX3236_PLUS)),356 MPP_MODE(1,357 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_98DX3236_PLUS),358 MPP_VAR_FUNCTION(0x2, "spi0", "miso", V_98DX3236_PLUS),359 MPP_VAR_FUNCTION(0x4, "dev", "ad9", V_98DX3236_PLUS)),360 MPP_MODE(2,361 MPP_VAR_FUNCTION(0x0, "gpo", NULL, V_98DX3236_PLUS),362 MPP_VAR_FUNCTION(0x2, "spi0", "sck", V_98DX3236_PLUS),363 MPP_VAR_FUNCTION(0x4, "dev", "ad10", V_98DX3236_PLUS)),364 MPP_MODE(3,365 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_98DX3236_PLUS),366 MPP_VAR_FUNCTION(0x2, "spi0", "cs0", V_98DX3236_PLUS),367 MPP_VAR_FUNCTION(0x4, "dev", "ad11", V_98DX3236_PLUS)),368 MPP_MODE(4,369 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_98DX3236_PLUS),370 MPP_VAR_FUNCTION(0x2, "spi0", "cs1", V_98DX3236_PLUS),371 MPP_VAR_FUNCTION(0x3, "smi", "mdc", V_98DX3236_PLUS),372 MPP_VAR_FUNCTION(0x4, "dev", "cs0", V_98DX3236_PLUS)),373 MPP_MODE(5,374 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_98DX3236_PLUS),375 MPP_VAR_FUNCTION(0x1, "pex", "rsto", V_98DX3236_PLUS),376 MPP_VAR_FUNCTION(0x2, "sd0", "cmd", V_98DX4251),377 MPP_VAR_FUNCTION(0x4, "dev", "bootcs", V_98DX3236_PLUS)),378 MPP_MODE(6,379 MPP_VAR_FUNCTION(0x0, "gpo", NULL, V_98DX3236_PLUS),380 MPP_VAR_FUNCTION(0x2, "sd0", "clk", V_98DX4251),381 MPP_VAR_FUNCTION(0x4, "dev", "a2", V_98DX3236_PLUS)),382 MPP_MODE(7,383 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_98DX3236_PLUS),384 MPP_VAR_FUNCTION(0x2, "sd0", "d0", V_98DX4251),385 MPP_VAR_FUNCTION(0x4, "dev", "ale0", V_98DX3236_PLUS)),386 MPP_MODE(8,387 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_98DX3236_PLUS),388 MPP_VAR_FUNCTION(0x2, "sd0", "d1", V_98DX4251),389 MPP_VAR_FUNCTION(0x4, "dev", "ale1", V_98DX3236_PLUS)),390 MPP_MODE(9,391 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_98DX3236_PLUS),392 MPP_VAR_FUNCTION(0x2, "sd0", "d2", V_98DX4251),393 MPP_VAR_FUNCTION(0x4, "dev", "ready0", V_98DX3236_PLUS)),394 MPP_MODE(10,395 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_98DX3236_PLUS),396 MPP_VAR_FUNCTION(0x2, "sd0", "d3", V_98DX4251),397 MPP_VAR_FUNCTION(0x4, "dev", "ad12", V_98DX3236_PLUS)),398 MPP_MODE(11,399 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_98DX3236_PLUS),400 MPP_VAR_FUNCTION(0x2, "uart1", "rxd", V_98DX3236_PLUS),401 MPP_VAR_FUNCTION(0x3, "uart0", "cts", V_98DX3236_PLUS),402 MPP_VAR_FUNCTION(0x4, "dev", "ad13", V_98DX3236_PLUS)),403 MPP_MODE(12,404 MPP_VAR_FUNCTION(0x0, "gpo", NULL, V_98DX3236_PLUS),405 MPP_VAR_FUNCTION(0x2, "uart1", "txd", V_98DX3236_PLUS),406 MPP_VAR_FUNCTION(0x3, "uart0", "rts", V_98DX3236_PLUS),407 MPP_VAR_FUNCTION(0x4, "dev", "ad14", V_98DX3236_PLUS)),408 MPP_MODE(13,409 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_98DX3236_PLUS),410 MPP_VAR_FUNCTION(0x1, "intr", "out", V_98DX3236_PLUS),411 MPP_VAR_FUNCTION(0x4, "dev", "ad15", V_98DX3236_PLUS)),412 MPP_MODE(14,413 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_98DX3236_PLUS),414 MPP_VAR_FUNCTION(0x1, "i2c0", "sck", V_98DX3236_PLUS)),415 MPP_MODE(15,416 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_98DX3236_PLUS),417 MPP_VAR_FUNCTION(0x1, "i2c0", "sda", V_98DX3236_PLUS)),418 MPP_MODE(16,419 MPP_VAR_FUNCTION(0x0, "gpo", NULL, V_98DX3236_PLUS),420 MPP_VAR_FUNCTION(0x4, "dev", "oe", V_98DX3236_PLUS)),421 MPP_MODE(17,422 MPP_VAR_FUNCTION(0x0, "gpo", NULL, V_98DX3236_PLUS),423 MPP_VAR_FUNCTION(0x4, "dev", "clkout", V_98DX3236_PLUS)),424 MPP_MODE(18,425 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_98DX3236_PLUS),426 MPP_VAR_FUNCTION(0x3, "uart1", "txd", V_98DX3236_PLUS)),427 MPP_MODE(19,428 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_98DX3236_PLUS),429 MPP_VAR_FUNCTION(0x3, "uart1", "rxd", V_98DX3236_PLUS),430 MPP_VAR_FUNCTION(0x4, "nand", "rb", V_98DX3236_PLUS)),431 MPP_MODE(20,432 MPP_VAR_FUNCTION(0x0, "gpo", NULL, V_98DX3236_PLUS),433 MPP_VAR_FUNCTION(0x4, "dev", "we0", V_98DX3236_PLUS)),434 MPP_MODE(21,435 MPP_VAR_FUNCTION(0x0, "gpo", NULL, V_98DX3236_PLUS),436 MPP_VAR_FUNCTION(0x4, "dev", "ad0", V_98DX3236_PLUS)),437 MPP_MODE(22,438 MPP_VAR_FUNCTION(0x0, "gpo", NULL, V_98DX3236_PLUS),439 MPP_VAR_FUNCTION(0x4, "dev", "ad1", V_98DX3236_PLUS)),440 MPP_MODE(23,441 MPP_VAR_FUNCTION(0x0, "gpo", NULL, V_98DX3236_PLUS),442 MPP_VAR_FUNCTION(0x4, "dev", "ad2", V_98DX3236_PLUS)),443 MPP_MODE(24,444 MPP_VAR_FUNCTION(0x0, "gpo", NULL, V_98DX3236_PLUS),445 MPP_VAR_FUNCTION(0x4, "dev", "ad3", V_98DX3236_PLUS)),446 MPP_MODE(25,447 MPP_VAR_FUNCTION(0x0, "gpo", NULL, V_98DX3236_PLUS),448 MPP_VAR_FUNCTION(0x4, "dev", "ad4", V_98DX3236_PLUS)),449 MPP_MODE(26,450 MPP_VAR_FUNCTION(0x0, "gpo", NULL, V_98DX3236_PLUS),451 MPP_VAR_FUNCTION(0x4, "dev", "ad5", V_98DX3236_PLUS)),452 MPP_MODE(27,453 MPP_VAR_FUNCTION(0x0, "gpo", NULL, V_98DX3236_PLUS),454 MPP_VAR_FUNCTION(0x4, "dev", "ad6", V_98DX3236_PLUS)),455 MPP_MODE(28,456 MPP_VAR_FUNCTION(0x0, "gpo", NULL, V_98DX3236_PLUS),457 MPP_VAR_FUNCTION(0x4, "dev", "ad7", V_98DX3236_PLUS)),458 MPP_MODE(29,459 MPP_VAR_FUNCTION(0x0, "gpo", NULL, V_98DX3236_PLUS),460 MPP_VAR_FUNCTION(0x4, "dev", "a0", V_98DX3236_PLUS)),461 MPP_MODE(30,462 MPP_VAR_FUNCTION(0x0, "gpo", NULL, V_98DX3236_PLUS),463 MPP_VAR_FUNCTION(0x4, "dev", "a1", V_98DX3236_PLUS)),464 MPP_MODE(31,465 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_98DX3236_PLUS),466 MPP_VAR_FUNCTION(0x1, "slv_smi", "mdc", V_98DX3236_PLUS),467 MPP_VAR_FUNCTION(0x3, "smi", "mdc", V_98DX3236_PLUS),468 MPP_VAR_FUNCTION(0x4, "dev", "we1", V_98DX3236_PLUS)),469 MPP_MODE(32,470 MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_98DX3236_PLUS),471 MPP_VAR_FUNCTION(0x1, "slv_smi", "mdio", V_98DX3236_PLUS),472 MPP_VAR_FUNCTION(0x3, "smi", "mdio", V_98DX3236_PLUS),473 MPP_VAR_FUNCTION(0x4, "dev", "cs1", V_98DX3236_PLUS)),474};475 476static struct mvebu_pinctrl_soc_info armada_xp_pinctrl_info;477 478static const struct of_device_id armada_xp_pinctrl_of_match[] = {479 {480 .compatible = "marvell,mv78230-pinctrl",481 .data = (void *) V_MV78230,482 },483 {484 .compatible = "marvell,mv78260-pinctrl",485 .data = (void *) V_MV78260,486 },487 {488 .compatible = "marvell,mv78460-pinctrl",489 .data = (void *) V_MV78460,490 },491 {492 .compatible = "marvell,98dx3236-pinctrl",493 .data = (void *) V_98DX3236,494 },495 {496 .compatible = "marvell,98dx4251-pinctrl",497 .data = (void *) V_98DX4251,498 },499 { },500};501 502static const struct mvebu_mpp_ctrl mv78230_mpp_controls[] = {503 MPP_FUNC_CTRL(0, 48, NULL, mvebu_mmio_mpp_ctrl),504};505 506static struct pinctrl_gpio_range mv78230_mpp_gpio_ranges[] = {507 MPP_GPIO_RANGE(0, 0, 0, 32),508 MPP_GPIO_RANGE(1, 32, 32, 17),509};510 511static const struct mvebu_mpp_ctrl mv78260_mpp_controls[] = {512 MPP_FUNC_CTRL(0, 66, NULL, mvebu_mmio_mpp_ctrl),513};514 515static struct pinctrl_gpio_range mv78260_mpp_gpio_ranges[] = {516 MPP_GPIO_RANGE(0, 0, 0, 32),517 MPP_GPIO_RANGE(1, 32, 32, 32),518 MPP_GPIO_RANGE(2, 64, 64, 3),519};520 521static const struct mvebu_mpp_ctrl mv78460_mpp_controls[] = {522 MPP_FUNC_CTRL(0, 66, NULL, mvebu_mmio_mpp_ctrl),523};524 525static struct pinctrl_gpio_range mv78460_mpp_gpio_ranges[] = {526 MPP_GPIO_RANGE(0, 0, 0, 32),527 MPP_GPIO_RANGE(1, 32, 32, 32),528 MPP_GPIO_RANGE(2, 64, 64, 3),529};530 531static struct mvebu_mpp_ctrl mv98dx3236_mpp_controls[] = {532 MPP_FUNC_CTRL(0, 32, NULL, mvebu_mmio_mpp_ctrl),533};534 535static struct pinctrl_gpio_range mv98dx3236_mpp_gpio_ranges[] = {536 MPP_GPIO_RANGE(0, 0, 0, 32),537};538 539static int armada_xp_pinctrl_suspend(struct platform_device *pdev,540 pm_message_t state)541{542 struct mvebu_pinctrl_soc_info *soc =543 platform_get_drvdata(pdev);544 int i, nregs;545 546 nregs = DIV_ROUND_UP(soc->nmodes, MVEBU_MPPS_PER_REG);547 548 for (i = 0; i < nregs; i++)549 mpp_saved_regs[i] = readl(soc->control_data[0].base + i * 4);550 551 return 0;552}553 554static int armada_xp_pinctrl_resume(struct platform_device *pdev)555{556 struct mvebu_pinctrl_soc_info *soc =557 platform_get_drvdata(pdev);558 int i, nregs;559 560 nregs = DIV_ROUND_UP(soc->nmodes, MVEBU_MPPS_PER_REG);561 562 for (i = 0; i < nregs; i++)563 writel(mpp_saved_regs[i], soc->control_data[0].base + i * 4);564 565 return 0;566}567 568static int armada_xp_pinctrl_probe(struct platform_device *pdev)569{570 struct mvebu_pinctrl_soc_info *soc = &armada_xp_pinctrl_info;571 int nregs;572 573 soc->variant = (unsigned)device_get_match_data(&pdev->dev) & 0xff;574 575 switch (soc->variant) {576 case V_MV78230:577 soc->controls = mv78230_mpp_controls;578 soc->ncontrols = ARRAY_SIZE(mv78230_mpp_controls);579 soc->modes = armada_xp_mpp_modes;580 /* We don't necessarily want the full list of the581 * armada_xp_mpp_modes, but only the first 'n' ones582 * that are available on this SoC */583 soc->nmodes = mv78230_mpp_controls[0].npins;584 soc->gpioranges = mv78230_mpp_gpio_ranges;585 soc->ngpioranges = ARRAY_SIZE(mv78230_mpp_gpio_ranges);586 break;587 case V_MV78260:588 soc->controls = mv78260_mpp_controls;589 soc->ncontrols = ARRAY_SIZE(mv78260_mpp_controls);590 soc->modes = armada_xp_mpp_modes;591 /* We don't necessarily want the full list of the592 * armada_xp_mpp_modes, but only the first 'n' ones593 * that are available on this SoC */594 soc->nmodes = mv78260_mpp_controls[0].npins;595 soc->gpioranges = mv78260_mpp_gpio_ranges;596 soc->ngpioranges = ARRAY_SIZE(mv78260_mpp_gpio_ranges);597 break;598 case V_MV78460:599 soc->controls = mv78460_mpp_controls;600 soc->ncontrols = ARRAY_SIZE(mv78460_mpp_controls);601 soc->modes = armada_xp_mpp_modes;602 /* We don't necessarily want the full list of the603 * armada_xp_mpp_modes, but only the first 'n' ones604 * that are available on this SoC */605 soc->nmodes = mv78460_mpp_controls[0].npins;606 soc->gpioranges = mv78460_mpp_gpio_ranges;607 soc->ngpioranges = ARRAY_SIZE(mv78460_mpp_gpio_ranges);608 break;609 case V_98DX3236:610 case V_98DX3336:611 case V_98DX4251:612 /* fall-through */613 soc->controls = mv98dx3236_mpp_controls;614 soc->ncontrols = ARRAY_SIZE(mv98dx3236_mpp_controls);615 soc->modes = mv98dx3236_mpp_modes;616 soc->nmodes = mv98dx3236_mpp_controls[0].npins;617 soc->gpioranges = mv98dx3236_mpp_gpio_ranges;618 soc->ngpioranges = ARRAY_SIZE(mv98dx3236_mpp_gpio_ranges);619 break;620 }621 622 nregs = DIV_ROUND_UP(soc->nmodes, MVEBU_MPPS_PER_REG);623 624 mpp_saved_regs = devm_kmalloc_array(&pdev->dev, nregs, sizeof(u32),625 GFP_KERNEL);626 if (!mpp_saved_regs)627 return -ENOMEM;628 629 pdev->dev.platform_data = soc;630 631 return mvebu_pinctrl_simple_mmio_probe(pdev);632}633 634static struct platform_driver armada_xp_pinctrl_driver = {635 .driver = {636 .name = "armada-xp-pinctrl",637 .of_match_table = armada_xp_pinctrl_of_match,638 },639 .probe = armada_xp_pinctrl_probe,640 .suspend = armada_xp_pinctrl_suspend,641 .resume = armada_xp_pinctrl_resume,642};643builtin_platform_driver(armada_xp_pinctrl_driver);644