Message ID | 1470966423-16657-1-git-send-email-kever.yang@rock-chips.com |
---|---|
State | Superseded |
Delegated to: | Simon Glass |
Headers | show |
Hi Kever, On 11 August 2016 at 19:47, Kever Yang <kever.yang@rock-chips.com> wrote: > This patch add pinctrl driver for rk3399. > > Signed-off-by: Kever Yang <kever.yang@rock-chips.com> > --- > > arch/arm/include/asm/arch-rockchip/grf_rk3399.h | 365 ++++++++++++++++++++++++ > drivers/pinctrl/Kconfig | 9 + > drivers/pinctrl/rockchip/Makefile | 1 + > drivers/pinctrl/rockchip/pinctrl_rk3399.c | 282 ++++++++++++++++++ > 4 files changed, 657 insertions(+) > create mode 100644 arch/arm/include/asm/arch-rockchip/grf_rk3399.h > create mode 100644 drivers/pinctrl/rockchip/pinctrl_rk3399.c > > diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3399.h b/arch/arm/include/asm/arch-rockchip/grf_rk3399.h > new file mode 100644 > index 0000000..bcb5f97 > --- /dev/null > +++ b/arch/arm/include/asm/arch-rockchip/grf_rk3399.h > @@ -0,0 +1,365 @@ > +/* > + * This file is part of the coreboot project. > + * > + * Copyright 2016 Rockchip Inc. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; version 2 of the License. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + */ > + > +#ifndef __SOC_ROCKCHIP_RK3399_GRF_H__ > +#define __SOC_ROCKCHIP_RK3399_GRF_H__ > + > +struct rk3399_grf_regs { > + u32 reserved[0x800]; > + u32 usb3_perf_con0; > + u32 usb3_perf_con1; > + u32 usb3_perf_con2; > + u32 usb3_perf_rd_max_latency_num; > + u32 usb3_perf_rd_latency_samp_num; > + u32 usb3_perf_rd_latency_acc_num; > + u32 usb3_perf_rd_axi_total_byte; > + u32 usb3_perf_wr_axi_total_byte; > + u32 usb3_perf_working_cnt; > + u32 reserved1[0x103]; > + u32 usb3otg0_con0; > + u32 usb3otg0_con1; > + u32 reserved2[2]; > + u32 usb3otg1_con0; > + u32 usb3otg1_con1; > + u32 reserved3[2]; > + u32 usb3otg0_status_lat0; > + u32 usb3otg0_status_lat1; > + u32 usb3otg0_status_cb; > + u32 reserved4; > + u32 usb3otg1_status_lat0; > + u32 usb3otg1_status_lat1; > + u32 usb3ogt1_status_cb; > + u32 reserved5[0x6e5]; > + u32 pcie_perf_con0; > + u32 pcie_perf_con1; > + u32 pcie_perf_con2; > + u32 pcie_perf_rd_max_latency_num; > + u32 pcie_perf_rd_latency_samp_num; > + u32 pcie_perf_rd_laterncy_acc_num; > + u32 pcie_perf_rd_axi_total_byte; > + u32 pcie_perf_wr_axi_total_byte; > + u32 pcie_perf_working_cnt; > + u32 reserved6[0x37]; > + u32 usb20_host0_con0; > + u32 usb20_host0_con1; > + u32 reserved7[2]; > + u32 usb20_host1_con0; > + u32 usb20_host1_con1; > + u32 reserved8[2]; > + u32 hsic_con0; > + u32 hsic_con1; > + u32 reserved9[6]; > + u32 grf_usbhost0_status; > + u32 grf_usbhost1_Status; > + u32 grf_hsic_status; > + u32 reserved10[0xc9]; > + u32 hsicphy_con0; > + u32 reserved11[3]; > + u32 usbphy0_ctrl[26]; > + u32 reserved12[6]; > + u32 usbphy1[26]; > + u32 reserved13[0x72f]; > + u32 soc_con9; > + u32 reserved14[0x0a]; > + u32 soc_con20; > + u32 soc_con21; > + u32 soc_con22; > + u32 soc_con23; > + u32 soc_con24; > + u32 soc_con25; > + u32 soc_con26; > + u32 reserved15[0xf65]; > + u32 cpu_con[4]; > + u32 reserved16[0x1c]; > + u32 cpu_status[6]; > + u32 reserved17[0x1a]; > + u32 a53_perf_con[4]; > + u32 a53_perf_rd_mon_st; > + u32 a53_perf_rd_mon_end; > + u32 a53_perf_wr_mon_st; > + u32 a53_perf_wr_mon_end; > + u32 a53_perf_rd_max_latency_num; > + u32 a53_perf_rd_latency_samp_num; > + u32 a53_perf_rd_laterncy_acc_num; > + u32 a53_perf_rd_axi_total_byte; > + u32 a53_perf_wr_axi_total_byte; > + u32 a53_perf_working_cnt; > + u32 a53_perf_int_status; > + u32 reserved18[0x31]; > + u32 a72_perf_con[4]; > + u32 a72_perf_rd_mon_st; > + u32 a72_perf_rd_mon_end; > + u32 a72_perf_wr_mon_st; > + u32 a72_perf_wr_mon_end; > + u32 a72_perf_rd_max_latency_num; > + u32 a72_perf_rd_latency_samp_num; > + u32 a72_perf_rd_laterncy_acc_num; > + u32 a72_perf_rd_axi_total_byte; > + u32 a72_perf_wr_axi_total_byte; > + u32 a72_perf_working_cnt; > + u32 a72_perf_int_status; > + u32 reserved19[0x7f6]; > + u32 soc_con5; > + u32 soc_con6; > + u32 reserved20[0x779]; > + u32 gpio2a_iomux; > + union { > + u32 iomux_spi2; > + u32 gpio2b_iomux; Can we drop these unions and just have one member? Which one do you use? > + }; > + union { > + u32 gpio2c_iomux; > + u32 iomux_spi5; > + }; > + u32 gpio2d_iomux; > + union { > + u32 gpio3a_iomux; > + u32 iomux_spi0; > + }; > + u32 gpio3b_iomux; > + u32 gpio3c_iomux; > + union { > + u32 iomux_i2s0; > + u32 gpio3d_iomux; > + }; > + union { > + u32 iomux_i2sclk; > + u32 gpio4a_iomux; > + }; > + union { > + u32 iomux_sdmmc; > + u32 iomux_uart2a; > + u32 gpio4b_iomux; > + }; > + union { > + u32 iomux_pwm_0; > + u32 iomux_pwm_1; > + u32 iomux_uart2b; > + u32 iomux_uart2c; > + u32 iomux_edp_hotplug; > + u32 gpio4c_iomux; > + }; > + u32 gpio4d_iomux; > + u32 reserved21[4]; > + u32 gpio2_p[3][4]; > + u32 reserved22[4]; > + u32 gpio2_sr[3][4]; > + u32 reserved23[4]; > + u32 gpio2_smt[3][4]; > + u32 reserved24[(0xe130 - 0xe0ec)/4 - 1]; > + u32 gpio4b_e01; > + u32 gpio4b_e2; > + u32 reserved24a[(0xe200 - 0xe134)/4 - 1]; > + u32 soc_con0; > + u32 soc_con1; > + u32 soc_con2; > + u32 soc_con3; > + u32 soc_con4; > + u32 soc_con5_pcie; > + u32 reserved25; > + u32 soc_con7; > + u32 soc_con8; > + u32 soc_con9_pcie; > + u32 reserved26[0x1e]; > + u32 soc_status[6]; > + u32 reserved27[0x32]; > + u32 ddrc0_con0; > + u32 ddrc0_con1; > + u32 ddrc1_con0; > + u32 ddrc1_con1; > + u32 reserved28[0xac]; > + u32 io_vsel; > + u32 saradc_testbit; > + u32 tsadc_testbit_l; > + u32 tsadc_testbit_h; > + u32 reserved29[0x6c]; > + u32 chip_id_addr; > + u32 reserved30[0x1f]; > + u32 fast_boot_addr; > + u32 reserved31[0x1df]; > + u32 emmccore_con[12]; > + u32 reserved32[4]; > + u32 emmccore_status[4]; > + u32 reserved33[0x1cc]; > + u32 emmcphy_con[7]; > + u32 reserved34; > + u32 emmcphy_status; > +}; > +check_member(rk3399_grf_regs, emmcphy_status, 0xf7a0); > + > +struct rk3399_pmugrf_regs { > + union { > + u32 iomux_pwm_3a; > + u32 gpio0a_iomux; > + }; > + u32 gpio0b_iomux; > + u32 reserved0[2]; > + union { > + u32 spi1_rxd; > + u32 tsadc_int; > + u32 gpio1a_iomux; > + }; > + union { > + u32 spi1_csclktx; > + u32 iomux_pwm_3b; > + u32 iomux_i2c0_sda; > + u32 gpio1b_iomux; > + }; > + union { > + u32 iomux_pwm_2; > + u32 iomux_i2c0_scl; > + u32 gpio1c_iomux; > + }; > + u32 gpio1d_iomux; > + u32 reserved1[8]; > + u32 gpio0_p[2][4]; > + u32 reserved3[8]; > + u32 gpio0a_e; > + u32 reserved4; > + u32 gpio0b_e; > + u32 reserved5[5]; > + u32 gpio1a_e; > + u32 reserved6; > + u32 gpio1b_e; > + u32 reserved7; > + u32 gpio1c_e; > + u32 reserved8; > + u32 gpio1d_e; > + u32 reserved9[0x11]; > + u32 gpio0l_sr; > + u32 reserved10; > + u32 gpio1l_sr; > + u32 gpio1h_sr; > + u32 reserved11[4]; > + u32 gpio0a_smt; > + u32 gpio0b_smt; > + u32 reserved12[2]; > + u32 gpio1a_smt; > + u32 gpio1b_smt; > + u32 gpio1c_smt; > + u32 gpio1d_smt; > + u32 reserved13[8]; > + u32 gpio0l_he; > + u32 reserved14; > + u32 gpio1l_he; > + u32 gpio1h_he; > + u32 reserved15[4]; > + u32 soc_con0; > + u32 reserved16[9]; > + u32 soc_con10; > + u32 soc_con11; > + u32 reserved17[0x24]; > + u32 pmupvtm_con0; > + u32 pmupvtm_con1; > + u32 pmupvtm_status0; > + u32 pmupvtm_status1; > + u32 grf_osc_e; > + u32 reserved18[0x2b]; > + u32 os_reg0; > + u32 os_reg1; > + u32 os_reg2; > + u32 os_reg3; > +}; > +check_member(rk3399_pmugrf_regs, os_reg3, 0x30c); > + > +struct rk3399_pmusgrf_regs { > + u32 ddr_rgn_con[35]; > + u32 reserved[0x1fe5]; > + u32 soc_con8; > + u32 soc_con9; > + u32 soc_con10; > + u32 soc_con11; > + u32 soc_con12; > + u32 soc_con13; > + u32 soc_con14; > + u32 soc_con15; > + u32 reserved1[3]; > + u32 soc_con19; > + u32 soc_con20; > + u32 soc_con21; > + u32 soc_con22; > + u32 reserved2[0x29]; > + u32 perilp_con[9]; > + u32 reserved4[7]; > + u32 perilp_status; > + u32 reserved5[0xfaf]; > + u32 soc_con0; > + u32 soc_con1; > + u32 reserved6[0x3e]; > + u32 pmu_con[9]; > + u32 reserved7[0x17]; > + u32 fast_boot_addr; > + u32 reserved8[0x1f]; > + u32 efuse_prg_mask; > + u32 efuse_read_mask; > + u32 reserved9[0x0e]; > + u32 pmu_slv_con0; > + u32 pmu_slv_con1; > + u32 reserved10[0x771]; > + u32 soc_con3; > + u32 soc_con4; > + u32 soc_con5; > + u32 soc_con6; > + u32 soc_con7; > + u32 reserved11[8]; > + u32 soc_con16; > + u32 soc_con17; > + u32 soc_con18; > + u32 reserved12[0xdd]; > + u32 slv_secure_con0; > + u32 slv_secure_con1; > + u32 reserved13; > + u32 slv_secure_con2; > + u32 slv_secure_con3; > + u32 slv_secure_con4; > +}; > +check_member(rk3399_pmusgrf_regs, slv_secure_con4, 0xe3d4); > + > +#define UART2A_SEL RK_CLRSETBITS(3 << 10, 0 << 10) > +#define UART2B_SEL RK_CLRSETBITS(3 << 10, 1 << 10) > +#define UART2C_SEL RK_CLRSETBITS(3 << 10, 2 << 10) > +#define PWM3_SEL_A RK_CLRBITS(1 << 5) > +#define PWM3_SEL_B RK_SETBITS(1 << 5) > + > +#define IOMUX_UART2A RK_CLRSETBITS(3 << 2 | 3 << 0, 2 << 2 | 2 << 0) > +#define IOMUX_UART2B RK_CLRSETBITS(3 << 2 | 3 << 0, 2 << 2 | 2 << 0) > +#define IOMUX_UART2C RK_CLRSETBITS(3 << 8 | 3 << 6, 1 << 8 | 1 << 6) > +#define IOMUX_SPI0_DATA RK_CLRSETBITS(0x3f << 8, \ > + 2 << 12 | 2 << 10 | 2 << 8) > +#define IOMUX_SPI0_CS0 RK_CLRSETBITS(3 << 14, 2) > +#define IOMUX_SPI0_CS1 RK_CLRSETBITS(3, 2) > +#define IOMUX_SPI1_RX RK_CLRSETBITS(3 << 14, 2 << 14) > +#define IOMUX_SPI1_CSCLKTX RK_CLRSETBITS(0x3f << 0, 2 << 4 |\ > + 2 << 2 | 2 << 0) > +#define IOMUX_SPI2 RK_CLRSETBITS(0xff << 2, 1 << 8 | 1 << 6 |\ > + 1 << 4 | 1 << 2) > +#define IOMUX_SPI5 RK_CLRSETBITS(0xff << 8, \ > + 2 << 14 | 2 << 12 | 2 << 10 | 2 << 8) > +#define IOMUX_SDMMC RK_CLRSETBITS(0xfff, 1 << 10 | 1 << 8 | 1 << 6 |\ > + 1 << 4 | 1 << 2 | 1 << 0) > +#define IOMUX_I2C0_SCL RK_CLRSETBITS(3 << 0, 2 << 0) > +#define IOMUX_I2C0_SDA RK_CLRSETBITS(3 << 14, 2 << 14) > +#define IOMUX_I2S0 RK_SETBITS(1 << 14 | 1 << 12 | 1 << 10 | 1 << 8 |\ > + 1 << 6 | 1 << 4 | 1 << 2 | 1 << 0) > +#define IOMUX_I2SCLK RK_SETBITS(1 << 0) > + > +#define IOMUX_PWM_0 RK_CLRSETBITS(3 << 4, 1 << 4) > +#define IOMUX_PWM_1 RK_CLRSETBITS(3 << 12, 1 << 12) > +#define IOMUX_PWM_2 RK_CLRSETBITS(3 << 6, 1 << 6) > +#define IOMUX_PWM_3_A RK_CLRSETBITS(3 << 12, 1 << 12) > +#define IOMUX_PWM_3_B RK_CLRSETBITS(3 << 12, 1 << 12) > +#define IOMUX_TSADC_INT RK_CLRSETBITS(3 << 12, 1 << 12) > +#define IOMUX_EDP_HOTPLUG RK_CLRSETBITS(3 << 14, 2 << 14) Can you drop these defines and put the code in the C file? Please define SHIFT and MASK in the header file #define SOMETHING_SHIFT 5 #define SOMETHING_MASK (7 << SOMETHING_SHIFT) > +#endif /* __SOC_ROCKCHIP_RK3399_GRF_H__ */ > diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig > index 2972dba..e2ea675 100644 > --- a/drivers/pinctrl/Kconfig > +++ b/drivers/pinctrl/Kconfig > @@ -141,6 +141,15 @@ config ROCKCHIP_RK3288_PINCTRL > definitions and pin control functions for each available multiplex > function. > > +config ROCKCHIP_RK3399_PINCTRL > + bool "Rockchip pin control driver" > + depends on DM > + help > + Support pin multiplexing control on Rockchip rk3399 SoCs. The driver > + is controlled by a device tree node which contains both the GPIO > + definitions and pin control functions for each available multiplex > + function. > + > config PINCTRL_SANDBOX > bool "Sandbox pinctrl driver" > depends on SANDBOX > diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile > index 64e9587..805c833 100644 > --- a/drivers/pinctrl/rockchip/Makefile > +++ b/drivers/pinctrl/rockchip/Makefile > @@ -7,3 +7,4 @@ > > obj-$(CONFIG_ROCKCHIP_RK3036_PINCTRL) += pinctrl_rk3036.o > obj-$(CONFIG_ROCKCHIP_RK3288_PINCTRL) += pinctrl_rk3288.o > +obj-$(CONFIG_ROCKCHIP_RK3399_PINCTRL) += pinctrl_rk3399.o > diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3399.c b/drivers/pinctrl/rockchip/pinctrl_rk3399.c > new file mode 100644 > index 0000000..63ba7bd > --- /dev/null > +++ b/drivers/pinctrl/rockchip/pinctrl_rk3399.c > @@ -0,0 +1,282 @@ > +/* > + * Pinctrl driver for Rockchip SoCs > + * Copyright (c) 2015 Google, Inc > + * Written by Simon Glass <sjg@chromium.org> > + * > + * 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/grf_rk3399.h> > +#include <asm/arch/hardware.h> > +#include <asm/arch/periph.h> > +#include <asm/arch/clock.h> > +#include <dm/pinctrl.h> > + > +DECLARE_GLOBAL_DATA_PTR; > + > +struct rk3399_pinctrl_priv { > + struct rk3399_grf_regs *grf; > + struct rk3399_pmugrf_regs *pmugrf; > +}; > + > +static void pinctrl_rk3399_pwm_config(struct rk3399_grf_regs *grf, > + struct rk3399_pmugrf_regs *pmugrf, int pwm_id) > +{ > + switch (pwm_id) { > + case PERIPH_ID_PWM0: > + writel(IOMUX_PWM_0, &grf->iomux_pwm_0); > + break; > + case PERIPH_ID_PWM1: > + writel(IOMUX_PWM_1, &grf->iomux_pwm_1); > + break; > + case PERIPH_ID_PWM2: > + writel(IOMUX_PWM_2, &pmugrf->iomux_pwm_2); > + break; > + case PERIPH_ID_PWM3: > + if (readl(&pmugrf->soc_con0) & (1 << 5)) > + writel(IOMUX_PWM_3_B, &pmugrf->iomux_pwm_3b); > + else > + writel(IOMUX_PWM_3_A, &pmugrf->iomux_pwm_3a); > + break; > + default: > + debug("pwm id = %d iomux error!\n", pwm_id); > + break; > + } > +} > + > +static void pinctrl_rk3399_i2c_config(struct rk3399_grf_regs *grf, > + struct rk3399_pmugrf_regs *pmugrf, > + int i2c_id) > +{ > + switch (i2c_id) { > + case PERIPH_ID_I2C0: > + writel(IOMUX_I2C0_SCL, &pmugrf->iomux_i2c0_sda); > + writel(IOMUX_I2C0_SDA, &pmugrf->iomux_i2c0_scl); > + break; > + case PERIPH_ID_I2C1: > + case PERIPH_ID_I2C2: > + case PERIPH_ID_I2C3: > + case PERIPH_ID_I2C4: > + case PERIPH_ID_I2C5: > + default: > + debug("i2c id = %d iomux error!\n", i2c_id); > + break; > + } > +} > + > +static void pinctrl_rk3399_lcdc_config(struct rk3399_grf_regs *grf, int lcd_id) > +{ > + switch (lcd_id) { > + case PERIPH_ID_LCDC0: > + break; > + default: > + debug("lcdc id = %d iomux error!\n", lcd_id); > + break; > + } > +} > + > +static int pinctrl_rk3399_spi_config(struct rk3399_grf_regs *grf, > + struct rk3399_pmugrf_regs *pmugrf, > + enum periph_id spi_id, int cs) > +{ > + switch (spi_id) { > + case PERIPH_ID_SPI0: > + switch (cs) { > + case 0: > + writel(IOMUX_SPI0_CS0, &grf->iomux_spi0); > + break; > + case 1: > + writel(IOMUX_SPI0_CS1, &grf->gpio3b_iomux); > + break; > + default: > + goto err; > + } > + writel(IOMUX_SPI0_DATA, &grf->iomux_spi0); Check indent. > + break; > + case PERIPH_ID_SPI1: > + if (cs != 0) > + goto err; > + writel(IOMUX_SPI1_RX, &pmugrf->gpio1a_iomux); > + writel(IOMUX_SPI1_CSCLKTX, &pmugrf->gpio1b_iomux); > + break; > + case PERIPH_ID_SPI2: > + if (cs != 0) > + goto err; > + writel(IOMUX_SPI2, &grf->gpio2b_iomux); > + break; > + default: > + goto err; > + } > + > + return 0; > +err: > + debug("rkspi: periph%d cs=%d not supported", spi_id, cs); > + return -ENOENT; > +} > + > +static void pinctrl_rk3399_uart_config(struct rk3399_grf_regs *grf, > + struct rk3399_pmugrf_regs *pmugrf, > + int uart_id) > +{ > + switch (uart_id) { > + case PERIPH_ID_UART2: > + writel(IOMUX_UART2A, &grf->iomux_uart2a); > + break; > + case PERIPH_ID_UART0: > + case PERIPH_ID_UART1: > + case PERIPH_ID_UART3: > + case PERIPH_ID_UART4: > + default: > + debug("uart id = %d iomux error!\n", uart_id); > + break; > + } > +} > + > +static void pinctrl_rk3399_sdmmc_config(struct rk3399_grf_regs *grf, int mmc_id) > +{ > + switch (mmc_id) { > + case PERIPH_ID_EMMC: > + break; > + case PERIPH_ID_SDCARD: > + writel(IOMUX_SDMMC, &grf->iomux_sdmmc); > + break; > + default: > + debug("mmc id = %d iomux error!\n", mmc_id); > + break; > + } > +} > + > +static int rk3399_pinctrl_request(struct udevice *dev, int func, int flags) > +{ > + struct rk3399_pinctrl_priv *priv = dev_get_priv(dev); > + > + debug("%s: func=%x, flags=%x\n", __func__, func, flags); > + switch (func) { > + case PERIPH_ID_PWM0: > + case PERIPH_ID_PWM1: > + case PERIPH_ID_PWM2: > + case PERIPH_ID_PWM3: > + case PERIPH_ID_PWM4: > + pinctrl_rk3399_pwm_config(priv->grf, priv->pmugrf, func); > + break; > + case PERIPH_ID_I2C0: > + case PERIPH_ID_I2C1: > + case PERIPH_ID_I2C2: > + case PERIPH_ID_I2C3: > + case PERIPH_ID_I2C4: > + case PERIPH_ID_I2C5: > + pinctrl_rk3399_i2c_config(priv->grf, priv->pmugrf, func); > + break; > + case PERIPH_ID_SPI0: > + case PERIPH_ID_SPI1: > + case PERIPH_ID_SPI2: > + pinctrl_rk3399_spi_config(priv->grf, priv->pmugrf, func, flags); > + break; > + case PERIPH_ID_UART0: > + case PERIPH_ID_UART1: > + case PERIPH_ID_UART2: > + case PERIPH_ID_UART3: > + case PERIPH_ID_UART4: > + pinctrl_rk3399_uart_config(priv->grf, priv->pmugrf, func); > + break; > + case PERIPH_ID_LCDC0: > + case PERIPH_ID_LCDC1: > + pinctrl_rk3399_lcdc_config(priv->grf, func); > + break; > + case PERIPH_ID_SDMMC0: > + case PERIPH_ID_SDMMC1: > + pinctrl_rk3399_sdmmc_config(priv->grf, func); > + break; > + default: > + return -EINVAL; > + } > + > + return 0; > +} > + > +static int rk3399_pinctrl_get_periph_id(struct udevice *dev, > + struct udevice *periph) > +{ > + u32 cell[3]; > + int ret; > + > + ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset, > + "interrupts", cell, ARRAY_SIZE(cell)); > + if (ret < 0) > + return -EINVAL; > + > + switch (cell[1]) { > + case 68: > + return PERIPH_ID_SPI0; > + case 53: > + return PERIPH_ID_SPI1; > + case 52: > + return PERIPH_ID_SPI2; > + case 57: > + return PERIPH_ID_I2C0; > + case 59: /* Note strange order */ > + return PERIPH_ID_I2C1; > + case 35: > + return PERIPH_ID_I2C2; > + case 34: > + return PERIPH_ID_I2C3; > + case 56: > + return PERIPH_ID_I2C4; > + case 38: > + return PERIPH_ID_I2C5; > + case 65: > + return PERIPH_ID_SDMMC1; > + } > + > + return -ENOENT; > +} > + > +static int rk3399_pinctrl_set_state_simple(struct udevice *dev, > + struct udevice *periph) > +{ > + int func; > + > + func = rk3399_pinctrl_get_periph_id(dev, periph); > + if (func < 0) > + return func; > + > + return rk3399_pinctrl_request(dev, func, 0); > +} > + > +static struct pinctrl_ops rk3399_pinctrl_ops = { > + .set_state_simple = rk3399_pinctrl_set_state_simple, > + .request = rk3399_pinctrl_request, > + .get_periph_id = rk3399_pinctrl_get_periph_id, > +}; > + > +static int rk3399_pinctrl_probe(struct udevice *dev) > +{ > + struct rk3399_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 rk3399_pinctrl_ids[] = { > + { .compatible = "rockchip,rk3399-pinctrl" }, > + { } > +}; > + > +U_BOOT_DRIVER(pinctrl_rk3399) = { > + .name = "rockchip_rk3399_pinctrl", > + .id = UCLASS_PINCTRL, > + .of_match = rk3399_pinctrl_ids, > + .priv_auto_alloc_size = sizeof(struct rk3399_pinctrl_priv), > + .ops = &rk3399_pinctrl_ops, > + .bind = dm_scan_fdt_dev, > + .probe = rk3399_pinctrl_probe, > +}; > -- > 1.9.1 > > Regards, Simon
diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3399.h b/arch/arm/include/asm/arch-rockchip/grf_rk3399.h new file mode 100644 index 0000000..bcb5f97 --- /dev/null +++ b/arch/arm/include/asm/arch-rockchip/grf_rk3399.h @@ -0,0 +1,365 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2016 Rockchip Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __SOC_ROCKCHIP_RK3399_GRF_H__ +#define __SOC_ROCKCHIP_RK3399_GRF_H__ + +struct rk3399_grf_regs { + u32 reserved[0x800]; + u32 usb3_perf_con0; + u32 usb3_perf_con1; + u32 usb3_perf_con2; + u32 usb3_perf_rd_max_latency_num; + u32 usb3_perf_rd_latency_samp_num; + u32 usb3_perf_rd_latency_acc_num; + u32 usb3_perf_rd_axi_total_byte; + u32 usb3_perf_wr_axi_total_byte; + u32 usb3_perf_working_cnt; + u32 reserved1[0x103]; + u32 usb3otg0_con0; + u32 usb3otg0_con1; + u32 reserved2[2]; + u32 usb3otg1_con0; + u32 usb3otg1_con1; + u32 reserved3[2]; + u32 usb3otg0_status_lat0; + u32 usb3otg0_status_lat1; + u32 usb3otg0_status_cb; + u32 reserved4; + u32 usb3otg1_status_lat0; + u32 usb3otg1_status_lat1; + u32 usb3ogt1_status_cb; + u32 reserved5[0x6e5]; + u32 pcie_perf_con0; + u32 pcie_perf_con1; + u32 pcie_perf_con2; + u32 pcie_perf_rd_max_latency_num; + u32 pcie_perf_rd_latency_samp_num; + u32 pcie_perf_rd_laterncy_acc_num; + u32 pcie_perf_rd_axi_total_byte; + u32 pcie_perf_wr_axi_total_byte; + u32 pcie_perf_working_cnt; + u32 reserved6[0x37]; + u32 usb20_host0_con0; + u32 usb20_host0_con1; + u32 reserved7[2]; + u32 usb20_host1_con0; + u32 usb20_host1_con1; + u32 reserved8[2]; + u32 hsic_con0; + u32 hsic_con1; + u32 reserved9[6]; + u32 grf_usbhost0_status; + u32 grf_usbhost1_Status; + u32 grf_hsic_status; + u32 reserved10[0xc9]; + u32 hsicphy_con0; + u32 reserved11[3]; + u32 usbphy0_ctrl[26]; + u32 reserved12[6]; + u32 usbphy1[26]; + u32 reserved13[0x72f]; + u32 soc_con9; + u32 reserved14[0x0a]; + u32 soc_con20; + u32 soc_con21; + u32 soc_con22; + u32 soc_con23; + u32 soc_con24; + u32 soc_con25; + u32 soc_con26; + u32 reserved15[0xf65]; + u32 cpu_con[4]; + u32 reserved16[0x1c]; + u32 cpu_status[6]; + u32 reserved17[0x1a]; + u32 a53_perf_con[4]; + u32 a53_perf_rd_mon_st; + u32 a53_perf_rd_mon_end; + u32 a53_perf_wr_mon_st; + u32 a53_perf_wr_mon_end; + u32 a53_perf_rd_max_latency_num; + u32 a53_perf_rd_latency_samp_num; + u32 a53_perf_rd_laterncy_acc_num; + u32 a53_perf_rd_axi_total_byte; + u32 a53_perf_wr_axi_total_byte; + u32 a53_perf_working_cnt; + u32 a53_perf_int_status; + u32 reserved18[0x31]; + u32 a72_perf_con[4]; + u32 a72_perf_rd_mon_st; + u32 a72_perf_rd_mon_end; + u32 a72_perf_wr_mon_st; + u32 a72_perf_wr_mon_end; + u32 a72_perf_rd_max_latency_num; + u32 a72_perf_rd_latency_samp_num; + u32 a72_perf_rd_laterncy_acc_num; + u32 a72_perf_rd_axi_total_byte; + u32 a72_perf_wr_axi_total_byte; + u32 a72_perf_working_cnt; + u32 a72_perf_int_status; + u32 reserved19[0x7f6]; + u32 soc_con5; + u32 soc_con6; + u32 reserved20[0x779]; + u32 gpio2a_iomux; + union { + u32 iomux_spi2; + u32 gpio2b_iomux; + }; + union { + u32 gpio2c_iomux; + u32 iomux_spi5; + }; + u32 gpio2d_iomux; + union { + u32 gpio3a_iomux; + u32 iomux_spi0; + }; + u32 gpio3b_iomux; + u32 gpio3c_iomux; + union { + u32 iomux_i2s0; + u32 gpio3d_iomux; + }; + union { + u32 iomux_i2sclk; + u32 gpio4a_iomux; + }; + union { + u32 iomux_sdmmc; + u32 iomux_uart2a; + u32 gpio4b_iomux; + }; + union { + u32 iomux_pwm_0; + u32 iomux_pwm_1; + u32 iomux_uart2b; + u32 iomux_uart2c; + u32 iomux_edp_hotplug; + u32 gpio4c_iomux; + }; + u32 gpio4d_iomux; + u32 reserved21[4]; + u32 gpio2_p[3][4]; + u32 reserved22[4]; + u32 gpio2_sr[3][4]; + u32 reserved23[4]; + u32 gpio2_smt[3][4]; + u32 reserved24[(0xe130 - 0xe0ec)/4 - 1]; + u32 gpio4b_e01; + u32 gpio4b_e2; + u32 reserved24a[(0xe200 - 0xe134)/4 - 1]; + u32 soc_con0; + u32 soc_con1; + u32 soc_con2; + u32 soc_con3; + u32 soc_con4; + u32 soc_con5_pcie; + u32 reserved25; + u32 soc_con7; + u32 soc_con8; + u32 soc_con9_pcie; + u32 reserved26[0x1e]; + u32 soc_status[6]; + u32 reserved27[0x32]; + u32 ddrc0_con0; + u32 ddrc0_con1; + u32 ddrc1_con0; + u32 ddrc1_con1; + u32 reserved28[0xac]; + u32 io_vsel; + u32 saradc_testbit; + u32 tsadc_testbit_l; + u32 tsadc_testbit_h; + u32 reserved29[0x6c]; + u32 chip_id_addr; + u32 reserved30[0x1f]; + u32 fast_boot_addr; + u32 reserved31[0x1df]; + u32 emmccore_con[12]; + u32 reserved32[4]; + u32 emmccore_status[4]; + u32 reserved33[0x1cc]; + u32 emmcphy_con[7]; + u32 reserved34; + u32 emmcphy_status; +}; +check_member(rk3399_grf_regs, emmcphy_status, 0xf7a0); + +struct rk3399_pmugrf_regs { + union { + u32 iomux_pwm_3a; + u32 gpio0a_iomux; + }; + u32 gpio0b_iomux; + u32 reserved0[2]; + union { + u32 spi1_rxd; + u32 tsadc_int; + u32 gpio1a_iomux; + }; + union { + u32 spi1_csclktx; + u32 iomux_pwm_3b; + u32 iomux_i2c0_sda; + u32 gpio1b_iomux; + }; + union { + u32 iomux_pwm_2; + u32 iomux_i2c0_scl; + u32 gpio1c_iomux; + }; + u32 gpio1d_iomux; + u32 reserved1[8]; + u32 gpio0_p[2][4]; + u32 reserved3[8]; + u32 gpio0a_e; + u32 reserved4; + u32 gpio0b_e; + u32 reserved5[5]; + u32 gpio1a_e; + u32 reserved6; + u32 gpio1b_e; + u32 reserved7; + u32 gpio1c_e; + u32 reserved8; + u32 gpio1d_e; + u32 reserved9[0x11]; + u32 gpio0l_sr; + u32 reserved10; + u32 gpio1l_sr; + u32 gpio1h_sr; + u32 reserved11[4]; + u32 gpio0a_smt; + u32 gpio0b_smt; + u32 reserved12[2]; + u32 gpio1a_smt; + u32 gpio1b_smt; + u32 gpio1c_smt; + u32 gpio1d_smt; + u32 reserved13[8]; + u32 gpio0l_he; + u32 reserved14; + u32 gpio1l_he; + u32 gpio1h_he; + u32 reserved15[4]; + u32 soc_con0; + u32 reserved16[9]; + u32 soc_con10; + u32 soc_con11; + u32 reserved17[0x24]; + u32 pmupvtm_con0; + u32 pmupvtm_con1; + u32 pmupvtm_status0; + u32 pmupvtm_status1; + u32 grf_osc_e; + u32 reserved18[0x2b]; + u32 os_reg0; + u32 os_reg1; + u32 os_reg2; + u32 os_reg3; +}; +check_member(rk3399_pmugrf_regs, os_reg3, 0x30c); + +struct rk3399_pmusgrf_regs { + u32 ddr_rgn_con[35]; + u32 reserved[0x1fe5]; + u32 soc_con8; + u32 soc_con9; + u32 soc_con10; + u32 soc_con11; + u32 soc_con12; + u32 soc_con13; + u32 soc_con14; + u32 soc_con15; + u32 reserved1[3]; + u32 soc_con19; + u32 soc_con20; + u32 soc_con21; + u32 soc_con22; + u32 reserved2[0x29]; + u32 perilp_con[9]; + u32 reserved4[7]; + u32 perilp_status; + u32 reserved5[0xfaf]; + u32 soc_con0; + u32 soc_con1; + u32 reserved6[0x3e]; + u32 pmu_con[9]; + u32 reserved7[0x17]; + u32 fast_boot_addr; + u32 reserved8[0x1f]; + u32 efuse_prg_mask; + u32 efuse_read_mask; + u32 reserved9[0x0e]; + u32 pmu_slv_con0; + u32 pmu_slv_con1; + u32 reserved10[0x771]; + u32 soc_con3; + u32 soc_con4; + u32 soc_con5; + u32 soc_con6; + u32 soc_con7; + u32 reserved11[8]; + u32 soc_con16; + u32 soc_con17; + u32 soc_con18; + u32 reserved12[0xdd]; + u32 slv_secure_con0; + u32 slv_secure_con1; + u32 reserved13; + u32 slv_secure_con2; + u32 slv_secure_con3; + u32 slv_secure_con4; +}; +check_member(rk3399_pmusgrf_regs, slv_secure_con4, 0xe3d4); + +#define UART2A_SEL RK_CLRSETBITS(3 << 10, 0 << 10) +#define UART2B_SEL RK_CLRSETBITS(3 << 10, 1 << 10) +#define UART2C_SEL RK_CLRSETBITS(3 << 10, 2 << 10) +#define PWM3_SEL_A RK_CLRBITS(1 << 5) +#define PWM3_SEL_B RK_SETBITS(1 << 5) + +#define IOMUX_UART2A RK_CLRSETBITS(3 << 2 | 3 << 0, 2 << 2 | 2 << 0) +#define IOMUX_UART2B RK_CLRSETBITS(3 << 2 | 3 << 0, 2 << 2 | 2 << 0) +#define IOMUX_UART2C RK_CLRSETBITS(3 << 8 | 3 << 6, 1 << 8 | 1 << 6) +#define IOMUX_SPI0_DATA RK_CLRSETBITS(0x3f << 8, \ + 2 << 12 | 2 << 10 | 2 << 8) +#define IOMUX_SPI0_CS0 RK_CLRSETBITS(3 << 14, 2) +#define IOMUX_SPI0_CS1 RK_CLRSETBITS(3, 2) +#define IOMUX_SPI1_RX RK_CLRSETBITS(3 << 14, 2 << 14) +#define IOMUX_SPI1_CSCLKTX RK_CLRSETBITS(0x3f << 0, 2 << 4 |\ + 2 << 2 | 2 << 0) +#define IOMUX_SPI2 RK_CLRSETBITS(0xff << 2, 1 << 8 | 1 << 6 |\ + 1 << 4 | 1 << 2) +#define IOMUX_SPI5 RK_CLRSETBITS(0xff << 8, \ + 2 << 14 | 2 << 12 | 2 << 10 | 2 << 8) +#define IOMUX_SDMMC RK_CLRSETBITS(0xfff, 1 << 10 | 1 << 8 | 1 << 6 |\ + 1 << 4 | 1 << 2 | 1 << 0) +#define IOMUX_I2C0_SCL RK_CLRSETBITS(3 << 0, 2 << 0) +#define IOMUX_I2C0_SDA RK_CLRSETBITS(3 << 14, 2 << 14) +#define IOMUX_I2S0 RK_SETBITS(1 << 14 | 1 << 12 | 1 << 10 | 1 << 8 |\ + 1 << 6 | 1 << 4 | 1 << 2 | 1 << 0) +#define IOMUX_I2SCLK RK_SETBITS(1 << 0) + +#define IOMUX_PWM_0 RK_CLRSETBITS(3 << 4, 1 << 4) +#define IOMUX_PWM_1 RK_CLRSETBITS(3 << 12, 1 << 12) +#define IOMUX_PWM_2 RK_CLRSETBITS(3 << 6, 1 << 6) +#define IOMUX_PWM_3_A RK_CLRSETBITS(3 << 12, 1 << 12) +#define IOMUX_PWM_3_B RK_CLRSETBITS(3 << 12, 1 << 12) +#define IOMUX_TSADC_INT RK_CLRSETBITS(3 << 12, 1 << 12) +#define IOMUX_EDP_HOTPLUG RK_CLRSETBITS(3 << 14, 2 << 14) +#endif /* __SOC_ROCKCHIP_RK3399_GRF_H__ */ diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 2972dba..e2ea675 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -141,6 +141,15 @@ config ROCKCHIP_RK3288_PINCTRL definitions and pin control functions for each available multiplex function. +config ROCKCHIP_RK3399_PINCTRL + bool "Rockchip pin control driver" + depends on DM + help + Support pin multiplexing control on Rockchip rk3399 SoCs. The driver + is controlled by a device tree node which contains both the GPIO + definitions and pin control functions for each available multiplex + function. + config PINCTRL_SANDBOX bool "Sandbox pinctrl driver" depends on SANDBOX diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile index 64e9587..805c833 100644 --- a/drivers/pinctrl/rockchip/Makefile +++ b/drivers/pinctrl/rockchip/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_ROCKCHIP_RK3036_PINCTRL) += pinctrl_rk3036.o obj-$(CONFIG_ROCKCHIP_RK3288_PINCTRL) += pinctrl_rk3288.o +obj-$(CONFIG_ROCKCHIP_RK3399_PINCTRL) += pinctrl_rk3399.o diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3399.c b/drivers/pinctrl/rockchip/pinctrl_rk3399.c new file mode 100644 index 0000000..63ba7bd --- /dev/null +++ b/drivers/pinctrl/rockchip/pinctrl_rk3399.c @@ -0,0 +1,282 @@ +/* + * Pinctrl driver for Rockchip SoCs + * Copyright (c) 2015 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + * + * 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/grf_rk3399.h> +#include <asm/arch/hardware.h> +#include <asm/arch/periph.h> +#include <asm/arch/clock.h> +#include <dm/pinctrl.h> + +DECLARE_GLOBAL_DATA_PTR; + +struct rk3399_pinctrl_priv { + struct rk3399_grf_regs *grf; + struct rk3399_pmugrf_regs *pmugrf; +}; + +static void pinctrl_rk3399_pwm_config(struct rk3399_grf_regs *grf, + struct rk3399_pmugrf_regs *pmugrf, int pwm_id) +{ + switch (pwm_id) { + case PERIPH_ID_PWM0: + writel(IOMUX_PWM_0, &grf->iomux_pwm_0); + break; + case PERIPH_ID_PWM1: + writel(IOMUX_PWM_1, &grf->iomux_pwm_1); + break; + case PERIPH_ID_PWM2: + writel(IOMUX_PWM_2, &pmugrf->iomux_pwm_2); + break; + case PERIPH_ID_PWM3: + if (readl(&pmugrf->soc_con0) & (1 << 5)) + writel(IOMUX_PWM_3_B, &pmugrf->iomux_pwm_3b); + else + writel(IOMUX_PWM_3_A, &pmugrf->iomux_pwm_3a); + break; + default: + debug("pwm id = %d iomux error!\n", pwm_id); + break; + } +} + +static void pinctrl_rk3399_i2c_config(struct rk3399_grf_regs *grf, + struct rk3399_pmugrf_regs *pmugrf, + int i2c_id) +{ + switch (i2c_id) { + case PERIPH_ID_I2C0: + writel(IOMUX_I2C0_SCL, &pmugrf->iomux_i2c0_sda); + writel(IOMUX_I2C0_SDA, &pmugrf->iomux_i2c0_scl); + break; + case PERIPH_ID_I2C1: + case PERIPH_ID_I2C2: + case PERIPH_ID_I2C3: + case PERIPH_ID_I2C4: + case PERIPH_ID_I2C5: + default: + debug("i2c id = %d iomux error!\n", i2c_id); + break; + } +} + +static void pinctrl_rk3399_lcdc_config(struct rk3399_grf_regs *grf, int lcd_id) +{ + switch (lcd_id) { + case PERIPH_ID_LCDC0: + break; + default: + debug("lcdc id = %d iomux error!\n", lcd_id); + break; + } +} + +static int pinctrl_rk3399_spi_config(struct rk3399_grf_regs *grf, + struct rk3399_pmugrf_regs *pmugrf, + enum periph_id spi_id, int cs) +{ + switch (spi_id) { + case PERIPH_ID_SPI0: + switch (cs) { + case 0: + writel(IOMUX_SPI0_CS0, &grf->iomux_spi0); + break; + case 1: + writel(IOMUX_SPI0_CS1, &grf->gpio3b_iomux); + break; + default: + goto err; + } + writel(IOMUX_SPI0_DATA, &grf->iomux_spi0); + break; + case PERIPH_ID_SPI1: + if (cs != 0) + goto err; + writel(IOMUX_SPI1_RX, &pmugrf->gpio1a_iomux); + writel(IOMUX_SPI1_CSCLKTX, &pmugrf->gpio1b_iomux); + break; + case PERIPH_ID_SPI2: + if (cs != 0) + goto err; + writel(IOMUX_SPI2, &grf->gpio2b_iomux); + break; + default: + goto err; + } + + return 0; +err: + debug("rkspi: periph%d cs=%d not supported", spi_id, cs); + return -ENOENT; +} + +static void pinctrl_rk3399_uart_config(struct rk3399_grf_regs *grf, + struct rk3399_pmugrf_regs *pmugrf, + int uart_id) +{ + switch (uart_id) { + case PERIPH_ID_UART2: + writel(IOMUX_UART2A, &grf->iomux_uart2a); + break; + case PERIPH_ID_UART0: + case PERIPH_ID_UART1: + case PERIPH_ID_UART3: + case PERIPH_ID_UART4: + default: + debug("uart id = %d iomux error!\n", uart_id); + break; + } +} + +static void pinctrl_rk3399_sdmmc_config(struct rk3399_grf_regs *grf, int mmc_id) +{ + switch (mmc_id) { + case PERIPH_ID_EMMC: + break; + case PERIPH_ID_SDCARD: + writel(IOMUX_SDMMC, &grf->iomux_sdmmc); + break; + default: + debug("mmc id = %d iomux error!\n", mmc_id); + break; + } +} + +static int rk3399_pinctrl_request(struct udevice *dev, int func, int flags) +{ + struct rk3399_pinctrl_priv *priv = dev_get_priv(dev); + + debug("%s: func=%x, flags=%x\n", __func__, func, flags); + switch (func) { + case PERIPH_ID_PWM0: + case PERIPH_ID_PWM1: + case PERIPH_ID_PWM2: + case PERIPH_ID_PWM3: + case PERIPH_ID_PWM4: + pinctrl_rk3399_pwm_config(priv->grf, priv->pmugrf, func); + break; + case PERIPH_ID_I2C0: + case PERIPH_ID_I2C1: + case PERIPH_ID_I2C2: + case PERIPH_ID_I2C3: + case PERIPH_ID_I2C4: + case PERIPH_ID_I2C5: + pinctrl_rk3399_i2c_config(priv->grf, priv->pmugrf, func); + break; + case PERIPH_ID_SPI0: + case PERIPH_ID_SPI1: + case PERIPH_ID_SPI2: + pinctrl_rk3399_spi_config(priv->grf, priv->pmugrf, func, flags); + break; + case PERIPH_ID_UART0: + case PERIPH_ID_UART1: + case PERIPH_ID_UART2: + case PERIPH_ID_UART3: + case PERIPH_ID_UART4: + pinctrl_rk3399_uart_config(priv->grf, priv->pmugrf, func); + break; + case PERIPH_ID_LCDC0: + case PERIPH_ID_LCDC1: + pinctrl_rk3399_lcdc_config(priv->grf, func); + break; + case PERIPH_ID_SDMMC0: + case PERIPH_ID_SDMMC1: + pinctrl_rk3399_sdmmc_config(priv->grf, func); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int rk3399_pinctrl_get_periph_id(struct udevice *dev, + struct udevice *periph) +{ + u32 cell[3]; + int ret; + + ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset, + "interrupts", cell, ARRAY_SIZE(cell)); + if (ret < 0) + return -EINVAL; + + switch (cell[1]) { + case 68: + return PERIPH_ID_SPI0; + case 53: + return PERIPH_ID_SPI1; + case 52: + return PERIPH_ID_SPI2; + case 57: + return PERIPH_ID_I2C0; + case 59: /* Note strange order */ + return PERIPH_ID_I2C1; + case 35: + return PERIPH_ID_I2C2; + case 34: + return PERIPH_ID_I2C3; + case 56: + return PERIPH_ID_I2C4; + case 38: + return PERIPH_ID_I2C5; + case 65: + return PERIPH_ID_SDMMC1; + } + + return -ENOENT; +} + +static int rk3399_pinctrl_set_state_simple(struct udevice *dev, + struct udevice *periph) +{ + int func; + + func = rk3399_pinctrl_get_periph_id(dev, periph); + if (func < 0) + return func; + + return rk3399_pinctrl_request(dev, func, 0); +} + +static struct pinctrl_ops rk3399_pinctrl_ops = { + .set_state_simple = rk3399_pinctrl_set_state_simple, + .request = rk3399_pinctrl_request, + .get_periph_id = rk3399_pinctrl_get_periph_id, +}; + +static int rk3399_pinctrl_probe(struct udevice *dev) +{ + struct rk3399_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 rk3399_pinctrl_ids[] = { + { .compatible = "rockchip,rk3399-pinctrl" }, + { } +}; + +U_BOOT_DRIVER(pinctrl_rk3399) = { + .name = "rockchip_rk3399_pinctrl", + .id = UCLASS_PINCTRL, + .of_match = rk3399_pinctrl_ids, + .priv_auto_alloc_size = sizeof(struct rk3399_pinctrl_priv), + .ops = &rk3399_pinctrl_ops, + .bind = dm_scan_fdt_dev, + .probe = rk3399_pinctrl_probe, +};
This patch add pinctrl driver for rk3399. Signed-off-by: Kever Yang <kever.yang@rock-chips.com> --- arch/arm/include/asm/arch-rockchip/grf_rk3399.h | 365 ++++++++++++++++++++++++ drivers/pinctrl/Kconfig | 9 + drivers/pinctrl/rockchip/Makefile | 1 + drivers/pinctrl/rockchip/pinctrl_rk3399.c | 282 ++++++++++++++++++ 4 files changed, 657 insertions(+) create mode 100644 arch/arm/include/asm/arch-rockchip/grf_rk3399.h create mode 100644 drivers/pinctrl/rockchip/pinctrl_rk3399.c