]> Git Repo - u-boot.git/blobdiff - drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
Merge tag 'v2024.07-rc5' into next
[u-boot.git] / drivers / pinctrl / rockchip / pinctrl-rockchip-core.c
index 386a13ed8761501d4ee7d5b3e861f87bc21782f7..d449d07d32e74d1dec1978b1405bec94887908a2 100644 (file)
@@ -3,19 +3,20 @@
  * (C) Copyright 2019 Rockchip Electronics Co., Ltd
  */
 
-#include <common.h>
 #include <dm.h>
+#include <log.h>
 #include <dm/pinctrl.h>
 #include <regmap.h>
 #include <syscon.h>
 #include <fdtdec.h>
+#include <linux/bitops.h>
 #include <linux/libfdt.h>
 
 #include "pinctrl-rockchip.h"
+#include <dt-bindings/pinctrl/rockchip.h>
 
 #define MAX_ROCKCHIP_PINS_ENTRIES      30
 #define MAX_ROCKCHIP_GPIO_PER_BANK      32
-#define RK_FUNC_GPIO                    0
 
 static int rockchip_verify_config(struct udevice *dev, u32 bank, u32 pin)
 {
@@ -59,8 +60,9 @@ void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int pin,
        *bit = data->bit;
 }
 
-bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin,
-                           int mux, u32 *reg, u32 *value)
+static enum rockchip_pin_route_type
+rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin,
+                      int mux, u32 *reg, u32 *value)
 {
        struct rockchip_pinctrl_priv *priv = bank->priv;
        struct rockchip_pin_ctrl *ctrl = priv->ctrl;
@@ -75,12 +77,12 @@ bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin,
        }
 
        if (i >= ctrl->niomux_routes)
-               return false;
+               return ROUTE_TYPE_INVALID;
 
        *reg = data->route_offset;
        *value = data->route_val;
 
-       return true;
+       return data->route_type;
 }
 
 int rockchip_get_mux_data(int mux_type, int pin, u8 *bit, int *mask)
@@ -129,8 +131,12 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
        if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY)
                return RK_FUNC_GPIO;
 
-       regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
-                               ? priv->regmap_pmu : priv->regmap_base;
+       if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
+               regmap = priv->regmap_pmu;
+       else if (bank->iomux[iomux_num].type & IOMUX_L_SOURCE_PMU)
+               regmap = (pin % 8 < 4) ? priv->regmap_pmu : priv->regmap_base;
+       else
+               regmap = priv->regmap_base;
 
        /* get basic quadrupel of mux registers and the correct reg inside */
        mux_type = bank->iomux[iomux_num].type;
@@ -140,6 +146,28 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
        if (bank->recalced_mask & BIT(pin))
                rockchip_get_recalced_mux(bank, pin, &reg, &bit, &mask);
 
+       if (IS_ENABLED(CONFIG_ROCKCHIP_RK3588)) {
+               if (bank->bank_num == 0) {
+                       if (pin >= RK_PB4 && pin <= RK_PD7) {
+                               u32 reg0 = 0;
+
+                               reg0 = reg + 0x4000 - 0xC; /* PMU2_IOC_BASE */
+                               ret = regmap_read(regmap, reg0, &val);
+                               if (ret)
+                                       return ret;
+
+                               ret = ((val >> bit) & mask);
+                               if (ret != 8)
+                                       return ret;
+
+                               reg = reg + 0x8000; /* BUS_IOC_BASE */
+                               regmap = priv->regmap_base;
+                       }
+               } else if (bank->bank_num > 0) {
+                       reg += 0x8000; /* BUS_IOC_BASE */
+               }
+       }
+
        ret = regmap_read(regmap, reg, &val);
        if (ret)
                return ret;
