#include <asm/arch/periph.h>
#include <asm/arch/pmu_rk3288.h>
#include <dm/pinctrl.h>
-#include <dm/root.h>
DECLARE_GLOBAL_DATA_PTR;
}
}
+static void pinctrl_rk3288_gmac_config(struct rk3288_grf *grf, int gmac_id)
+{
+ switch (gmac_id) {
+ case PERIPH_ID_GMAC:
+ rk_clrsetreg(&grf->gpio3dl_iomux,
+ GPIO3D3_MASK << GPIO3D3_SHIFT |
+ GPIO3D2_MASK << GPIO3D2_SHIFT |
+ GPIO3D2_MASK << GPIO3D1_SHIFT |
+ GPIO3D0_MASK << GPIO3D0_SHIFT,
+ GPIO3D3_MAC_RXD3 << GPIO3D3_SHIFT |
+ GPIO3D2_MAC_RXD2 << GPIO3D2_SHIFT |
+ GPIO3D1_MAC_TXD3 << GPIO3D1_SHIFT |
+ GPIO3D0_MAC_TXD2 << GPIO3D0_SHIFT);
+
+ rk_clrsetreg(&grf->gpio3dh_iomux,
+ GPIO3D7_MASK << GPIO3D7_SHIFT |
+ GPIO3D6_MASK << GPIO3D6_SHIFT |
+ GPIO3D5_MASK << GPIO3D5_SHIFT |
+ GPIO3D4_MASK << GPIO3D4_SHIFT,
+ GPIO3D7_MAC_RXD1 << GPIO3D7_SHIFT |
+ GPIO3D6_MAC_RXD0 << GPIO3D6_SHIFT |
+ GPIO3D5_MAC_TXD1 << GPIO3D5_SHIFT |
+ GPIO3D4_MAC_TXD0 << GPIO3D4_SHIFT);
+
+ /* switch the Tx pins to 12ma drive-strength */
+ rk_clrsetreg(&grf->gpio1_e[2][3],
+ GPIO_BIAS_MASK |
+ (GPIO_BIAS_MASK << GPIO_BIAS_SHIFT(1)) |
+ (GPIO_BIAS_MASK << GPIO_BIAS_SHIFT(4)) |
+ (GPIO_BIAS_MASK << GPIO_BIAS_SHIFT(5)),
+ (GPIO_BIAS_12MA << GPIO_BIAS_SHIFT(0)) |
+ (GPIO_BIAS_12MA << GPIO_BIAS_SHIFT(1)) |
+ (GPIO_BIAS_12MA << GPIO_BIAS_SHIFT(4)) |
+ (GPIO_BIAS_12MA << GPIO_BIAS_SHIFT(5)));
+
+ /* Set normal pull for all GPIO3D pins */
+ rk_clrsetreg(&grf->gpio1_p[2][3],
+ (GPIO_PULL_MASK << GPIO_PULL_SHIFT(0)) |
+ (GPIO_PULL_MASK << GPIO_PULL_SHIFT(1)) |
+ (GPIO_PULL_MASK << GPIO_PULL_SHIFT(2)) |
+ (GPIO_PULL_MASK << GPIO_PULL_SHIFT(3)) |
+ (GPIO_PULL_MASK << GPIO_PULL_SHIFT(4)) |
+ (GPIO_PULL_MASK << GPIO_PULL_SHIFT(5)) |
+ (GPIO_PULL_MASK << GPIO_PULL_SHIFT(5)) |
+ (GPIO_PULL_MASK << GPIO_PULL_SHIFT(7)),
+ (GPIO_PULL_NORMAL << GPIO_PULL_SHIFT(0)) |
+ (GPIO_PULL_NORMAL << GPIO_PULL_SHIFT(1)) |
+ (GPIO_PULL_NORMAL << GPIO_PULL_SHIFT(2)) |
+ (GPIO_PULL_NORMAL << GPIO_PULL_SHIFT(3)) |
+ (GPIO_PULL_NORMAL << GPIO_PULL_SHIFT(4)) |
+ (GPIO_PULL_NORMAL << GPIO_PULL_SHIFT(5)) |
+ (GPIO_PULL_NORMAL << GPIO_PULL_SHIFT(6)) |
+ (GPIO_PULL_NORMAL << GPIO_PULL_SHIFT(7)));
+
+ rk_clrsetreg(&grf->gpio4al_iomux,
+ GPIO4A3_MASK << GPIO4A3_SHIFT |
+ GPIO4A1_MASK << GPIO4A1_SHIFT |
+ GPIO4A0_MASK << GPIO4A0_SHIFT,
+ GPIO4A3_MAC_CLK << GPIO4A3_SHIFT |
+ GPIO4A1_MAC_TXDV << GPIO4A1_SHIFT |
+ GPIO4A0_MAC_MDC << GPIO4A0_SHIFT);
+
+ rk_clrsetreg(&grf->gpio4ah_iomux,
+ GPIO4A6_MASK << GPIO4A6_SHIFT |
+ GPIO4A5_MASK << GPIO4A5_SHIFT |
+ GPIO4A4_MASK << GPIO4A4_SHIFT,
+ GPIO4A6_MAC_RXCLK << GPIO4A6_SHIFT |
+ GPIO4A5_MAC_MDIO << GPIO4A5_SHIFT |
+ GPIO4A4_MAC_TXEN << GPIO4A4_SHIFT);
+
+ /* switch GPIO4A4 to 12ma drive-strength */
+ rk_clrsetreg(&grf->gpio1_e[3][0],
+ GPIO_BIAS_MASK << GPIO_BIAS_SHIFT(4),
+ GPIO_BIAS_12MA << GPIO_BIAS_SHIFT(4));
+
+ /* Set normal pull for all GPIO4A pins */
+ rk_clrsetreg(&grf->gpio1_p[3][0],
+ (GPIO_PULL_MASK << GPIO_PULL_SHIFT(0)) |
+ (GPIO_PULL_MASK << GPIO_PULL_SHIFT(1)) |
+ (GPIO_PULL_MASK << GPIO_PULL_SHIFT(2)) |
+ (GPIO_PULL_MASK << GPIO_PULL_SHIFT(3)) |
+ (GPIO_PULL_MASK << GPIO_PULL_SHIFT(4)) |
+ (GPIO_PULL_MASK << GPIO_PULL_SHIFT(5)) |
+ (GPIO_PULL_MASK << GPIO_PULL_SHIFT(5)) |
+ (GPIO_PULL_MASK << GPIO_PULL_SHIFT(7)),
+ (GPIO_PULL_NORMAL << GPIO_PULL_SHIFT(0)) |
+ (GPIO_PULL_NORMAL << GPIO_PULL_SHIFT(1)) |
+ (GPIO_PULL_NORMAL << GPIO_PULL_SHIFT(2)) |
+ (GPIO_PULL_NORMAL << GPIO_PULL_SHIFT(3)) |
+ (GPIO_PULL_NORMAL << GPIO_PULL_SHIFT(4)) |
+ (GPIO_PULL_NORMAL << GPIO_PULL_SHIFT(5)) |
+ (GPIO_PULL_NORMAL << GPIO_PULL_SHIFT(6)) |
+ (GPIO_PULL_NORMAL << GPIO_PULL_SHIFT(7)));
+
+ rk_clrsetreg(&grf->gpio4bl_iomux,
+ GPIO4B1_MASK << GPIO4B1_SHIFT,
+ GPIO4B1_MAC_TXCLK << GPIO4B1_SHIFT);
+
+ /* switch GPIO4B1 to 12ma drive-strength */
+ rk_clrsetreg(&grf->gpio1_e[3][1],
+ GPIO_BIAS_MASK << GPIO_BIAS_SHIFT(1),
+ GPIO_BIAS_12MA << GPIO_BIAS_SHIFT(1));
+
+ /* Set pull normal for GPIO4B1 */
+ rk_clrsetreg(&grf->gpio1_p[3][1],
+ (GPIO_PULL_MASK << GPIO_PULL_SHIFT(1)),
+ (GPIO_PULL_NORMAL << GPIO_PULL_SHIFT(1)));
+
+ break;
+ default:
+ printf("gmac id = %d iomux error!\n", gmac_id);
+ break;
+ }
+}
+
#ifndef CONFIG_SPL_BUILD
static void pinctrl_rk3288_hdmi_config(struct rk3288_grf *grf, int hdmi_id)
{
case PERIPH_ID_SDMMC1:
pinctrl_rk3288_sdmmc_config(priv->grf, func);
break;
+ case PERIPH_ID_GMAC:
+ pinctrl_rk3288_gmac_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,
- "interrupts", cell, ARRAY_SIZE(cell));
+ ret = dev_read_u32_array(periph, "interrupts", cell, ARRAY_SIZE(cell));
if (ret < 0)
return -EINVAL;
switch (cell[1]) {
+ case 27:
+ return PERIPH_ID_GMAC;
case 44:
return PERIPH_ID_SPI0;
case 45:
case 103:
return PERIPH_ID_HDMI;
}
+#endif
return -ENOENT;
}
struct rk3288_pinctrl_priv *priv = dev_get_priv(dev);
uint shift, ind = index;
uint mask;
+ uint value;
u32 *addr;
int ret;
&mask);
if (ret)
return ret;
- rk_clrsetreg(addr, mask << shift, muxval << shift);
- /* Handle pullup/pulldown */
+ /*
+ * 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/drive-strength */
if (flags) {
uint val = 0;
val = 1;
else if (flags & (1 << PIN_CONFIG_BIAS_PULL_DOWN))
val = 2;
+ else if (flags & (1 << PIN_CONFIG_DRIVE_STRENGTH))
+ val = 3;
+
shift = (index & 7) * 2;
ind = index >> 3;
if (banknum == 0)
addr = &priv->pmu->gpio0pull[ind];
+ else if (flags & (1 << PIN_CONFIG_DRIVE_STRENGTH))
+ addr = &priv->grf->gpio1_e[banknum - 1][ind];
else
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;
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) {
if (flags < 0)
return flags;
+ if (fdtdec_get_int(blob, pcfg_node, "drive-strength", 0) == 12)
+ flags |= 1 << PIN_CONFIG_DRIVE_STRENGTH;
+
ret = rk3288_pinctrl_set_pins(dev, ptr[0], ptr[1], ptr[2],
flags);
if (ret)
.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,
};