Parcourir la source

Merge git://git.denx.de/u-boot-rockchip

Tom Rini il y a 9 ans
Parent
commit
378f9134eb

+ 16 - 0
arch/arm/dts/rk3288-firefly.dtsi

@@ -146,6 +146,22 @@
 	status = "okay";
 };
 
+&gmac {
+	assigned-clocks = <&cru SCLK_MAC>;
+	assigned-clock-parents = <&ext_gmac>;
+	clock_in_out = "input";
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii_pins>, <&phy_rst>, <&phy_pmeb>, <&phy_int>;
+	phy-supply = <&vcc_lan>;
+	phy-mode = "rgmii";
+	snps,reset-active-low;
+	snps,reset-delays-us = <0 10000 1000000>;
+	snps,reset-gpio = <&gpio4 8 GPIO_ACTIVE_LOW>;
+	tx_delay = <0x30>;
+	rx_delay = <0x10>;
+	status = "okay";
+};
+
 &hdmi {
 	ddc-i2c-bus = <&i2c5>;
 	status = "okay";

+ 1 - 1
arch/arm/dts/rk3288-rock2-square.dts

@@ -111,7 +111,7 @@
 };
 
 &gmac {
-	status = "ok";
+	status = "okay";
 };
 
 &hdmi {

+ 17 - 0
arch/arm/include/asm/arch-rockchip/cru_rk3288.h

@@ -90,6 +90,23 @@ enum {
 	SDIO0_DIV_MASK		= 0x3f,
 };
 
+/* CRU_CLKSEL21_CON */
+enum {
+	MAC_DIV_CON_SHIFT = 0xf,
+	MAC_DIV_CON_MASK = 0x1f,
+
+	RMII_EXTCLK_SHIFT = 4,
+	RMII_EXTCLK_MASK = 1,
+	RMII_EXTCLK_SELECT_INT_DIV_CLK = 0,
+	RMII_EXTCLK_SELECT_EXT_CLK = 1,
+
+	EMAC_PLL_SHIFT = 0,
+	EMAC_PLL_MASK = 0x3,
+	EMAC_PLL_SELECT_NEW = 0x0,
+	EMAC_PLL_SELECT_CODEC = 0x1,
+	EMAC_PLL_SELECT_GENERAL = 0x2,
+};
+
 /* CRU_CLKSEL25_CON */
 enum {
 	SPI1_PLL_SHIFT		= 0xf,

+ 53 - 0
arch/arm/include/asm/arch-rockchip/grf_rk3288.h

@@ -718,6 +718,40 @@ enum {
 	MSCH0_MAINPARTIALPOP_MASK = 1,
 };
 
+/* GRF_SOC_CON1 */
+enum {
+	RMII_MODE_SHIFT = 0xe,
+	RMII_MODE_MASK = 1,
+	RMII_MODE = 1,
+
+	GMAC_CLK_SEL_SHIFT	= 0xc,
+	GMAC_CLK_SEL_MASK	= 3,
+	GMAC_CLK_SEL_125M	= 0,
+	GMAC_CLK_SEL_25M	= 0x3,
+	GMAC_CLK_SEL_2_5M	= 0x2,
+
+	RMII_CLK_SEL_SHIFT	= 0xb,
+	RMII_CLK_SEL_MASK	= 1,
+	RMII_CLK_SEL_2_5M	= 0,
+	RMII_CLK_SEL_25M,
+
+	GMAC_SPEED_SHIFT	= 0xa,
+	GMAC_SPEED_MASK		= 1,
+	GMAC_SPEED_10M		= 0,
+	GMAC_SPEED_100M,
+
+	GMAC_FLOWCTRL_SHIFT	= 0x9,
+	GMAC_FLOWCTRL_MASK	= 1,
+
+	GMAC_PHY_INTF_SEL_SHIFT	= 0x6,
+	GMAC_PHY_INTF_SEL_MASK	= 0x7,
+	GMAC_PHY_INTF_SEL_RGMII	= 0x1,
+	GMAC_PHY_INTF_SEL_RMII	= 0x4,
+
+	HOST_REMAP_SHIFT	= 0x5,
+	HOST_REMAP_MASK		= 1
+};
+
 /* GRF_SOC_CON2 */
 enum {
 	UPCTL1_LPDDR3_ODT_EN_SHIFT = 0xd,
@@ -765,4 +799,23 @@ enum {
 	PWM_PWM			= 0,
 };
 
+/* GRF_SOC_CON3 */
+enum {
+	RXCLK_DLY_ENA_GMAC_SHIFT	= 0xf,
+	RXCLK_DLY_ENA_GMAC_MASK		= 1,
+	RXCLK_DLY_ENA_GMAC_DISABLE	= 0,
+	RXCLK_DLY_ENA_GMAC_ENABLE,
+
+	TXCLK_DLY_ENA_GMAC_SHIFT	= 0xe,
+	TXCLK_DLY_ENA_GMAC_MASK		= 1,
+	TXCLK_DLY_ENA_GMAC_DISABLE	= 0,
+	TXCLK_DLY_ENA_GMAC_ENABLE,
+
+	CLK_RX_DL_CFG_GMAC_SHIFT	= 0x7,
+	CLK_RX_DL_CFG_GMAC_MASK		= 0x7f,
+
+	CLK_TX_DL_CFG_GMAC_SHIFT	= 0x0,
+	CLK_TX_DL_CFG_GMAC_MASK		= 0x7f,
+};
+
 #endif

+ 14 - 0
drivers/clk/clk_rk3288.c

@@ -326,6 +326,17 @@ static int pll_para_config(ulong freq_hz, struct pll_div *div, uint *ext_div)
 	return 0;
 }
 
+static int rockchip_mac_set_clk(struct rk3288_cru *cru,
+				  int periph, uint freq)
+{
+	/* Assuming mac_clk is fed by an external clock */
+	rk_clrsetreg(&cru->cru_clksel_con[21],
+		     RMII_EXTCLK_MASK << RMII_EXTCLK_SHIFT,
+		     RMII_EXTCLK_SELECT_EXT_CLK << RMII_EXTCLK_SHIFT);
+
+	 return 0;
+}
+
 static int rockchip_vop_set_clk(struct rk3288_cru *cru, struct rk3288_grf *grf,
 				int periph, unsigned int rate_hz)
 {
@@ -759,6 +770,9 @@ static ulong rk3288_set_periph_rate(struct udevice *dev, int periph, ulong rate)
 		new_rate = rockchip_spi_set_clk(cru, gclk_rate, periph, rate);
 		break;
 #ifndef CONFIG_SPL_BUILD
+	case SCLK_MAC:
+		new_rate = rockchip_mac_set_clk(priv->cru, periph, rate);
+		break;
 	case DCLK_VOP0:
 	case DCLK_VOP1:
 		new_rate = rockchip_vop_set_clk(cru, priv->grf, periph, rate);

+ 70 - 6
drivers/net/designware.c

@@ -24,7 +24,12 @@ DECLARE_GLOBAL_DATA_PTR;
 
 static int dw_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
 {
+#ifdef CONFIG_DM_ETH
+	struct dw_eth_dev *priv = dev_get_priv((struct udevice *)bus->priv);
+	struct eth_mac_regs *mac_p = priv->mac_regs_p;
+#else
 	struct eth_mac_regs *mac_p = bus->priv;
+#endif
 	ulong start;
 	u16 miiaddr;
 	int timeout = CONFIG_MDIO_TIMEOUT;
@@ -47,7 +52,12 @@ static int dw_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
 static int dw_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
 			u16 val)
 {
+#ifdef CONFIG_DM_ETH
+	struct dw_eth_dev *priv = dev_get_priv((struct udevice *)bus->priv);
+	struct eth_mac_regs *mac_p = priv->mac_regs_p;
+#else
 	struct eth_mac_regs *mac_p = bus->priv;
+#endif
 	ulong start;
 	u16 miiaddr;
 	int ret = -ETIMEDOUT, timeout = CONFIG_MDIO_TIMEOUT;
@@ -70,7 +80,41 @@ static int dw_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
 	return ret;
 }
 
-static int dw_mdio_init(const char *name, struct eth_mac_regs *mac_regs_p)
+#if CONFIG_DM_ETH
+static int dw_mdio_reset(struct mii_dev *bus)
+{
+	struct udevice *dev = bus->priv;
+	struct dw_eth_dev *priv = dev_get_priv(dev);
+	struct dw_eth_pdata *pdata = dev_get_platdata(dev);
+	int ret;
+
+	if (!dm_gpio_is_valid(&priv->reset_gpio))
+		return 0;
+
+	/* reset the phy */
+	ret = dm_gpio_set_value(&priv->reset_gpio, 0);
+	if (ret)
+		return ret;
+
+	udelay(pdata->reset_delays[0]);
+
+	ret = dm_gpio_set_value(&priv->reset_gpio, 1);
+	if (ret)
+		return ret;
+
+	udelay(pdata->reset_delays[1]);
+
+	ret = dm_gpio_set_value(&priv->reset_gpio, 0);
+	if (ret)
+		return ret;
+
+	udelay(pdata->reset_delays[2]);
+
+	return 0;
+}
+#endif
+
+static int dw_mdio_init(const char *name, void *priv)
 {
 	struct mii_dev *bus = mdio_alloc();
 
@@ -82,8 +126,11 @@ static int dw_mdio_init(const char *name, struct eth_mac_regs *mac_regs_p)
 	bus->read = dw_mdio_read;
 	bus->write = dw_mdio_write;
 	snprintf(bus->name, sizeof(bus->name), "%s", name);
+#ifdef CONFIG_DM_ETH
+	bus->reset = dw_mdio_reset;
+#endif
 
-	bus->priv = (void *)mac_regs_p;
+	bus->priv = priv;
 
 	return mdio_register(bus);
 }
@@ -611,7 +658,7 @@ static int designware_eth_probe(struct udevice *dev)
 	priv->interface = pdata->phy_interface;
 	priv->max_speed = pdata->max_speed;
 
-	dw_mdio_init(dev->name, priv->mac_regs_p);
+	dw_mdio_init(dev->name, dev);
 	priv->bus = miiphy_get_dev_by_name(dev->name);
 
 	ret = dw_phy_init(priv, dev);
@@ -642,9 +689,13 @@ static const struct eth_ops designware_eth_ops = {
 
 static int designware_eth_ofdata_to_platdata(struct udevice *dev)
 {
-	struct eth_pdata *pdata = dev_get_platdata(dev);
+	struct dw_eth_pdata *dw_pdata = dev_get_platdata(dev);
+	struct dw_eth_dev *priv = dev_get_priv(dev);
+	struct eth_pdata *pdata = &dw_pdata->eth_pdata;
 	const char *phy_mode;
 	const fdt32_t *cell;
+	int reset_flags = GPIOD_IS_OUT;
+	int ret = 0;
 
 	pdata->iobase = dev_get_addr(dev);
 	pdata->phy_interface = -1;
@@ -661,7 +712,20 @@ static int designware_eth_ofdata_to_platdata(struct udevice *dev)
 	if (cell)
 		pdata->max_speed = fdt32_to_cpu(*cell);
 
-	return 0;
+	if (fdtdec_get_bool(gd->fdt_blob, dev->of_offset,
+			    "snps,reset-active-low"))
+		reset_flags |= GPIOD_ACTIVE_LOW;
+
+	ret = gpio_request_by_name(dev, "snps,reset-gpio", 0,
+		&priv->reset_gpio, reset_flags);
+	if (ret == 0) {
+		ret = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset,
+			"snps,reset-delays-us", dw_pdata->reset_delays, 3);
+	} else if (ret == -ENOENT) {
+		ret = 0;
+	}
+
+	return ret;
 }
 
 static const struct udevice_id designware_eth_ids[] = {
@@ -680,7 +744,7 @@ U_BOOT_DRIVER(eth_designware) = {
 	.remove	= designware_eth_remove,
 	.ops	= &designware_eth_ops,
 	.priv_auto_alloc_size = sizeof(struct dw_eth_dev),
-	.platdata_auto_alloc_size = sizeof(struct eth_pdata),
+	.platdata_auto_alloc_size = sizeof(struct dw_eth_pdata),
 	.flags = DM_FLAG_ALLOC_PRIV_DMA,
 };
 

+ 10 - 0
drivers/net/designware.h

@@ -8,6 +8,8 @@
 #ifndef _DW_ETH_H
 #define _DW_ETH_H
 
+#include <asm/gpio.h>
+
 #define CONFIG_TX_DESCR_NUM	16
 #define CONFIG_RX_DESCR_NUM	16
 #define CONFIG_ETH_BUFSIZE	2048
@@ -232,8 +234,16 @@ struct dw_eth_dev {
 #ifndef CONFIG_DM_ETH
 	struct eth_device *dev;
 #endif
+	struct gpio_desc reset_gpio;
 	struct phy_device *phydev;
 	struct mii_dev *bus;
 };
 
+#ifdef CONFIG_DM_ETH
+struct dw_eth_pdata {
+	struct eth_pdata eth_pdata;
+	u32 reset_delays[3];
+};
+#endif
+
 #endif

+ 1 - 1
drivers/pinctrl/rockchip/pinctrl_rk3288.c

@@ -623,7 +623,7 @@ 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,