bootph-all;
};
- pinctrl_north@3900000 {
+ pinctrl@3400000 {
bootph-all;
};
};
#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 {
clock-controller@100000 {
bootph-all;
};
- gpio_north@3900000 {
- bootph-all;
- };
- pinctrl_north@3900000 {
+ pinctrl@3400000 {
bootph-all;
};
};
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;
};
};
/* 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_ */
#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)
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;
}
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;
}
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;
}
{
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;
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;
}
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)
}
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,
}
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,
}
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,
#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 {
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)
{
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,
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;
}
{
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;
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:
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;
#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);
}
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,
* 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");
{"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)
{
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;
}
}
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,