15dc626f8SMasahiro Yamada /* 25dc626f8SMasahiro Yamada * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> 35dc626f8SMasahiro Yamada * 45dc626f8SMasahiro Yamada * SPDX-License-Identifier: GPL-2.0+ 55dc626f8SMasahiro Yamada */ 65dc626f8SMasahiro Yamada 75dc626f8SMasahiro Yamada #include <common.h> 85dc626f8SMasahiro Yamada #include <mapmem.h> 95dc626f8SMasahiro Yamada #include <linux/io.h> 105dc626f8SMasahiro Yamada #include <linux/err.h> 11510454dbSMasahiro Yamada #include <linux/sizes.h> 125dc626f8SMasahiro Yamada #include <dm/device.h> 135dc626f8SMasahiro Yamada #include <dm/pinctrl.h> 145dc626f8SMasahiro Yamada 155dc626f8SMasahiro Yamada #include "pinctrl-uniphier.h" 165dc626f8SMasahiro Yamada 175dc626f8SMasahiro Yamada static int uniphier_pinctrl_get_groups_count(struct udevice *dev) 185dc626f8SMasahiro Yamada { 195dc626f8SMasahiro Yamada struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 205dc626f8SMasahiro Yamada 215dc626f8SMasahiro Yamada return priv->socdata->groups_count; 225dc626f8SMasahiro Yamada } 235dc626f8SMasahiro Yamada 245dc626f8SMasahiro Yamada static const char *uniphier_pinctrl_get_group_name(struct udevice *dev, 255dc626f8SMasahiro Yamada unsigned selector) 265dc626f8SMasahiro Yamada { 275dc626f8SMasahiro Yamada struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 285dc626f8SMasahiro Yamada 295dc626f8SMasahiro Yamada return priv->socdata->groups[selector].name; 305dc626f8SMasahiro Yamada } 315dc626f8SMasahiro Yamada 325dc626f8SMasahiro Yamada static int uniphier_pinmux_get_functions_count(struct udevice *dev) 335dc626f8SMasahiro Yamada { 345dc626f8SMasahiro Yamada struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 355dc626f8SMasahiro Yamada 365dc626f8SMasahiro Yamada return priv->socdata->functions_count; 375dc626f8SMasahiro Yamada } 385dc626f8SMasahiro Yamada 395dc626f8SMasahiro Yamada static const char *uniphier_pinmux_get_function_name(struct udevice *dev, 405dc626f8SMasahiro Yamada unsigned selector) 415dc626f8SMasahiro Yamada { 425dc626f8SMasahiro Yamada struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 435dc626f8SMasahiro Yamada 445dc626f8SMasahiro Yamada return priv->socdata->functions[selector]; 455dc626f8SMasahiro Yamada } 465dc626f8SMasahiro Yamada 47*3b05b5f0SMasahiro Yamada static void uniphier_pinconf_input_enable_perpin(struct udevice *dev, 48*3b05b5f0SMasahiro Yamada unsigned pin) 49*3b05b5f0SMasahiro Yamada { 50*3b05b5f0SMasahiro Yamada struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 51*3b05b5f0SMasahiro Yamada unsigned reg; 52*3b05b5f0SMasahiro Yamada u32 mask, tmp; 53*3b05b5f0SMasahiro Yamada 54*3b05b5f0SMasahiro Yamada reg = UNIPHIER_PINCTRL_IECTRL + pin / 32 * 4; 55*3b05b5f0SMasahiro Yamada mask = BIT(pin % 32); 56*3b05b5f0SMasahiro Yamada 57*3b05b5f0SMasahiro Yamada tmp = readl(priv->base + reg); 58*3b05b5f0SMasahiro Yamada tmp |= mask; 59*3b05b5f0SMasahiro Yamada writel(tmp, priv->base + reg); 60*3b05b5f0SMasahiro Yamada } 61*3b05b5f0SMasahiro Yamada 62*3b05b5f0SMasahiro Yamada static void uniphier_pinconf_input_enable_legacy(struct udevice *dev, 63*3b05b5f0SMasahiro Yamada unsigned pin) 645dc626f8SMasahiro Yamada { 655dc626f8SMasahiro Yamada struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 665dc626f8SMasahiro Yamada int pins_count = priv->socdata->pins_count; 675dc626f8SMasahiro Yamada const struct uniphier_pinctrl_pin *pins = priv->socdata->pins; 685dc626f8SMasahiro Yamada int i; 695dc626f8SMasahiro Yamada 705dc626f8SMasahiro Yamada for (i = 0; i < pins_count; i++) { 715dc626f8SMasahiro Yamada if (pins[i].number == pin) { 725dc626f8SMasahiro Yamada unsigned int iectrl; 735dc626f8SMasahiro Yamada u32 tmp; 745dc626f8SMasahiro Yamada 755dc626f8SMasahiro Yamada iectrl = uniphier_pin_get_iectrl(pins[i].data); 765dc626f8SMasahiro Yamada tmp = readl(priv->base + UNIPHIER_PINCTRL_IECTRL); 775dc626f8SMasahiro Yamada tmp |= 1 << iectrl; 785dc626f8SMasahiro Yamada writel(tmp, priv->base + UNIPHIER_PINCTRL_IECTRL); 795dc626f8SMasahiro Yamada } 805dc626f8SMasahiro Yamada } 815dc626f8SMasahiro Yamada } 825dc626f8SMasahiro Yamada 83*3b05b5f0SMasahiro Yamada static void uniphier_pinconf_input_enable(struct udevice *dev, unsigned pin) 84*3b05b5f0SMasahiro Yamada { 85*3b05b5f0SMasahiro Yamada struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 86*3b05b5f0SMasahiro Yamada 87*3b05b5f0SMasahiro Yamada if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL) 88*3b05b5f0SMasahiro Yamada uniphier_pinconf_input_enable_perpin(dev, pin); 89*3b05b5f0SMasahiro Yamada else 90*3b05b5f0SMasahiro Yamada uniphier_pinconf_input_enable_legacy(dev, pin); 91*3b05b5f0SMasahiro Yamada } 92*3b05b5f0SMasahiro Yamada 935dc626f8SMasahiro Yamada static void uniphier_pinmux_set_one(struct udevice *dev, unsigned pin, 945dc626f8SMasahiro Yamada unsigned muxval) 955dc626f8SMasahiro Yamada { 965dc626f8SMasahiro Yamada struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 978cc92b99SMasahiro Yamada unsigned mux_bits, reg_stride, reg, reg_end, shift, mask; 988cc92b99SMasahiro Yamada bool load_pinctrl; 995dc626f8SMasahiro Yamada u32 tmp; 1005dc626f8SMasahiro Yamada 101fdd15b6aSMasahiro Yamada /* some pins need input-enabling */ 102fdd15b6aSMasahiro Yamada uniphier_pinconf_input_enable(dev, pin); 103fdd15b6aSMasahiro Yamada 1048cc92b99SMasahiro Yamada if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_DBGMUX_SEPARATE) { 1058cc92b99SMasahiro Yamada /* 1068cc92b99SMasahiro Yamada * Mode offset bit 1078cc92b99SMasahiro Yamada * Normal 4 * n shift+3:shift 1088cc92b99SMasahiro Yamada * Debug 4 * n shift+7:shift+4 1098cc92b99SMasahiro Yamada */ 1108cc92b99SMasahiro Yamada mux_bits = 4; 1118cc92b99SMasahiro Yamada reg_stride = 8; 1128cc92b99SMasahiro Yamada load_pinctrl = true; 1138cc92b99SMasahiro Yamada } else { 1148cc92b99SMasahiro Yamada /* 1158cc92b99SMasahiro Yamada * Mode offset bit 1168cc92b99SMasahiro Yamada * Normal 8 * n shift+3:shift 1178cc92b99SMasahiro Yamada * Debug 8 * n + 4 shift+3:shift 1188cc92b99SMasahiro Yamada */ 1198cc92b99SMasahiro Yamada mux_bits = 8; 1208cc92b99SMasahiro Yamada reg_stride = 4; 1218cc92b99SMasahiro Yamada load_pinctrl = false; 1228cc92b99SMasahiro Yamada } 1238cc92b99SMasahiro Yamada 1245dc626f8SMasahiro Yamada reg = UNIPHIER_PINCTRL_PINMUX_BASE + pin * mux_bits / 32 * reg_stride; 1255dc626f8SMasahiro Yamada reg_end = reg + reg_stride; 1265dc626f8SMasahiro Yamada shift = pin * mux_bits % 32; 1275dc626f8SMasahiro Yamada mask = (1U << mux_bits) - 1; 1285dc626f8SMasahiro Yamada 1295dc626f8SMasahiro Yamada /* 1305dc626f8SMasahiro Yamada * If reg_stride is greater than 4, the MSB of each pinsel shall be 1315dc626f8SMasahiro Yamada * stored in the offset+4. 1325dc626f8SMasahiro Yamada */ 1335dc626f8SMasahiro Yamada for (; reg < reg_end; reg += 4) { 1345dc626f8SMasahiro Yamada tmp = readl(priv->base + reg); 1355dc626f8SMasahiro Yamada tmp &= ~(mask << shift); 1365dc626f8SMasahiro Yamada tmp |= (mask & muxval) << shift; 1375dc626f8SMasahiro Yamada writel(tmp, priv->base + reg); 1385dc626f8SMasahiro Yamada 1395dc626f8SMasahiro Yamada muxval >>= mux_bits; 1405dc626f8SMasahiro Yamada } 1415dc626f8SMasahiro Yamada 1428cc92b99SMasahiro Yamada if (load_pinctrl) 1435dc626f8SMasahiro Yamada writel(1, priv->base + UNIPHIER_PINCTRL_LOAD_PINMUX); 1445dc626f8SMasahiro Yamada } 1455dc626f8SMasahiro Yamada 1465dc626f8SMasahiro Yamada static int uniphier_pinmux_group_set(struct udevice *dev, 1475dc626f8SMasahiro Yamada unsigned group_selector, 1485dc626f8SMasahiro Yamada unsigned func_selector) 1495dc626f8SMasahiro Yamada { 1505dc626f8SMasahiro Yamada struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 1515dc626f8SMasahiro Yamada const struct uniphier_pinctrl_group *grp = 1525dc626f8SMasahiro Yamada &priv->socdata->groups[group_selector]; 1535dc626f8SMasahiro Yamada int i; 1545dc626f8SMasahiro Yamada 1555dc626f8SMasahiro Yamada for (i = 0; i < grp->num_pins; i++) 1565dc626f8SMasahiro Yamada uniphier_pinmux_set_one(dev, grp->pins[i], grp->muxvals[i]); 1575dc626f8SMasahiro Yamada 1585dc626f8SMasahiro Yamada return 0; 1595dc626f8SMasahiro Yamada } 1605dc626f8SMasahiro Yamada 1615dc626f8SMasahiro Yamada const struct pinctrl_ops uniphier_pinctrl_ops = { 1625dc626f8SMasahiro Yamada .get_groups_count = uniphier_pinctrl_get_groups_count, 1635dc626f8SMasahiro Yamada .get_group_name = uniphier_pinctrl_get_group_name, 1645dc626f8SMasahiro Yamada .get_functions_count = uniphier_pinmux_get_functions_count, 1655dc626f8SMasahiro Yamada .get_function_name = uniphier_pinmux_get_function_name, 1665dc626f8SMasahiro Yamada .pinmux_group_set = uniphier_pinmux_group_set, 1675dc626f8SMasahiro Yamada .set_state = pinctrl_generic_set_state, 1685dc626f8SMasahiro Yamada }; 1695dc626f8SMasahiro Yamada 1705dc626f8SMasahiro Yamada int uniphier_pinctrl_probe(struct udevice *dev, 1715dc626f8SMasahiro Yamada struct uniphier_pinctrl_socdata *socdata) 1725dc626f8SMasahiro Yamada { 1735dc626f8SMasahiro Yamada struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 1745dc626f8SMasahiro Yamada fdt_addr_t addr; 1755dc626f8SMasahiro Yamada 176510454dbSMasahiro Yamada addr = dev_get_addr(dev); 1775dc626f8SMasahiro Yamada if (addr == FDT_ADDR_T_NONE) 1785dc626f8SMasahiro Yamada return -EINVAL; 1795dc626f8SMasahiro Yamada 180510454dbSMasahiro Yamada priv->base = map_sysmem(addr, SZ_4K); 1815dc626f8SMasahiro Yamada if (!priv->base) 1825dc626f8SMasahiro Yamada return -ENOMEM; 1835dc626f8SMasahiro Yamada 1845dc626f8SMasahiro Yamada priv->socdata = socdata; 1855dc626f8SMasahiro Yamada 1865dc626f8SMasahiro Yamada return 0; 1875dc626f8SMasahiro Yamada } 1885dc626f8SMasahiro Yamada 1895dc626f8SMasahiro Yamada int uniphier_pinctrl_remove(struct udevice *dev) 1905dc626f8SMasahiro Yamada { 1915dc626f8SMasahiro Yamada struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); 1925dc626f8SMasahiro Yamada 1935dc626f8SMasahiro Yamada unmap_sysmem(priv->base); 1945dc626f8SMasahiro Yamada 1955dc626f8SMasahiro Yamada return 0; 1965dc626f8SMasahiro Yamada } 197