]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
pinctrl: qcom: make compatible with linux DTs
authorCaleb Connolly <caleb.connolly@linaro.org>
Tue, 14 Nov 2023 12:55:42 +0000 (12:55 +0000)
committerCaleb Connolly <caleb.connolly@linaro.org>
Tue, 16 Jan 2024 12:26:52 +0000 (12:26 +0000)
The pinctrl and GPIO drivers are currently heavily incompatible with
upstream. Most Qualcomm pinctrl blocks feature "tiles" of pins, each at
it's own address. Introduce support for these by allowing the soc driver
to specify per-pin register offsets similarly to the Linux driver.

Adjust the GPIO driver to handle these too, and finally enable support
for all pins with the same numbering as used in Linux.

Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
13 files changed:
arch/arm/dts/dragonboard845c-uboot.dtsi
arch/arm/dts/sdm845.dtsi
arch/arm/dts/starqltechn-uboot.dtsi
arch/arm/dts/starqltechn.dts
arch/arm/mach-snapdragon/include/mach/gpio.h
drivers/gpio/msm_gpio.c
drivers/pinctrl/qcom/pinctrl-apq8016.c
drivers/pinctrl/qcom/pinctrl-apq8096.c
drivers/pinctrl/qcom/pinctrl-ipq4019.c
drivers/pinctrl/qcom/pinctrl-qcom.c
drivers/pinctrl/qcom/pinctrl-qcom.h
drivers/pinctrl/qcom/pinctrl-qcs404.c
drivers/pinctrl/qcom/pinctrl-sdm845.c

index 7106db8a73486e95c5f0cc6f2d5f4ad8cf935bce..7728f4f4a3e5a61d27e31b7f77cab1c7750c13a6 100644 (file)
@@ -19,7 +19,7 @@
                        bootph-all;
                };
 
-               pinctrl_north@3900000 {
+               pinctrl@3400000 {
                        bootph-all;
                };
        };
index 3b86b9328fc6dd7062ed4112cf055bb32e20b4c2..4798ace0ff8b11ec5dc836e6fe7f4db051bc958a 100644 (file)
                        #power-domain-cells = <1>;
                };
 
