brintos

brintos / linux-shallow public Read only

0
0
Text · 28.2 KiB · dce601d Raw
874 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Marvell Dove pinctrl driver based on mvebu pinctrl core4 *5 * Author: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>6 */7 8#include <linux/err.h>9#include <linux/init.h>10#include <linux/io.h>11#include <linux/bitops.h>12#include <linux/platform_device.h>13#include <linux/clk.h>14#include <linux/of.h>15#include <linux/mfd/syscon.h>16#include <linux/pinctrl/pinctrl.h>17#include <linux/property.h>18#include <linux/regmap.h>19 20#include "pinctrl-mvebu.h"21 22/* Internal registers can be configured at any 1 MiB aligned address */23#define INT_REGS_MASK		~(SZ_1M - 1)24#define MPP4_REGS_OFFS		0xd044025#define PMU_REGS_OFFS		0xd802c26#define GC_REGS_OFFS		0xe802c27 28/* MPP Base registers */29#define PMU_MPP_GENERAL_CTRL	0x1030#define  AU0_AC97_SEL		BIT(16)31 32/* MPP Control 4 register */33#define SPI_GPIO_SEL		BIT(5)34#define UART1_GPIO_SEL		BIT(4)35#define AU1_GPIO_SEL		BIT(3)36#define CAM_GPIO_SEL		BIT(2)37#define SD1_GPIO_SEL		BIT(1)38#define SD0_GPIO_SEL		BIT(0)39 40/* PMU Signal Select registers */41#define PMU_SIGNAL_SELECT_0	0x0042#define PMU_SIGNAL_SELECT_1	0x0443 44/* Global Config regmap registers */45#define GLOBAL_CONFIG_1		0x0046#define  TWSI_ENABLE_OPTION1	BIT(7)47#define GLOBAL_CONFIG_2		0x0448#define  TWSI_ENABLE_OPTION2	BIT(20)49#define  TWSI_ENABLE_OPTION3	BIT(21)50#define  TWSI_OPTION3_GPIO	BIT(22)51#define SSP_CTRL_STATUS_1	0x0852#define  SSP_ON_AU1		BIT(0)53#define MPP_GENERAL_CONFIG	0x1054#define  AU1_SPDIFO_GPIO_EN	BIT(1)55#define  NAND_GPIO_EN		BIT(0)56 57#define CONFIG_PMU	BIT(4)58 59static void __iomem *mpp4_base;60static void __iomem *pmu_base;61static struct regmap *gconfmap;62 63static int dove_pmu_mpp_ctrl_get(struct mvebu_mpp_ctrl_data *data,64				 unsigned pid, unsigned long *config)65{66	unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;67	unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;68	unsigned long pmu = readl(data->base + PMU_MPP_GENERAL_CTRL);69	unsigned long func;70 71	if ((pmu & BIT(pid)) == 0)72		return mvebu_mmio_mpp_ctrl_get(data, pid, config);73 74	func = readl(pmu_base + PMU_SIGNAL_SELECT_0 + off);75	*config = (func >> shift) & MVEBU_MPP_MASK;76	*config |= CONFIG_PMU;77 78	return 0;79}80 81static int dove_pmu_mpp_ctrl_set(struct mvebu_mpp_ctrl_data *data,82				 unsigned pid, unsigned long config)83{84	unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;85	unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;86	unsigned long pmu = readl(data->base + PMU_MPP_GENERAL_CTRL);87	unsigned long func;88 89	if ((config & CONFIG_PMU) == 0) {90		writel(pmu & ~BIT(pid), data->base + PMU_MPP_GENERAL_CTRL);91		return mvebu_mmio_mpp_ctrl_set(data, pid, config);92	}93 94	writel(pmu | BIT(pid), data->base + PMU_MPP_GENERAL_CTRL);95	func = readl(pmu_base + PMU_SIGNAL_SELECT_0 + off);96	func &= ~(MVEBU_MPP_MASK << shift);97	func |= (config & MVEBU_MPP_MASK) << shift;98	writel(func, pmu_base + PMU_SIGNAL_SELECT_0 + off);99 100	return 0;101}102 103static int dove_mpp4_ctrl_get(struct mvebu_mpp_ctrl_data *data, unsigned pid,104			      unsigned long *config)105{106	unsigned long mpp4 = readl(mpp4_base);107	unsigned long mask;108 109	switch (pid) {110	case 24: /* mpp_camera */111		mask = CAM_GPIO_SEL;112		break;113	case 40: /* mpp_sdio0 */114		mask = SD0_GPIO_SEL;115		break;116	case 46: /* mpp_sdio1 */117		mask = SD1_GPIO_SEL;118		break;119	case 58: /* mpp_spi0 */120		mask = SPI_GPIO_SEL;121		break;122	case 62: /* mpp_uart1 */123		mask = UART1_GPIO_SEL;124		break;125	default:126		return -EINVAL;127	}128 129	*config = ((mpp4 & mask) != 0);130 131	return 0;132}133 134static int dove_mpp4_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid,135			      unsigned long config)136{137	unsigned long mpp4 = readl(mpp4_base);138	unsigned long mask;139 140	switch (pid) {141	case 24: /* mpp_camera */142		mask = CAM_GPIO_SEL;143		break;144	case 40: /* mpp_sdio0 */145		mask = SD0_GPIO_SEL;146		break;147	case 46: /* mpp_sdio1 */148		mask = SD1_GPIO_SEL;149		break;150	case 58: /* mpp_spi0 */151		mask = SPI_GPIO_SEL;152		break;153	case 62: /* mpp_uart1 */154		mask = UART1_GPIO_SEL;155		break;156	default:157		return -EINVAL;158	}159 160	mpp4 &= ~mask;161	if (config)162		mpp4 |= mask;163 164	writel(mpp4, mpp4_base);165 166	return 0;167}168 169static int dove_nand_ctrl_get(struct mvebu_mpp_ctrl_data *data, unsigned pid,170			      unsigned long *config)171{172	unsigned int gmpp;173 174	regmap_read(gconfmap, MPP_GENERAL_CONFIG, &gmpp);175	*config = ((gmpp & NAND_GPIO_EN) != 0);176 177	return 0;178}179 180static int dove_nand_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid,181			      unsigned long config)182{183	regmap_update_bits(gconfmap, MPP_GENERAL_CONFIG,184			   NAND_GPIO_EN,185			   (config) ? NAND_GPIO_EN : 0);186	return 0;187}188 189static int dove_audio0_ctrl_get(struct mvebu_mpp_ctrl_data *data, unsigned pid,190				unsigned long *config)191{192	unsigned long pmu = readl(data->base + PMU_MPP_GENERAL_CTRL);193 194	*config = ((pmu & AU0_AC97_SEL) != 0);195 196	return 0;197}198 199static int dove_audio0_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid,200				unsigned long config)201{202	unsigned long pmu = readl(data->base + PMU_MPP_GENERAL_CTRL);203 204	pmu &= ~AU0_AC97_SEL;205	if (config)206		pmu |= AU0_AC97_SEL;207	writel(pmu, data->base + PMU_MPP_GENERAL_CTRL);208 209	return 0;210}211 212static int dove_audio1_ctrl_get(struct mvebu_mpp_ctrl_data *data, unsigned pid,213				unsigned long *config)214{215	unsigned int mpp4 = readl(mpp4_base);216	unsigned int sspc1;217	unsigned int gmpp;218	unsigned int gcfg2;219 220	regmap_read(gconfmap, SSP_CTRL_STATUS_1, &sspc1);221	regmap_read(gconfmap, MPP_GENERAL_CONFIG, &gmpp);222	regmap_read(gconfmap, GLOBAL_CONFIG_2, &gcfg2);223 224	*config = 0;225	if (mpp4 & AU1_GPIO_SEL)226		*config |= BIT(3);227	if (sspc1 & SSP_ON_AU1)228		*config |= BIT(2);229	if (gmpp & AU1_SPDIFO_GPIO_EN)230		*config |= BIT(1);231	if (gcfg2 & TWSI_OPTION3_GPIO)232		*config |= BIT(0);233 234	/* SSP/TWSI only if I2S1 not set*/235	if ((*config & BIT(3)) == 0)236		*config &= ~(BIT(2) | BIT(0));237	/* TWSI only if SPDIFO not set*/238	if ((*config & BIT(1)) == 0)239		*config &= ~BIT(0);240	return 0;241}242 243static int dove_audio1_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid,244				unsigned long config)245{246	unsigned int mpp4 = readl(mpp4_base);247 248	mpp4 &= ~AU1_GPIO_SEL;249	if (config & BIT(3))250		mpp4 |= AU1_GPIO_SEL;251	writel(mpp4, mpp4_base);252 253	regmap_update_bits(gconfmap, SSP_CTRL_STATUS_1,254			   SSP_ON_AU1,255			   (config & BIT(2)) ? SSP_ON_AU1 : 0);256	regmap_update_bits(gconfmap, MPP_GENERAL_CONFIG,257			   AU1_SPDIFO_GPIO_EN,258			   (config & BIT(1)) ? AU1_SPDIFO_GPIO_EN : 0);259	regmap_update_bits(gconfmap, GLOBAL_CONFIG_2,260			   TWSI_OPTION3_GPIO,261			   (config & BIT(0)) ? TWSI_OPTION3_GPIO : 0);262 263	return 0;264}265 266/* mpp[52:57] gpio pins depend heavily on current config;267 * gpio_req does not try to mux in gpio capabilities to not268 * break other functions. If you require all mpps as gpio269 * enforce gpio setting by pinctrl mapping.270 */271static int dove_audio1_ctrl_gpio_req(struct mvebu_mpp_ctrl_data *data,272				     unsigned pid)273{274	unsigned long config;275 276	dove_audio1_ctrl_get(data, pid, &config);277 278	switch (config) {279	case 0x02: /* i2s1 : gpio[56:57] */280	case 0x0e: /* ssp  : gpio[56:57] */281		if (pid >= 56)282			return 0;283		return -ENOTSUPP;284	case 0x08: /* spdifo : gpio[52:55] */285	case 0x0b: /* twsi   : gpio[52:55] */286		if (pid <= 55)287			return 0;288		return -ENOTSUPP;289	case 0x0a: /* all gpio */290		return 0;291	/* 0x00 : i2s1/spdifo : no gpio */292	/* 0x0c : ssp/spdifo  : no gpio */293	/* 0x0f : ssp/twsi    : no gpio */294	}295	return -ENOTSUPP;296}297 298/* mpp[52:57] has gpio pins capable of in and out */299static int dove_audio1_ctrl_gpio_dir(struct mvebu_mpp_ctrl_data *data,300				     unsigned pid, bool input)301{302	if (pid < 52 || pid > 57)303		return -ENOTSUPP;304	return 0;305}306 307static int dove_twsi_ctrl_get(struct mvebu_mpp_ctrl_data *data, unsigned pid,308			      unsigned long *config)309{310	unsigned int gcfg1;311	unsigned int gcfg2;312 313	regmap_read(gconfmap, GLOBAL_CONFIG_1, &gcfg1);314	regmap_read(gconfmap, GLOBAL_CONFIG_2, &gcfg2);315 316	*config = 0;317	if (gcfg1 & TWSI_ENABLE_OPTION1)318		*config = 1;319	else if (gcfg2 & TWSI_ENABLE_OPTION2)320		*config = 2;321	else if (gcfg2 & TWSI_ENABLE_OPTION3)322		*config = 3;323 324	return 0;325}326 327static int dove_twsi_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid,328			      unsigned long config)329{330	unsigned int gcfg1 = 0;331	unsigned int gcfg2 = 0;332 333	switch (config) {334	case 1:335		gcfg1 = TWSI_ENABLE_OPTION1;336		break;337	case 2:338		gcfg2 = TWSI_ENABLE_OPTION2;339		break;340	case 3:341		gcfg2 = TWSI_ENABLE_OPTION3;342		break;343	}344 345	regmap_update_bits(gconfmap, GLOBAL_CONFIG_1,346			   TWSI_ENABLE_OPTION1,347			   gcfg1);348	regmap_update_bits(gconfmap, GLOBAL_CONFIG_2,349			   TWSI_ENABLE_OPTION2 | TWSI_ENABLE_OPTION3,350			   gcfg2);351 352	return 0;353}354 355static const struct mvebu_mpp_ctrl dove_mpp_controls[] = {356	MPP_FUNC_CTRL(0, 15, NULL, dove_pmu_mpp_ctrl),357	MPP_FUNC_CTRL(16, 23, NULL, mvebu_mmio_mpp_ctrl),358	MPP_FUNC_CTRL(24, 39, "mpp_camera", dove_mpp4_ctrl),359	MPP_FUNC_CTRL(40, 45, "mpp_sdio0", dove_mpp4_ctrl),360	MPP_FUNC_CTRL(46, 51, "mpp_sdio1", dove_mpp4_ctrl),361	MPP_FUNC_GPIO_CTRL(52, 57, "mpp_audio1", dove_audio1_ctrl),362	MPP_FUNC_CTRL(58, 61, "mpp_spi0", dove_mpp4_ctrl),363	MPP_FUNC_CTRL(62, 63, "mpp_uart1", dove_mpp4_ctrl),364	MPP_FUNC_CTRL(64, 71, "mpp_nand", dove_nand_ctrl),365	MPP_FUNC_CTRL(72, 72, "audio0", dove_audio0_ctrl),366	MPP_FUNC_CTRL(73, 73, "twsi", dove_twsi_ctrl),367};368 369static struct mvebu_mpp_mode dove_mpp_modes[] = {370	MPP_MODE(0,371		MPP_FUNCTION(0x00, "gpio", NULL),372		MPP_FUNCTION(0x02, "uart2", "rts"),373		MPP_FUNCTION(0x03, "sdio0", "cd"),374		MPP_FUNCTION(0x0f, "lcd0", "pwm"),375		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),376		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),377		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),378		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),379		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),380		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),381		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),382		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),383		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),384		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),385		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),386		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),387	MPP_MODE(1,388		MPP_FUNCTION(0x00, "gpio", NULL),389		MPP_FUNCTION(0x02, "uart2", "cts"),390		MPP_FUNCTION(0x03, "sdio0", "wp"),391		MPP_FUNCTION(0x0f, "lcd1", "pwm"),392		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),393		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),394		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),395		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),396		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),397		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),398		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),399		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),400		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),401		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),402		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),403		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),404	MPP_MODE(2,405		MPP_FUNCTION(0x00, "gpio", NULL),406		MPP_FUNCTION(0x01, "sata", "prsnt"),407		MPP_FUNCTION(0x02, "uart2", "txd"),408		MPP_FUNCTION(0x03, "sdio0", "buspwr"),409		MPP_FUNCTION(0x04, "uart1", "rts"),410		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),411		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),412		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),413		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),414		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),415		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),416		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),417		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),418		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),419		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),420		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),421		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),422	MPP_MODE(3,423		MPP_FUNCTION(0x00, "gpio", NULL),424		MPP_FUNCTION(0x01, "sata", "act"),425		MPP_FUNCTION(0x02, "uart2", "rxd"),426		MPP_FUNCTION(0x03, "sdio0", "ledctrl"),427		MPP_FUNCTION(0x04, "uart1", "cts"),428		MPP_FUNCTION(0x0f, "lcd-spi", "cs1"),429		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),430		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),431		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),432		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),433		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),434		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),435		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),436		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),437		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),438		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),439		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),440		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),441	MPP_MODE(4,442		MPP_FUNCTION(0x00, "gpio", NULL),443		MPP_FUNCTION(0x02, "uart3", "rts"),444		MPP_FUNCTION(0x03, "sdio1", "cd"),445		MPP_FUNCTION(0x04, "spi1", "miso"),446		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),447		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),448		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),449		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),450		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),451		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),452		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),453		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),454		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),455		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),456		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),457		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),458	MPP_MODE(5,459		MPP_FUNCTION(0x00, "gpio", NULL),460		MPP_FUNCTION(0x02, "uart3", "cts"),461		MPP_FUNCTION(0x03, "sdio1", "wp"),462		MPP_FUNCTION(0x04, "spi1", "cs"),463		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),464		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),465		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),466		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),467		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),468		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),469		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),470		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),471		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),472		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),473		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),474		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),475	MPP_MODE(6,476		MPP_FUNCTION(0x00, "gpio", NULL),477		MPP_FUNCTION(0x02, "uart3", "txd"),478		MPP_FUNCTION(0x03, "sdio1", "buspwr"),479		MPP_FUNCTION(0x04, "spi1", "mosi"),480		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),481		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),482		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),483		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),484		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),485		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),486		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),487		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),488		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),489		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),490		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),491		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),492	MPP_MODE(7,493		MPP_FUNCTION(0x00, "gpio", NULL),494		MPP_FUNCTION(0x02, "uart3", "rxd"),495		MPP_FUNCTION(0x03, "sdio1", "ledctrl"),496		MPP_FUNCTION(0x04, "spi1", "sck"),497		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),498		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),499		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),500		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),501		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),502		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),503		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),504		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),505		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),506		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),507		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),508		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),509	MPP_MODE(8,510		MPP_FUNCTION(0x00, "gpio", NULL),511		MPP_FUNCTION(0x01, "watchdog", "rstout"),512		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),513		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),514		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),515		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),516		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),517		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),518		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),519		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),520		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),521		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),522		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),523		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),524	MPP_MODE(9,525		MPP_FUNCTION(0x00, "gpio", NULL),526		MPP_FUNCTION(0x05, "pex1", "clkreq"),527		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),528		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),529		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),530		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),531		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),532		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),533		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),534		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),535		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),536		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),537		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),538		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),539	MPP_MODE(10,540		MPP_FUNCTION(0x00, "gpio", NULL),541		MPP_FUNCTION(0x05, "ssp", "sclk"),542		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),543		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),544		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),545		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),546		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),547		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),548		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),549		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),550		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),551		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),552		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),553		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),554	MPP_MODE(11,555		MPP_FUNCTION(0x00, "gpio", NULL),556		MPP_FUNCTION(0x01, "sata", "prsnt"),557		MPP_FUNCTION(0x02, "sata-1", "act"),558		MPP_FUNCTION(0x03, "sdio0", "ledctrl"),559		MPP_FUNCTION(0x04, "sdio1", "ledctrl"),560		MPP_FUNCTION(0x05, "pex0", "clkreq"),561		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),562		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),563		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),564		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),565		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),566		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),567		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),568		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),569		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),570		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),571		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),572		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),573	MPP_MODE(12,574		MPP_FUNCTION(0x00, "gpio", NULL),575		MPP_FUNCTION(0x01, "sata", "act"),576		MPP_FUNCTION(0x02, "uart2", "rts"),577		MPP_FUNCTION(0x03, "audio0", "extclk"),578		MPP_FUNCTION(0x04, "sdio1", "cd"),579		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),580		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),581		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),582		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),583		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),584		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),585		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),586		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),587		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),588		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),589		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),590		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),591	MPP_MODE(13,592		MPP_FUNCTION(0x00, "gpio", NULL),593		MPP_FUNCTION(0x02, "uart2", "cts"),594		MPP_FUNCTION(0x03, "audio1", "extclk"),595		MPP_FUNCTION(0x04, "sdio1", "wp"),596		MPP_FUNCTION(0x05, "ssp", "extclk"),597		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),598		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),599		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),600		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),601		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),602		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),603		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),604		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),605		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),606		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),607		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),608		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),609	MPP_MODE(14,610		MPP_FUNCTION(0x00, "gpio", NULL),611		MPP_FUNCTION(0x02, "uart2", "txd"),612		MPP_FUNCTION(0x04, "sdio1", "buspwr"),613		MPP_FUNCTION(0x05, "ssp", "rxd"),614		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),615		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),616		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),617		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),618		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),619		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),620		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),621		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),622		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),623		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),624		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),625		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),626	MPP_MODE(15,627		MPP_FUNCTION(0x00, "gpio", NULL),628		MPP_FUNCTION(0x02, "uart2", "rxd"),629		MPP_FUNCTION(0x04, "sdio1", "ledctrl"),630		MPP_FUNCTION(0x05, "ssp", "sfrm"),631		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),632		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),633		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),634		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),635		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),636		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),637		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),638		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),639		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),640		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),641		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),642		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),643	MPP_MODE(16,644		MPP_FUNCTION(0x00, "gpio", NULL),645		MPP_FUNCTION(0x02, "uart3", "rts"),646		MPP_FUNCTION(0x03, "sdio0", "cd"),647		MPP_FUNCTION(0x04, "lcd-spi", "cs1"),648		MPP_FUNCTION(0x05, "ac97", "sdi1")),649	MPP_MODE(17,650		MPP_FUNCTION(0x00, "gpio", NULL),651		MPP_FUNCTION(0x01, "ac97-1", "sysclko"),652		MPP_FUNCTION(0x02, "uart3", "cts"),653		MPP_FUNCTION(0x03, "sdio0", "wp"),654		MPP_FUNCTION(0x04, "twsi", "sda"),655		MPP_FUNCTION(0x05, "ac97", "sdi2")),656	MPP_MODE(18,657		MPP_FUNCTION(0x00, "gpio", NULL),658		MPP_FUNCTION(0x02, "uart3", "txd"),659		MPP_FUNCTION(0x03, "sdio0", "buspwr"),660		MPP_FUNCTION(0x04, "lcd0", "pwm"),661		MPP_FUNCTION(0x05, "ac97", "sdi3")),662	MPP_MODE(19,663		MPP_FUNCTION(0x00, "gpio", NULL),664		MPP_FUNCTION(0x02, "uart3", "rxd"),665		MPP_FUNCTION(0x03, "sdio0", "ledctrl"),666		MPP_FUNCTION(0x04, "twsi", "sck")),667	MPP_MODE(20,668		MPP_FUNCTION(0x00, "gpio", NULL),669		MPP_FUNCTION(0x01, "ac97", "sysclko"),670		MPP_FUNCTION(0x02, "lcd-spi", "miso"),671		MPP_FUNCTION(0x03, "sdio1", "cd"),672		MPP_FUNCTION(0x05, "sdio0", "cd"),673		MPP_FUNCTION(0x06, "spi1", "miso")),674	MPP_MODE(21,675		MPP_FUNCTION(0x00, "gpio", NULL),676		MPP_FUNCTION(0x01, "uart1", "rts"),677		MPP_FUNCTION(0x02, "lcd-spi", "cs0"),678		MPP_FUNCTION(0x03, "sdio1", "wp"),679		MPP_FUNCTION(0x04, "ssp", "sfrm"),680		MPP_FUNCTION(0x05, "sdio0", "wp"),681		MPP_FUNCTION(0x06, "spi1", "cs")),682	MPP_MODE(22,683		MPP_FUNCTION(0x00, "gpio", NULL),684		MPP_FUNCTION(0x01, "uart1", "cts"),685		MPP_FUNCTION(0x02, "lcd-spi", "mosi"),686		MPP_FUNCTION(0x03, "sdio1", "buspwr"),687		MPP_FUNCTION(0x04, "ssp", "txd"),688		MPP_FUNCTION(0x05, "sdio0", "buspwr"),689		MPP_FUNCTION(0x06, "spi1", "mosi")),690	MPP_MODE(23,691		MPP_FUNCTION(0x00, "gpio", NULL),692		MPP_FUNCTION(0x02, "lcd-spi", "sck"),693		MPP_FUNCTION(0x03, "sdio1", "ledctrl"),694		MPP_FUNCTION(0x04, "ssp", "sclk"),695		MPP_FUNCTION(0x05, "sdio0", "ledctrl"),696		MPP_FUNCTION(0x06, "spi1", "sck")),697	MPP_MODE(24,698		MPP_FUNCTION(0x00, "camera", NULL),699		MPP_FUNCTION(0x01, "gpio", NULL)),700	MPP_MODE(40,701		MPP_FUNCTION(0x00, "sdio0", NULL),702		MPP_FUNCTION(0x01, "gpio", NULL)),703	MPP_MODE(46,704		MPP_FUNCTION(0x00, "sdio1", NULL),705		MPP_FUNCTION(0x01, "gpio", NULL)),706	MPP_MODE(52,707		MPP_FUNCTION(0x00, "i2s1/spdifo", NULL),708		MPP_FUNCTION(0x02, "i2s1", NULL),709		MPP_FUNCTION(0x08, "spdifo", NULL),710		MPP_FUNCTION(0x0a, "gpio", NULL),711		MPP_FUNCTION(0x0b, "twsi", NULL),712		MPP_FUNCTION(0x0c, "ssp/spdifo", NULL),713		MPP_FUNCTION(0x0e, "ssp", NULL),714		MPP_FUNCTION(0x0f, "ssp/twsi", NULL)),715	MPP_MODE(58,716		MPP_FUNCTION(0x00, "spi0", NULL),717		MPP_FUNCTION(0x01, "gpio", NULL)),718	MPP_MODE(62,719		MPP_FUNCTION(0x00, "uart1", NULL),720		MPP_FUNCTION(0x01, "gpio", NULL)),721	MPP_MODE(64,722		MPP_FUNCTION(0x00, "nand", NULL),723		MPP_FUNCTION(0x01, "gpo", NULL)),724	MPP_MODE(72,725		MPP_FUNCTION(0x00, "i2s", NULL),726		MPP_FUNCTION(0x01, "ac97", NULL)),727	MPP_MODE(73,728		MPP_FUNCTION(0x00, "twsi-none", NULL),729		MPP_FUNCTION(0x01, "twsi-opt1", NULL),730		MPP_FUNCTION(0x02, "twsi-opt2", NULL),731		MPP_FUNCTION(0x03, "twsi-opt3", NULL)),732};733 734static struct pinctrl_gpio_range dove_mpp_gpio_ranges[] = {735	MPP_GPIO_RANGE(0,  0,  0, 32),736	MPP_GPIO_RANGE(1, 32, 32, 32),737	MPP_GPIO_RANGE(2, 64, 64,  8),738};739 740static struct mvebu_pinctrl_soc_info dove_pinctrl_info = {741	.controls = dove_mpp_controls,742	.ncontrols = ARRAY_SIZE(dove_mpp_controls),743	.modes = dove_mpp_modes,744	.nmodes = ARRAY_SIZE(dove_mpp_modes),745	.gpioranges = dove_mpp_gpio_ranges,746	.ngpioranges = ARRAY_SIZE(dove_mpp_gpio_ranges),747	.variant = 0,748};749 750static struct clk *clk;751 752static const struct of_device_id dove_pinctrl_of_match[] = {753	{ .compatible = "marvell,dove-pinctrl", .data = &dove_pinctrl_info },754	{ }755};756 757static const struct regmap_config gc_regmap_config = {758	.reg_bits = 32,759	.val_bits = 32,760	.reg_stride = 4,761	.max_register = 5,762};763 764static int dove_pinctrl_probe(struct platform_device *pdev)765{766	struct resource *res, *mpp_res;767	struct resource fb_res;768	struct mvebu_mpp_ctrl_data *mpp_data;769	void __iomem *base;770	int i, ret;771 772	pdev->dev.platform_data = (void *)device_get_match_data(&pdev->dev);773 774	/*775	 * General MPP Configuration Register is part of pdma registers.776	 * grab clk to make sure it is ticking.777	 */778	clk = devm_clk_get(&pdev->dev, NULL);779	if (IS_ERR(clk)) {780		dev_err(&pdev->dev, "Unable to get pdma clock");781		return PTR_ERR(clk);782	}783	clk_prepare_enable(clk);784 785	base = devm_platform_get_and_ioremap_resource(pdev, 0, &mpp_res);786	if (IS_ERR(base)) {787		ret = PTR_ERR(base);788		goto err_probe;789	}790 791	mpp_data = devm_kcalloc(&pdev->dev, dove_pinctrl_info.ncontrols,792				sizeof(*mpp_data), GFP_KERNEL);793	if (!mpp_data) {794		ret = -ENOMEM;795		goto err_probe;796	}797 798	dove_pinctrl_info.control_data = mpp_data;799	for (i = 0; i < ARRAY_SIZE(dove_mpp_controls); i++)800		mpp_data[i].base = base;801 802	/* prepare fallback resource */803	memcpy(&fb_res, mpp_res, sizeof(struct resource));804	fb_res.start = 0;805 806	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);807	if (!res) {808		dev_warn(&pdev->dev, "falling back to hardcoded MPP4 resource\n");809		adjust_resource(&fb_res,810			(mpp_res->start & INT_REGS_MASK) + MPP4_REGS_OFFS, 0x4);811		res = &fb_res;812	}813 814	mpp4_base = devm_ioremap_resource(&pdev->dev, res);815	if (IS_ERR(mpp4_base)) {816		ret = PTR_ERR(mpp4_base);817		goto err_probe;818	}819 820	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);821	if (!res) {822		dev_warn(&pdev->dev, "falling back to hardcoded PMU resource\n");823		adjust_resource(&fb_res,824			(mpp_res->start & INT_REGS_MASK) + PMU_REGS_OFFS, 0x8);825		res = &fb_res;826	}827 828	pmu_base = devm_ioremap_resource(&pdev->dev, res);829	if (IS_ERR(pmu_base)) {830		ret = PTR_ERR(pmu_base);831		goto err_probe;832	}833 834	gconfmap = syscon_regmap_lookup_by_compatible("marvell,dove-global-config");835	if (IS_ERR(gconfmap)) {836		void __iomem *gc_base;837 838		dev_warn(&pdev->dev, "falling back to hardcoded global registers\n");839		adjust_resource(&fb_res,840			(mpp_res->start & INT_REGS_MASK) + GC_REGS_OFFS, 0x14);841		gc_base = devm_ioremap_resource(&pdev->dev, &fb_res);842		if (IS_ERR(gc_base)) {843			ret = PTR_ERR(gc_base);844			goto err_probe;845		}846 847		gconfmap = devm_regmap_init_mmio(&pdev->dev,848						 gc_base, &gc_regmap_config);849		if (IS_ERR(gconfmap)) {850			ret = PTR_ERR(gconfmap);851			goto err_probe;852		}853	}854 855	/* Warn on any missing DT resource */856	if (fb_res.start)857		dev_warn(&pdev->dev, FW_BUG "Missing pinctrl regs in DTB. Please update your firmware.\n");858 859	return mvebu_pinctrl_probe(pdev);860err_probe:861	clk_disable_unprepare(clk);862	return ret;863}864 865static struct platform_driver dove_pinctrl_driver = {866	.driver = {867		.name = "dove-pinctrl",868		.suppress_bind_attrs = true,869		.of_match_table = dove_pinctrl_of_match,870	},871	.probe = dove_pinctrl_probe,872};873builtin_platform_driver(dove_pinctrl_driver);874