@@ -169,7 +197,7 @@ static int rockchip_verify_mux(struct rockchip_pin_bank *bank,
        }
 
        if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) {
-               if (mux != IOMUX_GPIO_ONLY) {
+               if (mux != RK_FUNC_GPIO) {
                        debug("pin %d only supports a gpio mux\n", pin);
                        return -ENOTSUPP;
                }
@@ -211,8 +239,40 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
                return -ENOTSUPP;
 
        ret = ctrl->set_mux(bank, pin, mux);
+       if (ret)
+               return ret;
 
-       return ret;
+       if (bank->route_mask & BIT(pin)) {
+               struct regmap *regmap;
+               u32 route_reg = 0, route_val = 0;
+
+               ret = rockchip_get_mux_route(bank, pin, mux,
+                                            &route_reg, &route_val);
+               switch (ret) {
+               case ROUTE_TYPE_DEFAULT:
+                       if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
+                               regmap = priv->regmap_pmu;
+                       else if (bank->iomux[iomux_num].type & IOMUX_L_SOURCE_PMU)
+                               regmap = (pin % 8 < 4) ? priv->regmap_pmu : priv->regmap_base;
+                       else
+                               regmap = priv->regmap_base;
+
+                       regmap_write(regmap, route_reg, route_val);
+                       break;
+               case ROUTE_TYPE_TOPGRF:
+                       regmap_write(priv->regmap_base, route_reg, route_val);
+                       break;
+               case ROUTE_TYPE_PMUGRF:
+                       regmap_write(priv->regmap_pmu, route_reg, route_val);
+                       break;
+               case ROUTE_TYPE_INVALID:
+                       fallthrough;
+               default:
+                       break;
+               }
+       }
+
+       return 0;
 }
 
 static int rockchip_perpin_drv_list[DRV_TYPE_MAX][8] = {
@@ -397,13 +457,7 @@ static int rockchip_pinctrl_set_state(struct udevice *dev,
        int prop_len, param;
        const u32 *data;
        ofnode node;
-#ifdef CONFIG_OF_LIVE
-       const struct device_node *np;
-       struct property *pp;
-#else
-       int property_offset, pcfg_node;
-       const void *blob = gd->fdt_blob;
-#endif
+       struct ofprop prop;
        data = dev_read_prop(config, "rockchip,pins", &count);
        if (count < 0) {
                debug("%s: bad array size %d\n", __func__, count);
@@ -437,24 +491,15 @@ static int rockchip_pinctrl_set_state(struct udevice *dev,
                node = ofnode_get_by_phandle(conf);
                if (!ofnode_valid(node))
                        return -ENODEV;
-#ifdef CONFIG_OF_LIVE
-               np = ofnode_to_np(node);
-               for (pp = np->properties; pp; pp = pp->next) {
-                       prop_name = pp->name;
-                       prop_len = pp->length;
-                       value = pp->value;
-#else
-               pcfg_node = ofnode_to_offset(node);
-               fdt_for_each_property_offset(property_offset, blob, pcfg_node) {
-                       value = fdt_getprop_by_offset(blob, property_offset,
-                                                     &prop_name, &prop_len);
+               ofnode_for_each_prop(prop, node) {
+                       value = ofprop_get_property(&prop, &prop_name, &prop_len);
                        if (!value)
-                               return -ENOENT;
-#endif
+                               continue;
+
                        param = rockchip_pinconf_prop_name_to_param(prop_name,
                                                                    &default_val);
                        if (param < 0)
-                               break;
+                               continue;
 
                        if (prop_len >= sizeof(fdt32_t))
                                arg = fdt32_to_cpu(*(fdt32_t *)value);
@@ -512,12 +557,14 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct udevice *d
 
                        /* preset iomux offset value, set new start value */
                        if (iom->offset >= 0) {
-                               if (iom->type & IOMUX_SOURCE_PMU)
+                               if ((iom->type & IOMUX_SOURCE_PMU) ||
+                                   (iom->type & IOMUX_L_SOURCE_PMU))
                                        pmu_offs = iom->offset;
                                else
                                        grf_offs = iom->offset;
                        } else { /* set current iomux offset */
-                               iom->offset = (iom->type & IOMUX_SOURCE_PMU) ?
+                               iom->offset = ((iom->type & IOMUX_SOURCE_PMU) ||
+                                              (iom->type & IOMUX_L_SOURCE_PMU)) ?
                                                        pmu_offs : grf_offs;
                        }
 
@@ -542,7 +589,7 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct udevice *d
                        inc = (iom->type & (IOMUX_WIDTH_4BIT |
                                            IOMUX_WIDTH_3BIT |
                                            IOMUX_8WIDTH_2BIT)) ? 8 : 4;
-                       if (iom->type & IOMUX_SOURCE_PMU)
+                       if ((iom->type & IOMUX_SOURCE_PMU) || (iom->type & IOMUX_L_SOURCE_PMU))
                                pmu_offs += inc;
                        else
                                grf_offs += inc;
This page took 0.033158 seconds and 4 git commands to generate.