-               gpio_north: gpio_north@3900000 {
-                       #gpio-cells = <2>;
-                       compatible = "qcom,sdm845-pinctrl";
-                       reg = <0x3900000 0x400000>;
-                       gpio-count = <150>;
-                       gpio-controller;
-                       gpio-ranges = <&gpio_north 0 0 150>;
-                       gpio-bank-name = "soc_north.";
-               };
-
-               tlmm_north: pinctrl_north@3900000 {
+               tlmm: pinctrl@3400000 {
                        compatible = "qcom,sdm845-pinctrl";
-                       reg = <0x3900000 0x400000>;
+                       reg = <0x3400000 0xc00000>;
                        gpio-count = <150>;
                        gpio-controller;
                        #gpio-cells = <2>;
-                       gpio-ranges = <&tlmm_north 0 0 150>;
+                       gpio-ranges = <&tlmm 0 0 150>;
 
                        /* DEBUG UART */
                        qup_uart9: qup-uart9-default {
index d81a22ffe49266fc64c3f56518f4b31607dc2b56..034d5c1c07edcba48a7b7c960d380209f7b1b48b 100644 (file)
                clock-controller@100000 {
                        bootph-all;
                };
-               gpio_north@3900000 {
-                       bootph-all;
-               };
-               pinctrl_north@3900000 {
+               pinctrl@3400000 {
                        bootph-all;
                };
        };
index eec51d165f98def58c192c270e2e8fc778aef8f5..5b6372bee79afb991c74e475ea25f9d80ebaf304 100644 (file)
                serial@a84000 {
                        status = "okay";
                };
+       };
+};
 
-               pinctrl_north@3900000 {
-                       muic_i2c: muic_i2c {
-                               pins = "GPIO_33", "GPIO_34";
-                               drive-strength = <0x2>;
-                               function = "gpio";
-                               bias-disable;
-                       };
-               };
+&tlmm {
+       muic_i2c: muic-i2c-n {
+               pins = "GPIO_33", "GPIO_34";
+               drive-strength = <0x2>;
+               function = "gpio";
+               bias-disable;
        };
 };
 
index bbc2bc16175da05492ebdf45c7de841ed1a34312..8dac62f870b9d80968b2ca601e70fdbd7a3974ae 100644 (file)
@@ -1,8 +1,28 @@
 /* SPDX-License-Identifier: GPL-2.0+ */
 /*
- * Empty gpio.h
+ * Qualcomm common pin control data.
  *
- * This file must stay as arch/arm/include/asm/gpio.h requires it.
- *
- * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
+ * Copyright (C) 2023 Linaro Ltd.
  */
+#ifndef _QCOM_GPIO_H_
+#define _QCOM_GPIO_H_
+
+#include <asm/types.h>
+#include <stdbool.h>
+
+struct msm_pin_data {
+       int pin_count;
+       const unsigned int *pin_offsets;
+};
+
+static inline u32 qcom_pin_offset(const unsigned int *offs, unsigned int selector)
+{
+       u32 out = (selector * 0x1000);
+
+       if (offs)
+               return out + offs[selector];
+
+       return out;
+}
+
+#endif /* _QCOM_GPIO_H_ */
index 51670f263716309aacc15623d7bb6f75a36ee228..d9355ed4430c5cbd8ebf7f1e1b81394e051c7a15 100644 (file)
 #include <asm/global_data.h>
 #include <asm/gpio.h>
 #include <asm/io.h>
+#include <mach/gpio.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* Register offsets */
-#define GPIO_CONFIG_OFF(no)         ((no) * 0x1000)
-#define GPIO_IN_OUT_OFF(no)         ((no) * 0x1000 + 0x4)
-
 /* OE */
 #define GPIO_OE_DISABLE  (0x0 << 9)
 #define GPIO_OE_ENABLE   (0x1 << 9)
@@ -29,15 +26,22 @@ DECLARE_GLOBAL_DATA_PTR;
 
 struct msm_gpio_bank {
        phys_addr_t base;
+       const struct msm_pin_data *pin_data;
 };
 
+#define GPIO_CONFIG_REG(dev, x) \
+       (qcom_pin_offset(((struct msm_gpio_bank *)dev_get_priv(dev))->pin_data->pin_offsets, x))
+
+#define GPIO_IN_OUT_REG(dev, x) \
+       (GPIO_CONFIG_REG(dev, x) + 0x4)
+
 static int msm_gpio_direction_input(struct udevice *dev, unsigned int gpio)
 {
        struct msm_gpio_bank *priv = dev_get_priv(dev);
-       phys_addr_t reg = priv->base + GPIO_CONFIG_OFF(gpio);
 
        /* Disable OE bit */
-       clrsetbits_le32(reg, GPIO_OE_MASK, GPIO_OE_DISABLE);
+       clrsetbits_le32(priv->base + GPIO_CONFIG_REG(dev, gpio),
+                       GPIO_OE_MASK, GPIO_OE_DISABLE);
 
        return 0;
 }
@@ -48,7 +52,7 @@ static int msm_gpio_set_value(struct udevice *dev, unsigned gpio, int value)
 
        value = !!value;
        /* set value */
-       writel(value << GPIO_OUT, priv->base + GPIO_IN_OUT_OFF(gpio));
+       writel(value << GPIO_OUT, priv->base + GPIO_IN_OUT_REG(dev, gpio));
 
        return 0;
 }
