diff options
author | Andy Yan <andy.yan@rock-chips.com> | 2017-05-15 17:50:35 +0800 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2017-06-07 07:29:19 -0600 |
commit | 27600a583725ed0fa9cd4755a86ed0051bfb8c67 (patch) | |
tree | 1ac26326e8df67d550f405bb15cd8d654f3e8cf4 /drivers/pinctrl/rockchip | |
parent | d1dcf8527ececd1595d7ae6dc56c19bbcf0c537d (diff) | |
download | u-boot-27600a583725ed0fa9cd4755a86ed0051bfb8c67.tar.gz |
rockchip: rk3368: Add pinctrl driver
Add driver to support iomux setup for the most commonly
used peripherals on rk3368.
Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'drivers/pinctrl/rockchip')
-rw-r--r-- | drivers/pinctrl/rockchip/Makefile | 1 | ||||
-rw-r--r-- | drivers/pinctrl/rockchip/pinctrl_rk3368.c | 149 |
2 files changed, 150 insertions, 0 deletions
diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile index 69eef4c024..7b7c470b46 100644 --- a/drivers/pinctrl/rockchip/Makefile +++ b/drivers/pinctrl/rockchip/Makefile @@ -9,4 +9,5 @@ obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3036) += pinctrl_rk3036.o obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3188) += pinctrl_rk3188.o obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3288) += pinctrl_rk3288.o obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3328) += pinctrl_rk3328.o +obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3368) += pinctrl_rk3368.o obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3399) += pinctrl_rk3399.o diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3368.c b/drivers/pinctrl/rockchip/pinctrl_rk3368.c new file mode 100644 index 0000000000..bdf0758c0c --- /dev/null +++ b/drivers/pinctrl/rockchip/pinctrl_rk3368.c @@ -0,0 +1,149 @@ +/* + * (C) Copyright 2017 Rockchip Electronics Co., Ltd + * Author: Andy Yan <andy.yan@rock-chips.com> + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <syscon.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/hardware.h> +#include <asm/arch/grf_rk3368.h> +#include <asm/arch/periph.h> +#include <dm/pinctrl.h> + +DECLARE_GLOBAL_DATA_PTR; + +struct rk3368_pinctrl_priv { + struct rk3368_grf *grf; + struct rk3368_pmu_grf *pmugrf; +}; + +static void pinctrl_rk3368_uart_config(struct rk3368_pinctrl_priv *priv, + int uart_id) +{ + struct rk3368_grf *grf = priv->grf; + struct rk3368_pmu_grf *pmugrf = priv->pmugrf; + + switch (uart_id) { + case PERIPH_ID_UART2: + rk_clrsetreg(&grf->gpio2a_iomux, + GPIO2A6_MASK | GPIO2A5_MASK, + GPIO2A6_UART2_SIN << GPIO2A6_SHIFT | + GPIO2A5_UART2_SOUT << GPIO2A5_SHIFT); + break; + case PERIPH_ID_UART0: + break; + case PERIPH_ID_UART1: + break; + case PERIPH_ID_UART3: + break; + case PERIPH_ID_UART4: + rk_clrsetreg(&pmugrf->gpio0d_iomux, + GPIO0D0_MASK | GPIO0D1_MASK | + GPIO0D2_MASK | GPIO0D3_MASK, + GPIO0D0_GPIO << GPIO0D0_SHIFT | + GPIO0D1_GPIO << GPIO0D1_SHIFT | + GPIO0D2_UART4_SOUT << GPIO0D2_SHIFT | + GPIO0D3_UART4_SIN << GPIO0D3_SHIFT); + break; + default: + debug("uart id = %d iomux error!\n", uart_id); + break; + } +} + +static int rk3368_pinctrl_request(struct udevice *dev, int func, int flags) +{ + struct rk3368_pinctrl_priv *priv = dev_get_priv(dev); + + debug("%s: func=%d, flags=%x\n", __func__, func, flags); + switch (func) { + case PERIPH_ID_UART0: + case PERIPH_ID_UART1: + case PERIPH_ID_UART2: + case PERIPH_ID_UART3: + case PERIPH_ID_UART4: + pinctrl_rk3368_uart_config(priv, func); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int rk3368_pinctrl_get_periph_id(struct udevice *dev, + struct udevice *periph) +{ + u32 cell[3]; + int ret; + + ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(periph), + "interrupts", cell, ARRAY_SIZE(cell)); + if (ret < 0) + return -EINVAL; + + switch (cell[1]) { + case 59: + return PERIPH_ID_UART4; + case 58: + return PERIPH_ID_UART3; + case 57: + return PERIPH_ID_UART2; + case 56: + return PERIPH_ID_UART1; + case 55: + return PERIPH_ID_UART0; + } + + return -ENOENT; +} + +static int rk3368_pinctrl_set_state_simple(struct udevice *dev, + struct udevice *periph) +{ + int func; + + func = rk3368_pinctrl_get_periph_id(dev, periph); + if (func < 0) + return func; + + return rk3368_pinctrl_request(dev, func, 0); +} + +static struct pinctrl_ops rk3368_pinctrl_ops = { + .set_state_simple = rk3368_pinctrl_set_state_simple, + .request = rk3368_pinctrl_request, + .get_periph_id = rk3368_pinctrl_get_periph_id, +}; + +static int rk3368_pinctrl_probe(struct udevice *dev) +{ + struct rk3368_pinctrl_priv *priv = dev_get_priv(dev); + int ret = 0; + + priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); + priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF); + + debug("%s: grf=%p pmugrf:%p\n", __func__, priv->grf, priv->pmugrf); + + return ret; +} + +static const struct udevice_id rk3368_pinctrl_ids[] = { + { .compatible = "rockchip,rk3368-pinctrl" }, + { } +}; + +U_BOOT_DRIVER(pinctrl_rk3368) = { + .name = "rockchip_rk3368_pinctrl", + .id = UCLASS_PINCTRL, + .of_match = rk3368_pinctrl_ids, + .priv_auto_alloc_size = sizeof(struct rk3368_pinctrl_priv), + .ops = &rk3368_pinctrl_ops, + .bind = dm_scan_fdt_dev, + .probe = rk3368_pinctrl_probe, +}; |