X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=drivers%2Fpinctrl%2Frockchip%2Fpinctrl_rk3288.c;h=cb13d30da8e9e8769a1053a6281f4126ac10af2d;hb=d53ecad92f06d2e38a5cbc13af7473867c7fa277;hp=0e7721e0b5e33b8400ffcd907c9b3e60278c3c00;hpb=bea705c993a13a4737705fc739318a1fe9a6a178;p=oweals%2Fu-boot.git diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3288.c b/drivers/pinctrl/rockchip/pinctrl_rk3288.c index 0e7721e0b5..cb13d30da8 100644 --- a/drivers/pinctrl/rockchip/pinctrl_rk3288.c +++ b/drivers/pinctrl/rockchip/pinctrl_rk3288.c @@ -17,7 +17,6 @@ #include #include #include -#include DECLARE_GLOBAL_DATA_PTR; @@ -158,6 +157,7 @@ static void pinctrl_rk3288_i2c_config(struct rk3288_grf *grf, GPIO0_C0_MASK << GPIO0_C0_SHIFT, GPIO0_C0_I2C0PMU_SCL << GPIO0_C0_SHIFT); break; +#ifndef CONFIG_SPL_BUILD case PERIPH_ID_I2C1: rk_clrsetreg(&grf->gpio8a_iomux, GPIO8A4_MASK << GPIO8A4_SHIFT | @@ -194,12 +194,14 @@ static void pinctrl_rk3288_i2c_config(struct rk3288_grf *grf, GPIO7C4_MASK << GPIO7C4_SHIFT, GPIO7C4_I2C5HDMI_SCL << GPIO7C4_SHIFT); break; +#endif default: debug("i2c id = %d iomux error!\n", i2c_id); break; } } +#ifndef CONFIG_SPL_BUILD static void pinctrl_rk3288_lcdc_config(struct rk3288_grf *grf, int lcd_id) { switch (lcd_id) { @@ -219,11 +221,13 @@ static void pinctrl_rk3288_lcdc_config(struct rk3288_grf *grf, int lcd_id) break; } } +#endif static int pinctrl_rk3288_spi_config(struct rk3288_grf *grf, enum periph_id spi_id, int cs) { switch (spi_id) { +#ifndef CONFIG_SPL_BUILD case PERIPH_ID_SPI0: switch (cs) { case 0: @@ -260,6 +264,7 @@ static int pinctrl_rk3288_spi_config(struct rk3288_grf *grf, GPIO7B5_SPI1_CSN0 << GPIO7B5_SHIFT | GPIO7B4_SPI1_CLK << GPIO7B4_SHIFT); break; +#endif case PERIPH_ID_SPI2: switch (cs) { case 0: @@ -297,6 +302,7 @@ err: static void pinctrl_rk3288_uart_config(struct rk3288_grf *grf, int uart_id) { switch (uart_id) { +#ifndef CONFIG_SPL_BUILD case PERIPH_ID_UART_BT: rk_clrsetreg(&grf->gpio4c_iomux, GPIO4C3_MASK << GPIO4C3_SHIFT | @@ -319,6 +325,7 @@ static void pinctrl_rk3288_uart_config(struct rk3288_grf *grf, int uart_id) GPIO5B1_UART1BB_SOUT << GPIO5B1_SHIFT | GPIO5B0_UART1BB_SIN << GPIO5B0_SHIFT); break; +#endif case PERIPH_ID_UART_DBG: rk_clrsetreg(&grf->gpio7ch_iomux, GPIO7C7_MASK << GPIO7C7_SHIFT | @@ -326,6 +333,7 @@ static void pinctrl_rk3288_uart_config(struct rk3288_grf *grf, int uart_id) GPIO7C7_UART2DBG_SOUT << GPIO7C7_SHIFT | GPIO7C6_UART2DBG_SIN << GPIO7C6_SHIFT); break; +#ifndef CONFIG_SPL_BUILD case PERIPH_ID_UART_GPS: rk_clrsetreg(&grf->gpio7b_iomux, GPIO7B2_MASK << GPIO7B2_SHIFT | @@ -349,6 +357,7 @@ static void pinctrl_rk3288_uart_config(struct rk3288_grf *grf, int uart_id) GPIO5B6_UART4EXP_SOUT << GPIO5B6_SHIFT | GPIO5B7_UART4EXP_SIN << GPIO5B7_SHIFT); break; +#endif default: debug("uart id = %d iomux error!\n", uart_id); break; @@ -393,6 +402,7 @@ static void pinctrl_rk3288_sdmmc_config(struct rk3288_grf *grf, int mmc_id) } } +#ifndef CONFIG_SPL_BUILD static void pinctrl_rk3288_hdmi_config(struct rk3288_grf *grf, int hdmi_id) { switch (hdmi_id) { @@ -407,6 +417,7 @@ static void pinctrl_rk3288_hdmi_config(struct rk3288_grf *grf, int hdmi_id) break; } } +#endif static int rk3288_pinctrl_request(struct udevice *dev, int func, int flags) { @@ -441,17 +452,19 @@ static int rk3288_pinctrl_request(struct udevice *dev, int func, int flags) case PERIPH_ID_UART4: pinctrl_rk3288_uart_config(priv->grf, func); break; +#ifndef CONFIG_SPL_BUILD case PERIPH_ID_LCDC0: case PERIPH_ID_LCDC1: pinctrl_rk3288_lcdc_config(priv->grf, func); break; + case PERIPH_ID_HDMI: + pinctrl_rk3288_hdmi_config(priv->grf, func); + break; +#endif case PERIPH_ID_SDMMC0: case PERIPH_ID_SDMMC1: pinctrl_rk3288_sdmmc_config(priv->grf, func); break; - case PERIPH_ID_HDMI: - pinctrl_rk3288_hdmi_config(priv->grf, func); - break; default: return -EINVAL; } @@ -462,10 +475,11 @@ static int rk3288_pinctrl_request(struct udevice *dev, int func, int flags) static int rk3288_pinctrl_get_periph_id(struct udevice *dev, struct udevice *periph) { +#if !CONFIG_IS_ENABLED(OF_PLATDATA) u32 cell[3]; int ret; - ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset, + ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(periph), "interrupts", cell, ARRAY_SIZE(cell)); if (ret < 0) return -EINVAL; @@ -489,7 +503,10 @@ static int rk3288_pinctrl_get_periph_id(struct udevice *dev, return PERIPH_ID_I2C4; case 65: return PERIPH_ID_I2C5; + case 103: + return PERIPH_ID_HDMI; } +#endif return -ENOENT; } @@ -506,18 +523,16 @@ static int rk3288_pinctrl_set_state_simple(struct udevice *dev, } #ifndef CONFIG_SPL_BUILD -static int rk3288_pinctrl_set_pins(struct udevice *dev, int banknum, int index, - int muxval, int flags) +int rk3288_pinctrl_get_pin_info(struct rk3288_pinctrl_priv *priv, + int banknum, int ind, u32 **addrp, uint *shiftp, + uint *maskp) { - struct rk3288_pinctrl_priv *priv = dev_get_priv(dev); struct rockchip_pin_bank *bank = &rk3288_pin_banks[banknum]; - uint shift, muxnum, ind = index; + uint muxnum; u32 *addr; - debug("%s: %x %x %x %x\n", __func__, banknum, index, muxval, flags); for (muxnum = 0; muxnum < 4; muxnum++) { struct rockchip_iomux *mux = &bank->iomux[muxnum]; - uint mask; if (ind >= 8) { ind -= 8; @@ -529,24 +544,73 @@ static int rk3288_pinctrl_set_pins(struct udevice *dev, int banknum, int index, else addr = (u32 *)priv->grf - 4; addr += mux->offset; - shift = ind & 7; + *shiftp = ind & 7; if (mux->type & IOMUX_WIDTH_4BIT) { - mask = 0xf; - shift *= 4; - if (shift >= 16) { - shift -= 16; + *maskp = 0xf; + *shiftp *= 4; + if (*shiftp >= 16) { + *shiftp -= 16; addr++; } } else { - mask = 3; - shift *= 2; + *maskp = 3; + *shiftp *= 2; } debug("%s: addr=%p, mask=%x, shift=%x\n", __func__, addr, - mask, shift); - rk_clrsetreg(addr, mask << shift, muxval << shift); - break; + *maskp, *shiftp); + *addrp = addr; + return 0; } + + return -EINVAL; +} + +static int rk3288_pinctrl_get_gpio_mux(struct udevice *dev, int banknum, + int index) +{ + struct rk3288_pinctrl_priv *priv = dev_get_priv(dev); + uint shift; + uint mask; + u32 *addr; + int ret; + + ret = rk3288_pinctrl_get_pin_info(priv, banknum, index, &addr, &shift, + &mask); + if (ret) + return ret; + return (readl(addr) & mask) >> shift; +} + +static int rk3288_pinctrl_set_pins(struct udevice *dev, int banknum, int index, + int muxval, int flags) +{ + struct rk3288_pinctrl_priv *priv = dev_get_priv(dev); + uint shift, ind = index; + uint mask; + uint value; + u32 *addr; + int ret; + + debug("%s: %x %x %x %x\n", __func__, banknum, index, muxval, flags); + ret = rk3288_pinctrl_get_pin_info(priv, banknum, index, &addr, &shift, + &mask); + if (ret) + return ret; + + /* + * PMU_GPIO0 registers cannot be selectively written so we cannot use + * rk_clrsetreg() here. However, the upper 16 bits are reserved and + * are ignored when written, so we can use the same code as for the + * other GPIO banks providing that we preserve the value of the other + * bits. + */ + value = readl(addr); + value &= ~(mask << shift); + value |= (mask << (shift + 16)) | (muxval << shift); + writel(value, addr); + + /* Handle pullup/pulldown */ if (flags) { uint val = 0; @@ -562,7 +626,12 @@ static int rk3288_pinctrl_set_pins(struct udevice *dev, int banknum, int index, addr = &priv->grf->gpio1_p[banknum - 1][ind]; debug("%s: addr=%p, val=%x, shift=%x\n", __func__, addr, val, shift); - rk_clrsetreg(addr, 3 << shift, val << shift); + + /* As above, rk_clrsetreg() cannot be used here. */ + value = readl(addr); + value &= ~(mask << shift); + value |= (3 << (shift + 16)) | (val << shift); + writel(value, addr); } return 0; @@ -572,10 +641,10 @@ static int rk3288_pinctrl_set_state(struct udevice *dev, struct udevice *config) { const void *blob = gd->fdt_blob; int pcfg_node, ret, flags, count, i; - u32 cell[40], *ptr; + u32 cell[60], *ptr; debug("%s: %s %s\n", __func__, dev->name, config->name); - ret = fdtdec_get_int_array_count(blob, config->of_offset, + ret = fdtdec_get_int_array_count(blob, dev_of_offset(config), "rockchip,pins", cell, ARRAY_SIZE(cell)); if (ret < 0) { @@ -604,18 +673,13 @@ static int rk3288_pinctrl_set_state(struct udevice *dev, struct udevice *config) static struct pinctrl_ops rk3288_pinctrl_ops = { #ifndef CONFIG_SPL_BUILD .set_state = rk3288_pinctrl_set_state, + .get_gpio_mux = rk3288_pinctrl_get_gpio_mux, #endif .set_state_simple = rk3288_pinctrl_set_state_simple, .request = rk3288_pinctrl_request, .get_periph_id = rk3288_pinctrl_get_periph_id, }; -static int rk3288_pinctrl_bind(struct udevice *dev) -{ - /* scan child GPIO banks */ - return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); -} - #ifndef CONFIG_SPL_BUILD static int rk3288_pinctrl_parse_tables(struct rk3288_pinctrl_priv *priv, struct rockchip_pin_bank *banks, @@ -667,11 +731,13 @@ static const struct udevice_id rk3288_pinctrl_ids[] = { }; U_BOOT_DRIVER(pinctrl_rk3288) = { - .name = "pinctrl_rk3288", + .name = "rockchip_rk3288_pinctrl", .id = UCLASS_PINCTRL, .of_match = rk3288_pinctrl_ids, .priv_auto_alloc_size = sizeof(struct rk3288_pinctrl_priv), .ops = &rk3288_pinctrl_ops, - .bind = rk3288_pinctrl_bind, +#if !CONFIG_IS_ENABLED(OF_PLATDATA) + .bind = dm_scan_fdt_dev, +#endif .probe = rk3288_pinctrl_probe, };