diff options
Diffstat (limited to 'drivers/pinctrl/mvebu/pinctrl-dove.c')
-rw-r--r-- | drivers/pinctrl/mvebu/pinctrl-dove.c | 404 |
1 files changed, 225 insertions, 179 deletions
diff --git a/drivers/pinctrl/mvebu/pinctrl-dove.c b/drivers/pinctrl/mvebu/pinctrl-dove.c index 47268393af3..3b022178a56 100644 --- a/drivers/pinctrl/mvebu/pinctrl-dove.c +++ b/drivers/pinctrl/mvebu/pinctrl-dove.c @@ -18,107 +18,122 @@ #include <linux/clk.h> #include <linux/of.h> #include <linux/of_device.h> +#include <linux/mfd/syscon.h> #include <linux/pinctrl/pinctrl.h> +#include <linux/regmap.h> #include "pinctrl-mvebu.h" -#define DOVE_SB_REGS_VIRT_BASE IOMEM(0xfde00000) -#define DOVE_MPP_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0xd0200) -#define DOVE_PMU_MPP_GENERAL_CTRL (DOVE_MPP_VIRT_BASE + 0x10) -#define DOVE_AU0_AC97_SEL BIT(16) -#define DOVE_PMU_SIGNAL_SELECT_0 (DOVE_SB_REGS_VIRT_BASE + 0xd802C) -#define DOVE_PMU_SIGNAL_SELECT_1 (DOVE_SB_REGS_VIRT_BASE + 0xd8030) -#define DOVE_GLOBAL_CONFIG_1 (DOVE_SB_REGS_VIRT_BASE + 0xe802C) -#define DOVE_GLOBAL_CONFIG_1 (DOVE_SB_REGS_VIRT_BASE + 0xe802C) -#define DOVE_TWSI_ENABLE_OPTION1 BIT(7) -#define DOVE_GLOBAL_CONFIG_2 (DOVE_SB_REGS_VIRT_BASE + 0xe8030) -#define DOVE_TWSI_ENABLE_OPTION2 BIT(20) -#define DOVE_TWSI_ENABLE_OPTION3 BIT(21) -#define DOVE_TWSI_OPTION3_GPIO BIT(22) -#define DOVE_SSP_CTRL_STATUS_1 (DOVE_SB_REGS_VIRT_BASE + 0xe8034) -#define DOVE_SSP_ON_AU1 BIT(0) -#define DOVE_MPP_GENERAL_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0xe803c) -#define DOVE_AU1_SPDIFO_GPIO_EN BIT(1) -#define DOVE_NAND_GPIO_EN BIT(0) -#define DOVE_GPIO_LO_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0xd0400) -#define DOVE_MPP_CTRL4_VIRT_BASE (DOVE_GPIO_LO_VIRT_BASE + 0x40) -#define DOVE_SPI_GPIO_SEL BIT(5) -#define DOVE_UART1_GPIO_SEL BIT(4) -#define DOVE_AU1_GPIO_SEL BIT(3) -#define DOVE_CAM_GPIO_SEL BIT(2) -#define DOVE_SD1_GPIO_SEL BIT(1) -#define DOVE_SD0_GPIO_SEL BIT(0) - -#define MPPS_PER_REG 8 -#define MPP_BITS 4 -#define MPP_MASK 0xf +/* Internal registers can be configured at any 1 MiB aligned address */ +#define INT_REGS_MASK ~(SZ_1M - 1) +#define MPP4_REGS_OFFS 0xd0440 +#define PMU_REGS_OFFS 0xd802c +#define GC_REGS_OFFS 0xe802c + +/* MPP Base registers */ +#define PMU_MPP_GENERAL_CTRL 0x10 +#define AU0_AC97_SEL BIT(16) + +/* MPP Control 4 register */ +#define SPI_GPIO_SEL BIT(5) +#define UART1_GPIO_SEL BIT(4) +#define AU1_GPIO_SEL BIT(3) +#define CAM_GPIO_SEL BIT(2) +#define SD1_GPIO_SEL BIT(1) +#define SD0_GPIO_SEL BIT(0) + +/* PMU Signal Select registers */ +#define PMU_SIGNAL_SELECT_0 0x00 +#define PMU_SIGNAL_SELECT_1 0x04 + +/* Global Config regmap registers */ +#define GLOBAL_CONFIG_1 0x00 +#define TWSI_ENABLE_OPTION1 BIT(7) +#define GLOBAL_CONFIG_2 0x04 +#define TWSI_ENABLE_OPTION2 BIT(20) +#define TWSI_ENABLE_OPTION3 BIT(21) +#define TWSI_OPTION3_GPIO BIT(22) +#define SSP_CTRL_STATUS_1 0x08 +#define SSP_ON_AU1 BIT(0) +#define MPP_GENERAL_CONFIG 0x10 +#define AU1_SPDIFO_GPIO_EN BIT(1) +#define NAND_GPIO_EN BIT(0) #define CONFIG_PMU BIT(4) -static int dove_pmu_mpp_ctrl_get(struct mvebu_mpp_ctrl *ctrl, - unsigned long *config) +static void __iomem *mpp_base; +static void __iomem *mpp4_base; +static void __iomem *pmu_base; +static struct regmap *gconfmap; + +static int dove_mpp_ctrl_get(unsigned pid, unsigned long *config) +{ + return default_mpp_ctrl_get(mpp_base, pid, config); +} + +static int dove_mpp_ctrl_set(unsigned pid, unsigned long config) { - unsigned off = (ctrl->pid / MPPS_PER_REG) * MPP_BITS; - unsigned shift = (ctrl->pid % MPPS_PER_REG) * MPP_BITS; - unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL); + return default_mpp_ctrl_set(mpp_base, pid, config); +} + +static int dove_pmu_mpp_ctrl_get(unsigned pid, unsigned long *config) +{ + unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS; + unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS; + unsigned long pmu = readl(mpp_base + PMU_MPP_GENERAL_CTRL); unsigned long func; - if (pmu & (1 << ctrl->pid)) { - func = readl(DOVE_PMU_SIGNAL_SELECT_0 + off); - *config = (func >> shift) & MPP_MASK; - *config |= CONFIG_PMU; - } else { - func = readl(DOVE_MPP_VIRT_BASE + off); - *config = (func >> shift) & MPP_MASK; - } + if ((pmu & BIT(pid)) == 0) + return default_mpp_ctrl_get(mpp_base, pid, config); + + func = readl(pmu_base + PMU_SIGNAL_SELECT_0 + off); + *config = (func >> shift) & MVEBU_MPP_MASK; + *config |= CONFIG_PMU; + return 0; } -static int dove_pmu_mpp_ctrl_set(struct mvebu_mpp_ctrl *ctrl, - unsigned long config) +static int dove_pmu_mpp_ctrl_set(unsigned pid, unsigned long config) { - unsigned off = (ctrl->pid / MPPS_PER_REG) * MPP_BITS; - unsigned shift = (ctrl->pid % MPPS_PER_REG) * MPP_BITS; - unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL); + unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS; + unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS; + unsigned long pmu = readl(mpp_base + PMU_MPP_GENERAL_CTRL); unsigned long func; - if (config & CONFIG_PMU) { - writel(pmu | (1 << ctrl->pid), DOVE_PMU_MPP_GENERAL_CTRL); - func = readl(DOVE_PMU_SIGNAL_SELECT_0 + off); - func &= ~(MPP_MASK << shift); - func |= (config & MPP_MASK) << shift; - writel(func, DOVE_PMU_SIGNAL_SELECT_0 + off); - } else { - writel(pmu & ~(1 << ctrl->pid), DOVE_PMU_MPP_GENERAL_CTRL); - func = readl(DOVE_MPP_VIRT_BASE + off); - func &= ~(MPP_MASK << shift); - func |= (config & MPP_MASK) << shift; - writel(func, DOVE_MPP_VIRT_BASE + off); + if ((config & CONFIG_PMU) == 0) { + writel(pmu & ~BIT(pid), mpp_base + PMU_MPP_GENERAL_CTRL); + return default_mpp_ctrl_set(mpp_base, pid, config); } + + writel(pmu | BIT(pid), mpp_base + PMU_MPP_GENERAL_CTRL); + func = readl(pmu_base + PMU_SIGNAL_SELECT_0 + off); + func &= ~(MVEBU_MPP_MASK << shift); + func |= (config & MVEBU_MPP_MASK) << shift; + writel(func, pmu_base + PMU_SIGNAL_SELECT_0 + off); + return 0; } -static int dove_mpp4_ctrl_get(struct mvebu_mpp_ctrl *ctrl, - unsigned long *config) +static int dove_mpp4_ctrl_get(unsigned pid, unsigned long *config) { - unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE); + unsigned long mpp4 = readl(mpp4_base); unsigned long mask; - switch (ctrl->pid) { + switch (pid) { case 24: /* mpp_camera */ - mask = DOVE_CAM_GPIO_SEL; + mask = CAM_GPIO_SEL; break; case 40: /* mpp_sdio0 */ - mask = DOVE_SD0_GPIO_SEL; + mask = SD0_GPIO_SEL; break; case 46: /* mpp_sdio1 */ - mask = DOVE_SD1_GPIO_SEL; + mask = SD1_GPIO_SEL; break; case 58: /* mpp_spi0 */ - mask = DOVE_SPI_GPIO_SEL; + mask = SPI_GPIO_SEL; break; case 62: /* mpp_uart1 */ - mask = DOVE_UART1_GPIO_SEL; + mask = UART1_GPIO_SEL; break; default: return -EINVAL; @@ -129,27 +144,26 @@ static int dove_mpp4_ctrl_get(struct mvebu_mpp_ctrl *ctrl, return 0; } -static int dove_mpp4_ctrl_set(struct mvebu_mpp_ctrl *ctrl, - unsigned long config) +static int dove_mpp4_ctrl_set(unsigned pid, unsigned long config) { - unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE); + unsigned long mpp4 = readl(mpp4_base); unsigned long mask; - switch (ctrl->pid) { + switch (pid) { case 24: /* mpp_camera */ - mask = DOVE_CAM_GPIO_SEL; + mask = CAM_GPIO_SEL; break; case 40: /* mpp_sdio0 */ - mask = DOVE_SD0_GPIO_SEL; + mask = SD0_GPIO_SEL; break; case 46: /* mpp_sdio1 */ - mask = DOVE_SD1_GPIO_SEL; + mask = SD1_GPIO_SEL; break; case 58: /* mpp_spi0 */ - mask = DOVE_SPI_GPIO_SEL; + mask = SPI_GPIO_SEL; break; case 62: /* mpp_uart1 */ - mask = DOVE_UART1_GPIO_SEL; + mask = UART1_GPIO_SEL; break; default: return -EINVAL; @@ -159,74 +173,69 @@ static int dove_mpp4_ctrl_set(struct mvebu_mpp_ctrl *ctrl, if (config) mpp4 |= mask; - writel(mpp4, DOVE_MPP_CTRL4_VIRT_BASE); + writel(mpp4, mpp4_base); return 0; } -static int dove_nand_ctrl_get(struct mvebu_mpp_ctrl *ctrl, - unsigned long *config) +static int dove_nand_ctrl_get(unsigned pid, unsigned long *config) { - unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE); + unsigned int gmpp; - *config = ((gmpp & DOVE_NAND_GPIO_EN) != 0); + regmap_read(gconfmap, MPP_GENERAL_CONFIG, &gmpp); + *config = ((gmpp & NAND_GPIO_EN) != 0); return 0; } -static int dove_nand_ctrl_set(struct mvebu_mpp_ctrl *ctrl, - unsigned long config) +static int dove_nand_ctrl_set(unsigned pid, unsigned long config) { - unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE); - - gmpp &= ~DOVE_NAND_GPIO_EN; - if (config) - gmpp |= DOVE_NAND_GPIO_EN; - - writel(gmpp, DOVE_MPP_GENERAL_VIRT_BASE); - + regmap_update_bits(gconfmap, MPP_GENERAL_CONFIG, + NAND_GPIO_EN, + (config) ? NAND_GPIO_EN : 0); return 0; } -static int dove_audio0_ctrl_get(struct mvebu_mpp_ctrl *ctrl, - unsigned long *config) +static int dove_audio0_ctrl_get(unsigned pid, unsigned long *config) { - unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL); + unsigned long pmu = readl(mpp_base + PMU_MPP_GENERAL_CTRL); - *config = ((pmu & DOVE_AU0_AC97_SEL) != 0); + *config = ((pmu & AU0_AC97_SEL) != 0); return 0; } -static int dove_audio0_ctrl_set(struct mvebu_mpp_ctrl *ctrl, - unsigned long config) +static int dove_audio0_ctrl_set(unsigned pid, unsigned long config) { - unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL); + unsigned long pmu = readl(mpp_base + PMU_MPP_GENERAL_CTRL); - pmu &= ~DOVE_AU0_AC97_SEL; + pmu &= ~AU0_AC97_SEL; if (config) - pmu |= DOVE_AU0_AC97_SEL; - writel(pmu, DOVE_PMU_MPP_GENERAL_CTRL); + pmu |= AU0_AC97_SEL; + writel(pmu, mpp_base + PMU_MPP_GENERAL_CTRL); return 0; } -static int dove_audio1_ctrl_get(struct mvebu_mpp_ctrl *ctrl, - unsigned long *config) +static int dove_audio1_ctrl_get(unsigned pid, unsigned long *config) { - unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE); - unsigned long sspc1 = readl(DOVE_SSP_CTRL_STATUS_1); - unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE); - unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2); + unsigned int mpp4 = readl(mpp4_base); + unsigned int sspc1; + unsigned int gmpp; + unsigned int gcfg2; + + regmap_read(gconfmap, SSP_CTRL_STATUS_1, &sspc1); + regmap_read(gconfmap, MPP_GENERAL_CONFIG, &gmpp); + regmap_read(gconfmap, GLOBAL_CONFIG_2, &gcfg2); *config = 0; - if (mpp4 & DOVE_AU1_GPIO_SEL) + if (mpp4 & AU1_GPIO_SEL) *config |= BIT(3); - if (sspc1 & DOVE_SSP_ON_AU1) + if (sspc1 & SSP_ON_AU1) *config |= BIT(2); - if (gmpp & DOVE_AU1_SPDIFO_GPIO_EN) + if (gmpp & AU1_SPDIFO_GPIO_EN) *config |= BIT(1); - if (gcfg2 & DOVE_TWSI_OPTION3_GPIO) + if (gcfg2 & TWSI_OPTION3_GPIO) *config |= BIT(0); /* SSP/TWSI only if I2S1 not set*/ @@ -238,35 +247,24 @@ static int dove_audio1_ctrl_get(struct mvebu_mpp_ctrl *ctrl, return 0; } -static int dove_audio1_ctrl_set(struct mvebu_mpp_ctrl *ctrl, - unsigned long config) +static int dove_audio1_ctrl_set(unsigned pid, unsigned long config) { - unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE); - unsigned long sspc1 = readl(DOVE_SSP_CTRL_STATUS_1); - unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE); - unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2); + unsigned int mpp4 = readl(mpp4_base); - /* - * clear all audio1 related bits before configure - */ - gcfg2 &= ~DOVE_TWSI_OPTION3_GPIO; - gmpp &= ~DOVE_AU1_SPDIFO_GPIO_EN; - sspc1 &= ~DOVE_SSP_ON_AU1; - mpp4 &= ~DOVE_AU1_GPIO_SEL; - - if (config & BIT(0)) - gcfg2 |= DOVE_TWSI_OPTION3_GPIO; - if (config & BIT(1)) - gmpp |= DOVE_AU1_SPDIFO_GPIO_EN; - if (config & BIT(2)) - sspc1 |= DOVE_SSP_ON_AU1; + mpp4 &= ~AU1_GPIO_SEL; if (config & BIT(3)) - mpp4 |= DOVE_AU1_GPIO_SEL; - - writel(mpp4, DOVE_MPP_CTRL4_VIRT_BASE); - writel(sspc1, DOVE_SSP_CTRL_STATUS_1); - writel(gmpp, DOVE_MPP_GENERAL_VIRT_BASE); - writel(gcfg2, DOVE_GLOBAL_CONFIG_2); + mpp4 |= AU1_GPIO_SEL; + writel(mpp4, mpp4_base); + + regmap_update_bits(gconfmap, SSP_CTRL_STATUS_1, + SSP_ON_AU1, + (config & BIT(2)) ? SSP_ON_AU1 : 0); + regmap_update_bits(gconfmap, MPP_GENERAL_CONFIG, + AU1_SPDIFO_GPIO_EN, + (config & BIT(1)) ? AU1_SPDIFO_GPIO_EN : 0); + regmap_update_bits(gconfmap, GLOBAL_CONFIG_2, + TWSI_OPTION3_GPIO, + (config & BIT(0)) ? TWSI_OPTION3_GPIO : 0); return 0; } @@ -276,11 +274,11 @@ static int dove_audio1_ctrl_set(struct mvebu_mpp_ctrl *ctrl, * break other functions. If you require all mpps as gpio * enforce gpio setting by pinctrl mapping. */ -static int dove_audio1_ctrl_gpio_req(struct mvebu_mpp_ctrl *ctrl, u8 pid) +static int dove_audio1_ctrl_gpio_req(unsigned pid) { unsigned long config; - dove_audio1_ctrl_get(ctrl, &config); + dove_audio1_ctrl_get(pid, &config); switch (config) { case 0x02: /* i2s1 : gpio[56:57] */ @@ -303,76 +301,62 @@ static int dove_audio1_ctrl_gpio_req(struct mvebu_mpp_ctrl *ctrl, u8 pid) } /* mpp[52:57] has gpio pins capable of in and out */ -static int dove_audio1_ctrl_gpio_dir(struct mvebu_mpp_ctrl *ctrl, u8 pid, - bool input) +static int dove_audio1_ctrl_gpio_dir(unsigned pid, bool input) { if (pid < 52 || pid > 57) return -ENOTSUPP; return 0; } -static int dove_twsi_ctrl_get(struct mvebu_mpp_ctrl *ctrl, - unsigned long *config) +static int dove_twsi_ctrl_get(unsigned pid, unsigned long *config) { - unsigned long gcfg1 = readl(DOVE_GLOBAL_CONFIG_1); - unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2); + unsigned int gcfg1; + unsigned int gcfg2; + + regmap_read(gconfmap, GLOBAL_CONFIG_1, &gcfg1); + regmap_read(gconfmap, GLOBAL_CONFIG_2, &gcfg2); *config = 0; - if (gcfg1 & DOVE_TWSI_ENABLE_OPTION1) + if (gcfg1 & TWSI_ENABLE_OPTION1) *config = 1; - else if (gcfg2 & DOVE_TWSI_ENABLE_OPTION2) + else if (gcfg2 & TWSI_ENABLE_OPTION2) *config = 2; - else if (gcfg2 & DOVE_TWSI_ENABLE_OPTION3) + else if (gcfg2 & TWSI_ENABLE_OPTION3) *config = 3; return 0; } -static int dove_twsi_ctrl_set(struct mvebu_mpp_ctrl *ctrl, - unsigned long config) +static int dove_twsi_ctrl_set(unsigned pid, unsigned long config) { - unsigned long gcfg1 = readl(DOVE_GLOBAL_CONFIG_1); - unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2); - - gcfg1 &= ~DOVE_TWSI_ENABLE_OPTION1; - gcfg2 &= ~(DOVE_TWSI_ENABLE_OPTION2 | DOVE_TWSI_ENABLE_OPTION3); + unsigned int gcfg1 = 0; + unsigned int gcfg2 = 0; switch (config) { case 1: - gcfg1 |= DOVE_TWSI_ENABLE_OPTION1; + gcfg1 = TWSI_ENABLE_OPTION1; break; case 2: - gcfg2 |= DOVE_TWSI_ENABLE_OPTION2; + gcfg2 = TWSI_ENABLE_OPTION2; break; case 3: - gcfg2 |= DOVE_TWSI_ENABLE_OPTION3; + gcfg2 = TWSI_ENABLE_OPTION3; break; } - writel(gcfg1, DOVE_GLOBAL_CONFIG_1); - writel(gcfg2, DOVE_GLOBAL_CONFIG_2); + regmap_update_bits(gconfmap, GLOBAL_CONFIG_1, + TWSI_ENABLE_OPTION1, + gcfg1); + regmap_update_bits(gconfmap, GLOBAL_CONFIG_2, + TWSI_ENABLE_OPTION2 | TWSI_ENABLE_OPTION3, + gcfg2); return 0; } static struct mvebu_mpp_ctrl dove_mpp_controls[] = { - MPP_FUNC_CTRL(0, 0, "mpp0", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(1, 1, "mpp1", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(2, 2, "mpp2", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(3, 3, "mpp3", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(4, 4, "mpp4", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(5, 5, "mpp5", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(6, 6, "mpp6", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(7, 7, "mpp7", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(8, 8, "mpp8", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(9, 9, "mpp9", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(10, 10, "mpp10", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(11, 11, "mpp11", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(12, 12, "mpp12", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(13, 13, "mpp13", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(14, 14, "mpp14", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(15, 15, "mpp15", dove_pmu_mpp_ctrl), - MPP_REG_CTRL(16, 23), + MPP_FUNC_CTRL(0, 15, NULL, dove_pmu_mpp_ctrl), + MPP_FUNC_CTRL(16, 23, NULL, dove_mpp_ctrl), MPP_FUNC_CTRL(24, 39, "mpp_camera", dove_mpp4_ctrl), MPP_FUNC_CTRL(40, 45, "mpp_sdio0", dove_mpp4_ctrl), MPP_FUNC_CTRL(46, 51, "mpp_sdio1", dove_mpp4_ctrl), @@ -772,8 +756,17 @@ static struct of_device_id dove_pinctrl_of_match[] = { { } }; +static struct regmap_config gc_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = 5, +}; + static int dove_pinctrl_probe(struct platform_device *pdev) { + struct resource *res, *mpp_res; + struct resource fb_res; const struct of_device_id *match = of_match_device(dove_pinctrl_of_match, &pdev->dev); pdev->dev.platform_data = (void *)match->data; @@ -789,6 +782,59 @@ static int dove_pinctrl_probe(struct platform_device *pdev) } clk_prepare_enable(clk); + mpp_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + mpp_base = devm_ioremap_resource(&pdev->dev, mpp_res); + if (IS_ERR(mpp_base)) + return PTR_ERR(mpp_base); + + /* prepare fallback resource */ + memcpy(&fb_res, mpp_res, sizeof(struct resource)); + fb_res.start = 0; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res) { + dev_warn(&pdev->dev, "falling back to hardcoded MPP4 resource\n"); + adjust_resource(&fb_res, + (mpp_res->start & INT_REGS_MASK) + MPP4_REGS_OFFS, 0x4); + res = &fb_res; + } + + mpp4_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(mpp4_base)) + return PTR_ERR(mpp4_base); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 2); + if (!res) { + dev_warn(&pdev->dev, "falling back to hardcoded PMU resource\n"); + adjust_resource(&fb_res, + (mpp_res->start & INT_REGS_MASK) + PMU_REGS_OFFS, 0x8); + res = &fb_res; + } + + pmu_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(pmu_base)) + return PTR_ERR(pmu_base); + + gconfmap = syscon_regmap_lookup_by_compatible("marvell,dove-global-config"); + if (IS_ERR(gconfmap)) { + void __iomem *gc_base; + + dev_warn(&pdev->dev, "falling back to hardcoded global registers\n"); + adjust_resource(&fb_res, + (mpp_res->start & INT_REGS_MASK) + GC_REGS_OFFS, 0x14); + gc_base = devm_ioremap_resource(&pdev->dev, &fb_res); + if (IS_ERR(gc_base)) + return PTR_ERR(gc_base); + gconfmap = devm_regmap_init_mmio(&pdev->dev, + gc_base, &gc_regmap_config); + if (IS_ERR(gconfmap)) + return PTR_ERR(gconfmap); + } + + /* Warn on any missing DT resource */ + if (fb_res.start) + dev_warn(&pdev->dev, FW_BUG "Missing pinctrl regs in DTB. Please update your firmware.\n"); + return mvebu_pinctrl_probe(pdev); } |