diff --git a/arch/arm/mach-snapdragon/Makefile b/arch/arm/mach-snapdragon/Makefile index 1c23dc5..1d35fea 100644 --- a/arch/arm/mach-snapdragon/Makefile +++ b/arch/arm/mach-snapdragon/Makefile @@ -6,4 +6,6 @@ obj-$(CONFIG_TARGET_DRAGONBOARD820C) += clock-apq8096.o obj-$(CONFIG_TARGET_DRAGONBOARD820C) += sysmap-apq8096.o obj-$(CONFIG_TARGET_DRAGONBOARD410C) += clock-apq8016.o obj-$(CONFIG_TARGET_DRAGONBOARD410C) += sysmap-apq8016.o +obj-$(CONFIG_TARGET_DRAGONBOARD410C) += pinctrl-apq8016.o +obj-$(CONFIG_TARGET_DRAGONBOARD410C) += pinctrl-snapdragon.o obj-y += clock-snapdragon.o diff --git a/arch/arm/mach-snapdragon/pinctrl-apq8016.c b/arch/arm/mach-snapdragon/pinctrl-apq8016.c new file mode 100644 index 0000000..bdb755d --- /dev/null +++ b/arch/arm/mach-snapdragon/pinctrl-apq8016.c @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Qualcomm APQ8016 pinctrl + * + * (C) Copyright 2018 Ramon Fried + * + */ + +#include "pinctrl-snapdragon.h" +#include + +#define MAX_PIN_NAME_LEN 32 +static char pin_name[MAX_PIN_NAME_LEN]; +static const char * const msm_pinctrl_pins[] = { + "SDC1_CLK", + "SDC1_CMD", + "SDC1_DATA", + "SDC2_CLK", + "SDC2_CMD", + "SDC2_DATA", + "QDSD_CLK", + "QDSD_CMD", + "QDSD_DATA0", + "QDSD_DATA1", + "QDSD_DATA2", + "QDSD_DATA3", +}; + +static const struct pinctrl_function msm_pinctrl_functions[] = { + {"blsp1_uart", 2}, +}; + +static const char *apq8016_get_function_name(struct udevice *dev, + unsigned int selector) +{ + return msm_pinctrl_functions[selector].name; +} + +static const char *apq8016_get_pin_name(struct udevice *dev, + unsigned int selector) +{ + if (selector < 130) { + snprintf(pin_name, MAX_PIN_NAME_LEN, "GPIO_%u", selector); + return pin_name; + } else { + return msm_pinctrl_pins[selector - 130]; + } +} + +static unsigned int apq8016_get_function_mux(unsigned int selector) +{ + return msm_pinctrl_functions[selector].val; +} + +struct msm_pinctrl_data apq8016_data = { + .pin_count = 140, + .functions_count = ARRAY_SIZE(msm_pinctrl_functions), + .get_function_name = apq8016_get_function_name, + .get_function_mux = apq8016_get_function_mux, + .get_pin_name = apq8016_get_pin_name, +}; + diff --git a/arch/arm/mach-snapdragon/pinctrl-snapdragon.c b/arch/arm/mach-snapdragon/pinctrl-snapdragon.c new file mode 100644 index 0000000..5365ccd --- /dev/null +++ b/arch/arm/mach-snapdragon/pinctrl-snapdragon.c @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * TLMM driver for Qualcomm APQ8016, APQ8096 + * + * (C) Copyright 2018 Ramon Fried + * + */ + +#include +#include +#include +#include +#include +#include "pinctrl-snapdragon.h" + +struct msm_pinctrl_priv { + phys_addr_t base; + struct msm_pinctrl_data *data; +}; + +#define GPIO_CONFIG_OFFSET(x) ((x) * 0x1000) +#define TLMM_GPIO_PULL_MASK GENMASK(1, 0) +#define TLMM_FUNC_SEL_MASK GENMASK(5, 2) +#define TLMM_DRV_STRENGTH_MASK GENMASK(8, 6) +#define TLMM_GPIO_ENABLE BIT(9) + +static const struct pinconf_param msm_conf_params[] = { + { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 3 }, + { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 }, +}; + +static int msm_get_functions_count(struct udevice *dev) +{ + struct msm_pinctrl_priv *priv = dev_get_priv(dev); + + return priv->data->functions_count; +} + +static int msm_get_pins_count(struct udevice *dev) +{ + struct msm_pinctrl_priv *priv = dev_get_priv(dev); + + return priv->data->pin_count; +} + +static const char *msm_get_function_name(struct udevice *dev, + unsigned int selector) +{ + struct msm_pinctrl_priv *priv = dev_get_priv(dev); + + return priv->data->get_function_name(dev, selector); +} + +static int msm_pinctrl_probe(struct udevice *dev) +{ + struct msm_pinctrl_priv *priv = dev_get_priv(dev); + + priv->base = devfdt_get_addr(dev); + priv->data = (struct msm_pinctrl_data *)dev->driver_data; + + return priv->base == FDT_ADDR_T_NONE ? -EINVAL : 0; +} + +static const char *msm_get_pin_name(struct udevice *dev, unsigned int selector) +{ + struct msm_pinctrl_priv *priv = dev_get_priv(dev); + + return priv->data->get_pin_name(dev, selector); +} + +static int msm_pinmux_set(struct udevice *dev, unsigned int pin_selector, + unsigned int func_selector) +{ + struct msm_pinctrl_priv *priv = dev_get_priv(dev); + + clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector), + TLMM_FUNC_SEL_MASK | TLMM_GPIO_ENABLE, + priv->data->get_function_mux(func_selector) << 2); + return 0; +} + +static int msm_pinconf_set(struct udevice *dev, unsigned int pin_selector, + unsigned int param, unsigned int argument) +{ + struct msm_pinctrl_priv *priv = dev_get_priv(dev); + + switch (param) { + case PIN_CONFIG_DRIVE_STRENGTH: + clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector), + TLMM_DRV_STRENGTH_MASK, argument << 6); + break; + case PIN_CONFIG_BIAS_DISABLE: + clrbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector), + TLMM_GPIO_PULL_MASK); + break; + default: + return 0; + } + + return 0; +} + +static struct pinctrl_ops msm_pinctrl_ops = { + .get_pins_count = msm_get_pins_count, + .get_pin_name = msm_get_pin_name, + .set_state = pinctrl_generic_set_state, + .pinmux_set = msm_pinmux_set, + .pinconf_num_params = ARRAY_SIZE(msm_conf_params), + .pinconf_params = msm_conf_params, + .pinconf_set = msm_pinconf_set, + .get_functions_count = msm_get_functions_count, + .get_function_name = msm_get_function_name, +}; + +static const struct udevice_id msm_pinctrl_ids[] = { + { .compatible = "qcom,tlmm-msm8916", .data = (ulong)&apq8016_data }, + { .compatible = "qcom,tlmm-apq8016", .data = (ulong)&apq8016_data }, + { } +}; + +U_BOOT_DRIVER(pinctrl_snapdraon) = { + .name = "pinctrl_msm", + .id = UCLASS_PINCTRL, + .of_match = msm_pinctrl_ids, + .priv_auto_alloc_size = sizeof(struct msm_pinctrl_priv), + .ops = &msm_pinctrl_ops, + .probe = msm_pinctrl_probe, +}; diff --git a/arch/arm/mach-snapdragon/pinctrl-snapdragon.h b/arch/arm/mach-snapdragon/pinctrl-snapdragon.h new file mode 100644 index 0000000..c47d988 --- /dev/null +++ b/arch/arm/mach-snapdragon/pinctrl-snapdragon.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Qualcomm Pin control + * + * (C) Copyright 2018 Ramon Fried + * + */ +#ifndef _PINCTRL_SNAPDRAGON_H +#define _PINCTRL_SNAPDRAGON_H + +#include + +struct msm_pinctrl_data { + int pin_count; + int functions_count; + const char *(*get_function_name)(struct udevice *dev, + unsigned int selector); + unsigned int (*get_function_mux)(unsigned int selector); + const char *(*get_pin_name)(struct udevice *dev, + unsigned int selector); +}; + +struct pinctrl_function { + const char *name; + int val; +}; + +extern struct msm_pinctrl_data apq8016_data; + +#endif diff --git a/configs/dragonboard410c_defconfig b/configs/dragonboard410c_defconfig index e6114db..4b3de64 100644 --- a/configs/dragonboard410c_defconfig +++ b/configs/dragonboard410c_defconfig @@ -45,3 +45,8 @@ CONFIG_USB_ETHER_ASIX88179=y CONFIG_USB_ETHER_MCS7830=y CONFIG_USB_ETHER_SMSC95XX=y CONFIG_OF_LIBFDT_OVERLAY=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_FULL=y +CONFIG_PINCTRL_GENERIC=y +CONFIG_PINMUX=y +CONFIG_PINCONF=y diff --git a/include/dt-bindings/pinctrl/pinctrl-snapdragon.h b/include/dt-bindings/pinctrl/pinctrl-snapdragon.h new file mode 100644 index 0000000..615affb --- /dev/null +++ b/include/dt-bindings/pinctrl/pinctrl-snapdragon.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * This header provides constants for Qualcomm Snapdragon pinctrl bindings. + * + * (C) Copyright 2018 Ramon Fried + * + */ + +#ifndef _DT_BINDINGS_PINCTRL_SNAPDRAGON_H +#define _DT_BINDINGS_PINCTRL_SNAPDRAGON_H + +/* GPIO Drive Strength */ +#define DRIVE_STRENGTH_2MA 0 +#define DRIVE_STRENGTH_4MA 1 +#define DRIVE_STRENGTH_6MA 2 +#define DRIVE_STRENGTH_8MA 3 +#define DRIVE_STRENGTH_10MA 4 +#define DRIVE_STRENGTH_12MA 5 +#define DRIVE_STRENGTH_14MA 6 +#define DRIVE_STRENGTH_16MA 7 + +#endif