mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2025-09-22 06:11:36 +02:00
pinctrl: qcom: stub support for special GPIOs
Most platforms have a handful of "special" GPIOs, like the MMC clock/data lanes, UFS reset, etc. These don't follow the usual naming scheme of "gpioX" and also have unique capabilities and registers. We can get away without supporting them all for now, but DT compatibility is still an issue. Add support for allowing these to be specified after the other pins, and make all pinmux/pinconf calls for them nop. Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Reviewed-by: Sumit Garg <sumit.garg@linaro.org> Tested-by: Sumit Garg <sumit.garg@linaro.org> #qcs404 Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
This commit is contained in:
parent
cc18d5486b
commit
a245aece2a
@ -13,6 +13,8 @@
|
|||||||
struct msm_pin_data {
|
struct msm_pin_data {
|
||||||
int pin_count;
|
int pin_count;
|
||||||
const unsigned int *pin_offsets;
|
const unsigned int *pin_offsets;
|
||||||
|
/* Index of first special pin, these are ignored for now */
|
||||||
|
unsigned int special_pins_start;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline u32 qcom_pin_offset(const unsigned int *offs, unsigned int selector)
|
static inline u32 qcom_pin_offset(const unsigned int *offs, unsigned int selector)
|
||||||
@ -25,4 +27,9 @@ static inline u32 qcom_pin_offset(const unsigned int *offs, unsigned int selecto
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool qcom_is_special_pin(const struct msm_pin_data *pindata, unsigned int pin)
|
||||||
|
{
|
||||||
|
return pindata->special_pins_start && pin >= pindata->special_pins_start;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _QCOM_GPIO_H_ */
|
#endif /* _QCOM_GPIO_H_ */
|
||||||
|
@ -39,6 +39,10 @@ static int msm_gpio_direction_input(struct udevice *dev, unsigned int gpio)
|
|||||||
{
|
{
|
||||||
struct msm_gpio_bank *priv = dev_get_priv(dev);
|
struct msm_gpio_bank *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
/* Always NOP for special pins, assume they're in the correct state */
|
||||||
|
if (qcom_is_special_pin(priv->pin_data, gpio))
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* Disable OE bit */
|
/* Disable OE bit */
|
||||||
clrsetbits_le32(priv->base + GPIO_CONFIG_REG(dev, gpio),
|
clrsetbits_le32(priv->base + GPIO_CONFIG_REG(dev, gpio),
|
||||||
GPIO_OE_MASK, GPIO_OE_DISABLE);
|
GPIO_OE_MASK, GPIO_OE_DISABLE);
|
||||||
@ -50,6 +54,10 @@ static int msm_gpio_set_value(struct udevice *dev, unsigned int gpio, int value)
|
|||||||
{
|
{
|
||||||
struct msm_gpio_bank *priv = dev_get_priv(dev);
|
struct msm_gpio_bank *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
/* Always NOP for special pins, assume they're in the correct state */
|
||||||
|
if (qcom_is_special_pin(priv->pin_data, gpio))
|
||||||
|
return 0;
|
||||||
|
|
||||||
value = !!value;
|
value = !!value;
|
||||||
/* set value */
|
/* set value */
|
||||||
writel(value << GPIO_OUT, priv->base + GPIO_IN_OUT_REG(dev, gpio));
|
writel(value << GPIO_OUT, priv->base + GPIO_IN_OUT_REG(dev, gpio));
|
||||||
@ -62,6 +70,10 @@ static int msm_gpio_direction_output(struct udevice *dev, unsigned int gpio,
|
|||||||
{
|
{
|
||||||
struct msm_gpio_bank *priv = dev_get_priv(dev);
|
struct msm_gpio_bank *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
/* Always NOP for special pins, assume they're in the correct state */
|
||||||
|
if (qcom_is_special_pin(priv->pin_data, gpio))
|
||||||
|
return 0;
|
||||||
|
|
||||||
value = !!value;
|
value = !!value;
|
||||||
/* set value */
|
/* set value */
|
||||||
writel(value << GPIO_OUT, priv->base + GPIO_IN_OUT_REG(dev, gpio));
|
writel(value << GPIO_OUT, priv->base + GPIO_IN_OUT_REG(dev, gpio));
|
||||||
@ -76,6 +88,10 @@ static int msm_gpio_get_value(struct udevice *dev, unsigned int gpio)
|
|||||||
{
|
{
|
||||||
struct msm_gpio_bank *priv = dev_get_priv(dev);
|
struct msm_gpio_bank *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
/* Always NOP for special pins, assume they're in the correct state */
|
||||||
|
if (qcom_is_special_pin(priv->pin_data, gpio))
|
||||||
|
return 0;
|
||||||
|
|
||||||
return !!(readl(priv->base + GPIO_IN_OUT_REG(dev, gpio)) >> GPIO_IN);
|
return !!(readl(priv->base + GPIO_IN_OUT_REG(dev, gpio)) >> GPIO_IN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,6 +99,10 @@ static int msm_gpio_get_function(struct udevice *dev, unsigned int gpio)
|
|||||||
{
|
{
|
||||||
struct msm_gpio_bank *priv = dev_get_priv(dev);
|
struct msm_gpio_bank *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
/* Always NOP for special pins, assume they're in the correct state */
|
||||||
|
if (qcom_is_special_pin(priv->pin_data, gpio))
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (readl(priv->base + GPIO_CONFIG_REG(dev, gpio)) & GPIO_OE_ENABLE)
|
if (readl(priv->base + GPIO_CONFIG_REG(dev, gpio)) & GPIO_OE_ENABLE)
|
||||||
return GPIOF_OUTPUT;
|
return GPIOF_OUTPUT;
|
||||||
|
|
||||||
|
@ -55,7 +55,10 @@ static unsigned int apq8016_get_function_mux(unsigned int selector)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const struct msm_pinctrl_data apq8016_data = {
|
static const struct msm_pinctrl_data apq8016_data = {
|
||||||
.pin_data = { .pin_count = 133, },
|
.pin_data = {
|
||||||
|
.pin_count = 133,
|
||||||
|
.special_pins_start = 122,
|
||||||
|
},
|
||||||
.functions_count = ARRAY_SIZE(msm_pinctrl_functions),
|
.functions_count = ARRAY_SIZE(msm_pinctrl_functions),
|
||||||
.get_function_name = apq8016_get_function_name,
|
.get_function_name = apq8016_get_function_name,
|
||||||
.get_function_mux = apq8016_get_function_mux,
|
.get_function_mux = apq8016_get_function_mux,
|
||||||
|
@ -50,7 +50,10 @@ static unsigned int apq8096_get_function_mux(unsigned int selector)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const struct msm_pinctrl_data apq8096_data = {
|
static const struct msm_pinctrl_data apq8096_data = {
|
||||||
.pin_data = { .pin_count = 157, },
|
.pin_data = {
|
||||||
|
.pin_count = 157,
|
||||||
|
.special_pins_start = 150,
|
||||||
|
},
|
||||||
.functions_count = ARRAY_SIZE(msm_pinctrl_functions),
|
.functions_count = ARRAY_SIZE(msm_pinctrl_functions),
|
||||||
.get_function_name = apq8096_get_function_name,
|
.get_function_name = apq8096_get_function_name,
|
||||||
.get_function_mux = apq8096_get_function_mux,
|
.get_function_mux = apq8096_get_function_mux,
|
||||||
|
@ -46,7 +46,10 @@ static unsigned int ipq4019_get_function_mux(unsigned int selector)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const struct msm_pinctrl_data ipq4019_data = {
|
static const struct msm_pinctrl_data ipq4019_data = {
|
||||||
.pin_data = { .pin_count = 100, },
|
.pin_data = {
|
||||||
|
.pin_count = 100,
|
||||||
|
.special_pins_start = 100, /* There are no special pins */
|
||||||
|
},
|
||||||
.functions_count = ARRAY_SIZE(msm_pinctrl_functions),
|
.functions_count = ARRAY_SIZE(msm_pinctrl_functions),
|
||||||
.get_function_name = ipq4019_get_function_name,
|
.get_function_name = ipq4019_get_function_name,
|
||||||
.get_function_mux = ipq4019_get_function_mux,
|
.get_function_mux = ipq4019_get_function_mux,
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include <asm/gpio.h>
|
#include <asm/gpio.h>
|
||||||
#include <dm/pinctrl.h>
|
#include <dm/pinctrl.h>
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
|
#include <linux/bug.h>
|
||||||
#include <mach/gpio.h>
|
#include <mach/gpio.h>
|
||||||
|
|
||||||
#include "pinctrl-qcom.h"
|
#include "pinctrl-qcom.h"
|
||||||
@ -83,6 +84,10 @@ static int msm_pinmux_set(struct udevice *dev, unsigned int pin_selector,
|
|||||||
{
|
{
|
||||||
struct msm_pinctrl_priv *priv = dev_get_priv(dev);
|
struct msm_pinctrl_priv *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
/* Always NOP for special pins, assume they're in the correct state */
|
||||||
|
if (qcom_is_special_pin(&priv->data->pin_data, pin_selector))
|
||||||
|
return 0;
|
||||||
|
|
||||||
clrsetbits_le32(priv->base + GPIO_CONFIG_REG(priv, pin_selector),
|
clrsetbits_le32(priv->base + GPIO_CONFIG_REG(priv, pin_selector),
|
||||||
TLMM_FUNC_SEL_MASK | TLMM_GPIO_DISABLE,
|
TLMM_FUNC_SEL_MASK | TLMM_GPIO_DISABLE,
|
||||||
priv->data->get_function_mux(func_selector) << 2);
|
priv->data->get_function_mux(func_selector) << 2);
|
||||||
@ -94,6 +99,10 @@ static int msm_pinconf_set(struct udevice *dev, unsigned int pin_selector,
|
|||||||
{
|
{
|
||||||
struct msm_pinctrl_priv *priv = dev_get_priv(dev);
|
struct msm_pinctrl_priv *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
/* Always NOP for special pins */
|
||||||
|
if (qcom_is_special_pin(&priv->data->pin_data, pin_selector))
|
||||||
|
return 0;
|
||||||
|
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case PIN_CONFIG_DRIVE_STRENGTH:
|
case PIN_CONFIG_DRIVE_STRENGTH:
|
||||||
argument = (argument / 2) - 1;
|
argument = (argument / 2) - 1;
|
||||||
@ -136,6 +145,9 @@ int msm_pinctrl_bind(struct udevice *dev)
|
|||||||
const char *name;
|
const char *name;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (!data->pin_data.special_pins_start)
|
||||||
|
dev_warn(dev, "Special pins start index not defined!\n");
|
||||||
|
|
||||||
drv = lists_driver_lookup_name("pinctrl_qcom");
|
drv = lists_driver_lookup_name("pinctrl_qcom");
|
||||||
if (!drv)
|
if (!drv)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
@ -61,8 +61,11 @@ static unsigned int qcs404_get_function_mux(unsigned int selector)
|
|||||||
return msm_pinctrl_functions[selector].val;
|
return msm_pinctrl_functions[selector].val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct msm_pinctrl_data qcs404_data = {
|
static const struct msm_pinctrl_data qcs404_data = {
|
||||||
.pin_data = { .pin_count = 126, },
|
.pin_data = {
|
||||||
|
.pin_count = 126,
|
||||||
|
.special_pins_start = 120,
|
||||||
|
},
|
||||||
.functions_count = ARRAY_SIZE(msm_pinctrl_functions),
|
.functions_count = ARRAY_SIZE(msm_pinctrl_functions),
|
||||||
.get_function_name = qcs404_get_function_name,
|
.get_function_name = qcs404_get_function_name,
|
||||||
.get_function_mux = qcs404_get_function_mux,
|
.get_function_mux = qcs404_get_function_mux,
|
||||||
|
@ -75,10 +75,11 @@ static unsigned int sdm845_get_function_mux(unsigned int selector)
|
|||||||
return msm_pinctrl_functions[selector].val;
|
return msm_pinctrl_functions[selector].val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct msm_pinctrl_data sdm845_data = {
|
static const struct msm_pinctrl_data sdm845_data = {
|
||||||
.pin_data = {
|
.pin_data = {
|
||||||
.pin_offsets = sdm845_pin_offsets,
|
.pin_offsets = sdm845_pin_offsets,
|
||||||
.pin_count = ARRAY_SIZE(sdm845_pin_offsets),
|
.pin_count = 154,
|
||||||
|
.special_pins_start = 150,
|
||||||
},
|
},
|
||||||
.functions_count = ARRAY_SIZE(msm_pinctrl_functions),
|
.functions_count = ARRAY_SIZE(msm_pinctrl_functions),
|
||||||
.get_function_name = sdm845_get_function_name,
|
.get_function_name = sdm845_get_function_name,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user