@@ -57,13 +61,13 @@ static int msm_gpio_direction_output(struct udevice *dev, unsigned gpio,
                                     int value)
 {
        struct msm_gpio_bank *priv = dev_get_priv(dev);
-       phys_addr_t reg = priv->base + GPIO_CONFIG_OFF(gpio);
 
        value = !!value;
        /* set value */
-       writel(value << GPIO_OUT, priv->base + GPIO_IN_OUT_OFF(gpio));
+       writel(value << GPIO_OUT, priv->base + GPIO_IN_OUT_REG(dev, gpio));
        /* switch direction */
-       clrsetbits_le32(reg, GPIO_OE_MASK, GPIO_OE_ENABLE);
+       clrsetbits_le32(priv->base + GPIO_CONFIG_REG(dev, gpio),
+                       GPIO_OE_MASK, GPIO_OE_ENABLE);
 
        return 0;
 }
@@ -72,14 +76,14 @@ static int msm_gpio_get_value(struct udevice *dev, unsigned gpio)
 {
        struct msm_gpio_bank *priv = dev_get_priv(dev);
 
-       return !!(readl(priv->base + GPIO_IN_OUT_OFF(gpio)) >> GPIO_IN);
+       return !!(readl(priv->base + GPIO_IN_OUT_REG(dev, gpio)) >> GPIO_IN);
 }
 
-static int msm_gpio_get_function(struct udevice *dev, unsigned offset)
+static int msm_gpio_get_function(struct udevice *dev, unsigned gpio)
 {
        struct msm_gpio_bank *priv = dev_get_priv(dev);
 
-       if (readl(priv->base + GPIO_CONFIG_OFF(offset)) & GPIO_OE_ENABLE)
+       if (readl(priv->base + GPIO_CONFIG_REG(dev, gpio)) & GPIO_OE_ENABLE)
                return GPIOF_OUTPUT;
 
        return GPIOF_INPUT;
@@ -98,6 +102,7 @@ static int msm_gpio_probe(struct udevice *dev)
        struct msm_gpio_bank *priv = dev_get_priv(dev);
 
        priv->base = dev_read_addr(dev);
+       priv->pin_data = (struct msm_pin_data *)dev_get_driver_data(dev);
 
        return priv->base == FDT_ADDR_T_NONE ? -EINVAL : 0;
 }
@@ -105,9 +110,10 @@ static int msm_gpio_probe(struct udevice *dev)
 static int msm_gpio_of_to_plat(struct udevice *dev)
 {
        struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+       const struct msm_pin_data *pin_data = (struct msm_pin_data *)dev_get_driver_data(dev);
 
-       uc_priv->gpio_count = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
-                                            "gpio-count", 0);
+       /* Get the pin count from the pinctrl driver */
+       uc_priv->gpio_count = pin_data->pin_count;
        uc_priv->bank_name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
                                         "gpio-bank-name", NULL);
        if (uc_priv->bank_name == NULL)
