#include <asm/arch/periph.h>
#include <asm/arch/pmu_rk3288.h>
#include <dm/pinctrl.h>
-#include <dm/root.h>
DECLARE_GLOBAL_DATA_PTR;
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 |
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) {
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:
GPIO7B5_SPI1_CSN0 << GPIO7B5_SHIFT |
GPIO7B4_SPI1_CLK << GPIO7B4_SHIFT);
break;
+#endif
case PERIPH_ID_SPI2:
switch (cs) {
case 0:
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 |
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 |
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 |
GPIO5B6_UART4EXP_SOUT << GPIO5B6_SHIFT |
GPIO5B7_UART4EXP_SIN << GPIO5B7_SHIFT);
break;
+#endif
default:
debug("uart id = %d iomux error!\n", uart_id);
break;
}
}
+#ifndef CONFIG_SPL_BUILD
static void pinctrl_rk3288_hdmi_config(struct rk3288_grf *grf, int hdmi_id)
{
switch (hdmi_id) {
break;
}
}
+#endif
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;
}
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;
return PERIPH_ID_I2C4;
case 65:
return PERIPH_ID_I2C5;
+ case 103:
+ return PERIPH_ID_HDMI;
}
+#endif
return -ENOENT;
}
}
#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;
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;
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;
{
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) {
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,
};
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,
};