index bcbc0df50715a1df49d7c76c0d73354d5cad622c..8149ffd83cc469e854c02b33339d555e2035d588 100644 (file)
@@ -55,7 +55,7 @@ static unsigned int apq8016_get_function_mux(unsigned int selector)
 }
 
 static const struct msm_pinctrl_data apq8016_data = {
-       .pin_count = 133,
+       .pin_data = { .pin_count = 133, },
        .functions_count = ARRAY_SIZE(msm_pinctrl_functions),
        .get_function_name = apq8016_get_function_name,
        .get_function_mux = apq8016_get_function_mux,
index 5250856176801789bd8cf08b8195fd7a0828b46a..d64ab1ff7bee522d32ebc76cfef69a8848ca93ad 100644 (file)
@@ -50,7 +50,7 @@ static unsigned int apq8096_get_function_mux(unsigned int selector)
 }
 
 static const struct msm_pinctrl_data apq8096_data = {
-       .pin_count = 157,
+       .pin_data = { .pin_count = 157, },
        .functions_count = ARRAY_SIZE(msm_pinctrl_functions),
        .get_function_name = apq8096_get_function_name,
        .get_function_mux = apq8096_get_function_mux,
index 87058e21ce8092985008ed3ff136c334ebcd16d5..2d99f99e1e4560e21d62e5caf0b4955eb6eba8a2 100644 (file)
@@ -46,7 +46,7 @@ static unsigned int ipq4019_get_function_mux(unsigned int selector)
 }
 
 static const struct msm_pinctrl_data ipq4019_data = {
-       .pin_count = 100,
+       .pin_data = { .pin_count = 100, },
        .functions_count = ARRAY_SIZE(msm_pinctrl_functions),
        .get_function_name = ipq4019_get_function_name,
        .get_function_mux = ipq4019_get_function_mux,
index 1cface7f610bdc34baa09a8c892bf96f002125b3..dc3d8c4d90347d264a67c0e30d9fc2cb3a0d9799 100644 (file)
 #include <dm/device_compat.h>
 #include <dm/device-internal.h>
 #include <dm/lists.h>
+#include <asm/gpio.h>
 #include <dm/pinctrl.h>
 #include <linux/bitops.h>
+#include <mach/gpio.h>
+
 #include "pinctrl-qcom.h"
 
 struct msm_pinctrl_priv {
@@ -22,7 +25,9 @@ struct msm_pinctrl_priv {
        struct msm_pinctrl_data *data;
 };
 
-#define GPIO_CONFIG_OFFSET(x)         ((x) * 0x1000)
+#define GPIO_CONFIG_REG(priv, x) \
+       (qcom_pin_offset((priv)->data->pin_data.pin_offsets, x))
+
 #define TLMM_GPIO_PULL_MASK GENMASK(1, 0)
 #define TLMM_FUNC_SEL_MASK GENMASK(5, 2)
 #define TLMM_DRV_STRENGTH_MASK GENMASK(8, 6)
@@ -45,7 +50,7 @@ static int msm_get_pins_count(struct udevice *dev)
 {
        struct msm_pinctrl_priv *priv = dev_get_priv(dev);
 
-       return priv->data->pin_count;
+       return priv->data->pin_data.pin_count;
 }
 
 static const char *msm_get_function_name(struct udevice *dev,
@@ -61,7 +66,7 @@ static int msm_pinctrl_probe(struct udevice *dev)
        struct msm_pinctrl_priv *priv = dev_get_priv(dev);
 
        priv->base = dev_read_addr(dev);
-       priv->data = (struct msm_pinctrl_data *)dev->driver_data;
+       priv->data = (struct msm_pinctrl_data *)dev_get_driver_data(dev);
 
        return priv->base == FDT_ADDR_T_NONE ? -EINVAL : 0;
 }
@@ -78,7 +83,7 @@ static int msm_pinmux_set(struct udevice *dev, unsigned int pin_selector,
 {
        struct msm_pinctrl_priv *priv = dev_get_priv(dev);
 
-       clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
+       clrsetbits_le32(priv->base + GPIO_CONFIG_REG(priv, pin_selector),
                        TLMM_FUNC_SEL_MASK | TLMM_GPIO_DISABLE,
                        priv->data->get_function_mux(func_selector) << 2);
        return 0;
@@ -92,15 +97,15 @@ static int msm_pinconf_set(struct udevice *dev, unsigned int pin_selector,
        switch (param) {
        case PIN_CONFIG_DRIVE_STRENGTH:
                argument = (argument / 2) - 1;
-               clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
+               clrsetbits_le32(priv->base + GPIO_CONFIG_REG(priv, pin_selector),
                                TLMM_DRV_STRENGTH_MASK, argument << 6);
                break;
        case PIN_CONFIG_BIAS_DISABLE:
-               clrbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
+               clrbits_le32(priv->base + GPIO_CONFIG_REG(priv, pin_selector),
                             TLMM_GPIO_PULL_MASK);
                break;
        case PIN_CONFIG_BIAS_PULL_UP:
-               clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
+               clrsetbits_le32(priv->base + GPIO_CONFIG_REG(priv, pin_selector),
                                TLMM_GPIO_PULL_MASK, argument);
                break;
        default:
@@ -149,9 +154,15 @@ int msm_pinctrl_bind(struct udevice *dev)
        if (!name)
                return -EINVAL;
 
-       /* Bind gpio node */
-       ret = device_bind_driver_to_node(dev, "gpio_msm",
-                                        name, node, NULL);
+       drv = lists_driver_lookup_name("gpio_msm");
+       if (!drv) {
+               printf("Can't find gpio_msm driver\n");
+               return -ENODEV;
+       }
+
+       /* Bind gpio device as a child of the pinctrl device */
+       ret = device_bind_with_driver_data(pinctrl_dev, drv,
+                                          name, (ulong)&data->pin_data, node, NULL);
        if (ret) {
                device_unbind(pinctrl_dev);
                return ret;
index 1edd9a43ffdadbea82e9213d651aca19a4cafbfd..07f2eae9baeadfd996ab40e021f3ad7da4ecd380 100644 (file)
@@ -8,10 +8,13 @@
 #ifndef _PINCTRL_QCOM_H
 #define _PINCTRL_QCOM_H
 
+#include <asm/types.h>
+#include <mach/gpio.h>
+
 struct udevice;
 
 struct msm_pinctrl_data {
-       int pin_count;
+       struct msm_pin_data pin_data;
        int functions_count;
        const char *(*get_function_name)(struct udevice *dev,
                                         unsigned int selector);
index 272331c90b5c59fe32df5c39cf37d7306a89f661..ac00afa2a1f4e65491e0555b8032ad7a26ac4273 100644 (file)
@@ -62,7 +62,7 @@ static unsigned int qcs404_get_function_mux(unsigned int selector)
 }
 
 static struct msm_pinctrl_data qcs404_data = {
-       .pin_count = 126,
+       .pin_data = { .pin_count = 126, },
        .functions_count = ARRAY_SIZE(msm_pinctrl_functions),
        .get_function_name = qcs404_get_function_name,
        .get_function_mux = qcs404_get_function_mux,
index 1a09c5c81dc6b50ed58d3dc40109e15e22f2f0e3..9f0f4085ce2da59c6496858bc1a79bdc18fd96a7 100644 (file)
@@ -3,6 +3,7 @@
  * Qualcomm SDM845 pinctrl
  *
  * (C) Copyright 2021 Dzmitry Sankouski <dsankouski@gmail.com>
+ * (C) Copyright 2023 Linaro Ltd.
  *
  */
 
 
 #include "pinctrl-qcom.h"
 
+#define NORTH  0x00500000
+#define SOUTH  0x00900000
+#define EAST   0x00100000
+
 #define MAX_PIN_NAME_LEN 32
 static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
 
@@ -19,6 +24,39 @@ static const struct pinctrl_function msm_pinctrl_functions[] = {
        {"gpio", 0},
 };
 
+static const unsigned int sdm845_pin_offsets[] = {
+       [0] = EAST,    [1] = EAST,    [2] = EAST,    [3] = EAST,    [4] = NORTH,
+       [5] = NORTH,   [6] = NORTH,   [7] = NORTH,   [8] = EAST,    [9] = EAST,
+       [10] = EAST,   [11] = EAST,   [12] = SOUTH,  [13] = SOUTH,  [14] = SOUTH,
+       [15] = SOUTH,  [16] = SOUTH,  [17] = SOUTH,  [18] = SOUTH,  [19] = SOUTH,
+       [20] = SOUTH,  [21] = SOUTH,  [22] = SOUTH,  [23] = SOUTH,  [24] = SOUTH,
+       [25] = SOUTH,  [26] = SOUTH,  [27] = EAST,   [28] = EAST,   [29] = EAST,
+       [30] = EAST,   [31] = NORTH,  [32] = NORTH,  [33] = NORTH,  [34] = NORTH,
+       [35] = SOUTH,  [36] = SOUTH,  [37] = SOUTH,  [38] = NORTH,  [39] = EAST,
+       [40] = SOUTH,  [41] = EAST,   [42] = EAST,   [43] = EAST,   [44] = EAST,
+       [45] = EAST,   [46] = EAST,   [47] = EAST,   [48] = EAST,   [49] = NORTH,
+       [50] = NORTH,  [51] = NORTH,  [52] = NORTH,  [53] = NORTH,  [54] = NORTH,
+       [55] = NORTH,  [56] = NORTH,  [57] = NORTH,  [58] = NORTH,  [59] = NORTH,
+       [60] = NORTH,  [61] = NORTH,  [62] = NORTH,  [63] = NORTH,  [64] = NORTH,
+       [65] = NORTH,  [66] = NORTH,  [67] = NORTH,  [68] = NORTH,  [69] = EAST,
+       [70] = EAST,   [71] = EAST,   [72] = EAST,   [73] = EAST,   [74] = EAST,
+       [75] = EAST,   [76] = EAST,   [77] = EAST,   [78] = EAST,   [79] = NORTH,
+       [80] = NORTH,  [81] = NORTH,  [82] = NORTH,  [83] = NORTH,  [84] = NORTH,
+       [85] = EAST,   [86] = EAST,   [87] = EAST,   [88] = EAST,   [89] = SOUTH,
+       [90] = SOUTH,  [91] = SOUTH,  [92] = SOUTH,  [93] = SOUTH,  [94] = SOUTH,
+       [95] = SOUTH,  [96] = SOUTH,  [97] = NORTH,  [98] = NORTH,  [99] = NORTH,
+       [100] = NORTH, [101] = NORTH, [102] = NORTH, [103] = NORTH, [104] = NORTH,
+       [105] = NORTH, [106] = NORTH, [107] = NORTH, [108] = NORTH, [109] = NORTH,
+       [110] = NORTH, [111] = NORTH, [112] = NORTH, [113] = NORTH, [114] = NORTH,
+       [115] = NORTH, [116] = NORTH, [117] = NORTH, [118] = NORTH, [119] = NORTH,
+       [120] = NORTH, [121] = NORTH, [122] = EAST,  [123] = EAST,  [124] = EAST,
+       [125] = EAST,  [126] = EAST,  [127] = NORTH, [128] = NORTH, [129] = NORTH,
+       [130] = NORTH, [131] = NORTH, [132] = NORTH, [133] = NORTH, [134] = NORTH,
+       [135] = NORTH, [136] = NORTH, [137] = NORTH, [138] = NORTH, [139] = NORTH,
+       [140] = NORTH, [141] = NORTH, [142] = NORTH, [143] = NORTH, [144] = NORTH,
+       [145] = NORTH, [146] = NORTH, [147] = NORTH, [148] = NORTH, [149] = NORTH,
+};
+
 static const char *sdm845_get_function_name(struct udevice *dev,
                                             unsigned int selector)
 {
@@ -28,7 +66,7 @@ static const char *sdm845_get_function_name(struct udevice *dev,
 static const char *sdm845_get_pin_name(struct udevice *dev,
                                        unsigned int selector)
 {
-       snprintf(pin_name, MAX_PIN_NAME_LEN, "GPIO_%u", selector);
+       snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector);
        return pin_name;
 }
 
@@ -38,7 +76,10 @@ static unsigned int sdm845_get_function_mux(unsigned int selector)
 }
 
 static struct msm_pinctrl_data sdm845_data = {
-       .pin_count = 150,
+       .pin_data = {
+               .pin_offsets = sdm845_pin_offsets,
+               .pin_count = ARRAY_SIZE(sdm845_pin_offsets),
+       },
        .functions_count = ARRAY_SIZE(msm_pinctrl_functions),
        .get_function_name = sdm845_get_function_name,
        .get_function_mux = sdm845_get_function_mux,