mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-25 06:00:43 +00:00
Merge branch 'master' of git://git.denx.de/u-boot-net
Signed-off-by: Tom Rini <trini@konsulko.com> Conflicts: drivers/net/zynq_gem.c
This commit is contained in:
commit
2ee490a024
22 changed files with 1341 additions and 631 deletions
|
@ -547,6 +547,7 @@
|
|||
active_slave = <0>;
|
||||
cpts_clock_mult = <0x80000000>;
|
||||
cpts_clock_shift = <29>;
|
||||
syscon = <&scm_conf>;
|
||||
ranges;
|
||||
|
||||
davinci_mdio: mdio@4a101000 {
|
||||
|
|
|
@ -1411,7 +1411,7 @@
|
|||
ti,irqs-safe-map = <0>;
|
||||
};
|
||||
|
||||
mac: ethernet@4a100000 {
|
||||
mac: ethernet@48484000 {
|
||||
compatible = "ti,cpsw";
|
||||
ti,hwmods = "gmac";
|
||||
clocks = <&dpll_gmac_ck>, <&gmac_gmii_ref_clk_div>;
|
||||
|
@ -1426,6 +1426,7 @@
|
|||
active_slave = <0>;
|
||||
cpts_clock_mult = <0x80000000>;
|
||||
cpts_clock_shift = <29>;
|
||||
syscon = <&scm_conf>;
|
||||
reg = <0x48484000 0x1000
|
||||
0x48485200 0x2E00>;
|
||||
#address-cells = <1>;
|
||||
|
|
|
@ -116,4 +116,16 @@ struct watchdog {
|
|||
#define CPSW_BASE 0x48484000
|
||||
#define CPSW_MDIO_BASE 0x48485000
|
||||
|
||||
/* gmii_sel register defines */
|
||||
#define GMII1_SEL_MII 0x0
|
||||
#define GMII1_SEL_RMII 0x1
|
||||
#define GMII1_SEL_RGMII 0x2
|
||||
#define GMII2_SEL_MII (GMII1_SEL_MII << 4)
|
||||
#define GMII2_SEL_RMII (GMII1_SEL_RMII << 4)
|
||||
#define GMII2_SEL_RGMII (GMII1_SEL_RGMII << 4)
|
||||
|
||||
#define MII_MODE_ENABLE (GMII1_SEL_MII | GMII2_SEL_MII)
|
||||
#define RMII_MODE_ENABLE (GMII1_SEL_RMII | GMII2_SEL_RMII)
|
||||
#define RGMII_MODE_ENABLE (GMII1_SEL_RGMII | GMII2_SEL_RGMII)
|
||||
|
||||
#endif /* _CPU_H */
|
||||
|
|
|
@ -47,3 +47,4 @@ CONFIG_USB_GADGET_DOWNLOAD=y
|
|||
CONFIG_G_DNL_MANUFACTURER="Texas Instruments"
|
||||
CONFIG_G_DNL_VENDOR_NUM=0x0403
|
||||
CONFIG_G_DNL_PRODUCT_NUM=0xbd00
|
||||
CONFIG_DM_ETH=y
|
||||
|
|
|
@ -51,3 +51,4 @@ CONFIG_USB_GADGET_DOWNLOAD=y
|
|||
CONFIG_G_DNL_MANUFACTURER="Texas Instruments"
|
||||
CONFIG_G_DNL_VENDOR_NUM=0x0403
|
||||
CONFIG_G_DNL_PRODUCT_NUM=0xbd00
|
||||
CONFIG_DM_ETH=y
|
||||
|
|
|
@ -50,3 +50,4 @@ CONFIG_USB_GADGET_DOWNLOAD=y
|
|||
CONFIG_G_DNL_MANUFACTURER="Texas Instruments"
|
||||
CONFIG_G_DNL_VENDOR_NUM=0x0451
|
||||
CONFIG_G_DNL_PRODUCT_NUM=0xd022
|
||||
CONFIG_DM_ETH=y
|
||||
|
|
25
doc/device-tree-bindings/net/ti,dp83867.txt
Normal file
25
doc/device-tree-bindings/net/ti,dp83867.txt
Normal file
|
@ -0,0 +1,25 @@
|
|||
* Texas Instruments - dp83867 Giga bit ethernet phy
|
||||
|
||||
Required properties:
|
||||
- reg - The ID number for the phy, usually a small integer
|
||||
- ti,rx-internal-delay - RGMII Recieve Clock Delay - see dt-bindings/net/ti-dp83867.h
|
||||
for applicable values
|
||||
- ti,tx-internal-delay - RGMII Transmit Clock Delay - see dt-bindings/net/ti-dp83867.h
|
||||
for applicable values
|
||||
- ti,fifo-depth - Transmitt FIFO depth- see dt-bindings/net/ti-dp83867.h
|
||||
for applicable values
|
||||
|
||||
Default child nodes are standard Ethernet PHY device
|
||||
nodes as described in doc/devicetree/bindings/net/ethernet.txt
|
||||
|
||||
Example:
|
||||
|
||||
ethernet-phy@0 {
|
||||
reg = <0>;
|
||||
ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>;
|
||||
ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_75_NS>;
|
||||
ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
|
||||
};
|
||||
|
||||
Datasheet can be found:
|
||||
http://www.ti.com/product/DP83867IR/datasheet
|
|
@ -721,3 +721,17 @@ int device_set_name(struct udevice *dev, const char *name)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool of_device_is_compatible(struct udevice *dev, const char *compat)
|
||||
{
|
||||
const void *fdt = gd->fdt_blob;
|
||||
|
||||
return !fdt_node_check_compatible(fdt, dev->of_offset, compat);
|
||||
}
|
||||
|
||||
bool of_machine_is_compatible(const char *compat)
|
||||
{
|
||||
const void *fdt = gd->fdt_blob;
|
||||
|
||||
return !fdt_node_check_compatible(fdt, 0, compat);
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ obj-$(CONFIG_SMC91111) += smc91111.o
|
|||
obj-$(CONFIG_SMC911X) += smc911x.o
|
||||
obj-$(CONFIG_DRIVER_TI_EMAC) += davinci_emac.o
|
||||
obj-$(CONFIG_TSEC_ENET) += tsec.o fsl_mdio.o
|
||||
obj-$(CONFIG_DRIVER_TI_CPSW) += cpsw.o
|
||||
obj-$(CONFIG_DRIVER_TI_CPSW) += cpsw.o cpsw-common.o
|
||||
obj-$(CONFIG_FMAN_ENET) += fsl_mdio.o
|
||||
obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o
|
||||
obj-$(CONFIG_ULI526X) += uli526x.o
|
||||
|
|
121
drivers/net/cpsw-common.c
Normal file
121
drivers/net/cpsw-common.c
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* CPSW common - libs used across TI ethernet devices.
|
||||
*
|
||||
* Copyright (C) 2016, Texas Instruments, Incorporated
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <fdt_support.h>
|
||||
#include <asm/io.h>
|
||||
#include <cpsw.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define CTRL_MAC_REG(offset, id) ((offset) + 0x8 * (id))
|
||||
|
||||
static int davinci_emac_3517_get_macid(struct udevice *dev, u16 offset,
|
||||
int slave, u8 *mac_addr)
|
||||
{
|
||||
void *fdt = (void *)gd->fdt_blob;
|
||||
int node = dev->of_offset;
|
||||
u32 macid_lsb;
|
||||
u32 macid_msb;
|
||||
fdt32_t gmii = 0;
|
||||
int syscon;
|
||||
u32 addr;
|
||||
|
||||
syscon = fdtdec_lookup_phandle(fdt, node, "syscon");
|
||||
if (syscon < 0) {
|
||||
error("Syscon offset not found\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
addr = (u32)map_physmem(fdt_translate_address(fdt, syscon, &gmii),
|
||||
sizeof(u32), MAP_NOCACHE);
|
||||
if (addr == FDT_ADDR_T_NONE) {
|
||||
error("Not able to get syscon address to get mac efuse address\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
addr += CTRL_MAC_REG(offset, slave);
|
||||
|
||||
/* try reading mac address from efuse */
|
||||
macid_lsb = readl(addr);
|
||||
macid_msb = readl(addr + 4);
|
||||
|
||||
mac_addr[0] = (macid_msb >> 16) & 0xff;
|
||||
mac_addr[1] = (macid_msb >> 8) & 0xff;
|
||||
mac_addr[2] = macid_msb & 0xff;
|
||||
mac_addr[3] = (macid_lsb >> 16) & 0xff;
|
||||
mac_addr[4] = (macid_lsb >> 8) & 0xff;
|
||||
mac_addr[5] = macid_lsb & 0xff;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpsw_am33xx_cm_get_macid(struct udevice *dev, u16 offset, int slave,
|
||||
u8 *mac_addr)
|
||||
{
|
||||
void *fdt = (void *)gd->fdt_blob;
|
||||
int node = dev->of_offset;
|
||||
u32 macid_lo;
|
||||
u32 macid_hi;
|
||||
fdt32_t gmii = 0;
|
||||
int syscon;
|
||||
u32 addr;
|
||||
|
||||
syscon = fdtdec_lookup_phandle(fdt, node, "syscon");
|
||||
if (syscon < 0) {
|
||||
error("Syscon offset not found\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
addr = (u32)map_physmem(fdt_translate_address(fdt, syscon, &gmii),
|
||||
sizeof(u32), MAP_NOCACHE);
|
||||
if (addr == FDT_ADDR_T_NONE) {
|
||||
error("Not able to get syscon address to get mac efuse address\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
addr += CTRL_MAC_REG(offset, slave);
|
||||
|
||||
/* try reading mac address from efuse */
|
||||
macid_lo = readl(addr);
|
||||
macid_hi = readl(addr + 4);
|
||||
|
||||
mac_addr[5] = (macid_lo >> 8) & 0xff;
|
||||
mac_addr[4] = macid_lo & 0xff;
|
||||
mac_addr[3] = (macid_hi >> 24) & 0xff;
|
||||
mac_addr[2] = (macid_hi >> 16) & 0xff;
|
||||
mac_addr[1] = (macid_hi >> 8) & 0xff;
|
||||
mac_addr[0] = macid_hi & 0xff;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ti_cm_get_macid(struct udevice *dev, int slave, u8 *mac_addr)
|
||||
{
|
||||
if (of_machine_is_compatible("ti,dm8148"))
|
||||
return cpsw_am33xx_cm_get_macid(dev, 0x630, slave, mac_addr);
|
||||
|
||||
if (of_machine_is_compatible("ti,am33xx"))
|
||||
return cpsw_am33xx_cm_get_macid(dev, 0x630, slave, mac_addr);
|
||||
|
||||
if (of_device_is_compatible(dev, "ti,am3517-emac"))
|
||||
return davinci_emac_3517_get_macid(dev, 0x110, slave, mac_addr);
|
||||
|
||||
if (of_device_is_compatible(dev, "ti,dm816-emac"))
|
||||
return cpsw_am33xx_cm_get_macid(dev, 0x30, slave, mac_addr);
|
||||
|
||||
if (of_machine_is_compatible("ti,am4372"))
|
||||
return cpsw_am33xx_cm_get_macid(dev, 0x630, slave, mac_addr);
|
||||
|
||||
if (of_machine_is_compatible("ti,dra7"))
|
||||
return davinci_emac_3517_get_macid(dev, 0x514, slave, mac_addr);
|
||||
|
||||
dev_err(dev, "incompatible machine/device type for reading mac address\n");
|
||||
return -ENOENT;
|
||||
}
|
|
@ -26,6 +26,7 @@
|
|||
#include <phy.h>
|
||||
#include <asm/arch/cpu.h>
|
||||
#include <dm.h>
|
||||
#include <fdt_support.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
|
@ -965,6 +966,11 @@ static int cpsw_phy_init(struct cpsw_priv *priv, struct cpsw_slave *slave)
|
|||
phydev->supported &= supported;
|
||||
phydev->advertising = phydev->supported;
|
||||
|
||||
#ifdef CONFIG_DM_ETH
|
||||
if (slave->data->phy_of_handle)
|
||||
phydev->dev->of_offset = slave->data->phy_of_handle;
|
||||
#endif
|
||||
|
||||
priv->phydev = phydev;
|
||||
phy_config(phydev);
|
||||
|
||||
|
@ -1137,6 +1143,11 @@ static const struct eth_ops cpsw_eth_ops = {
|
|||
.stop = cpsw_eth_stop,
|
||||
};
|
||||
|
||||
static inline fdt_addr_t cpsw_get_addr_by_node(const void *fdt, int node)
|
||||
{
|
||||
return fdtdec_get_addr_size_auto_noparent(fdt, node, "reg", 0, NULL);
|
||||
}
|
||||
|
||||
static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
|
||||
{
|
||||
struct eth_pdata *pdata = dev_get_platdata(dev);
|
||||
|
@ -1146,9 +1157,8 @@ static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
|
|||
int node = dev->of_offset;
|
||||
int subnode;
|
||||
int slave_index = 0;
|
||||
uint32_t mac_hi, mac_lo;
|
||||
fdt32_t gmii = 0;
|
||||
int active_slave;
|
||||
int ret;
|
||||
|
||||
pdata->iobase = dev_get_addr(dev);
|
||||
priv->data.version = CPSW_CTRL_VERSION_2;
|
||||
|
@ -1202,29 +1212,52 @@ static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
|
|||
|
||||
name = fdt_get_name(fdt, subnode, &len);
|
||||
if (!strncmp(name, "mdio", 4)) {
|
||||
priv->data.mdio_base = fdtdec_get_addr(fdt, subnode,
|
||||
"reg");
|
||||
u32 mdio_base;
|
||||
|
||||
mdio_base = cpsw_get_addr_by_node(fdt, subnode);
|
||||
if (mdio_base == FDT_ADDR_T_NONE) {
|
||||
error("Not able to get MDIO address space\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
priv->data.mdio_base = mdio_base;
|
||||
}
|
||||
|
||||
if (!strncmp(name, "slave", 5)) {
|
||||
u32 phy_id[2];
|
||||
|
||||
if (slave_index >= priv->data.slaves) {
|
||||
printf("error: num slaves and slave nodes did not match\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (slave_index >= priv->data.slaves)
|
||||
continue;
|
||||
phy_mode = fdt_getprop(fdt, subnode, "phy-mode", NULL);
|
||||
if (phy_mode)
|
||||
priv->data.slave_data[slave_index].phy_if =
|
||||
phy_get_interface_by_name(phy_mode);
|
||||
fdtdec_get_int_array(fdt, subnode, "phy_id", phy_id, 2);
|
||||
priv->data.slave_data[slave_index].phy_addr = phy_id[1];
|
||||
|
||||
priv->data.slave_data[slave_index].phy_of_handle =
|
||||
fdtdec_lookup_phandle(fdt, subnode,
|
||||
"phy-handle");
|
||||
|
||||
if (priv->data.slave_data[slave_index].phy_of_handle >= 0) {
|
||||
priv->data.slave_data[slave_index].phy_addr =
|
||||
fdtdec_get_int(gd->fdt_blob,
|
||||
priv->data.slave_data[slave_index].phy_of_handle,
|
||||
"reg", -1);
|
||||
} else {
|
||||
fdtdec_get_int_array(fdt, subnode, "phy_id",
|
||||
phy_id, 2);
|
||||
priv->data.slave_data[slave_index].phy_addr =
|
||||
phy_id[1];
|
||||
}
|
||||
slave_index++;
|
||||
}
|
||||
|
||||
if (!strncmp(name, "cpsw-phy-sel", 12)) {
|
||||
priv->data.gmii_sel = fdtdec_get_addr(fdt, subnode,
|
||||
"reg");
|
||||
priv->data.gmii_sel = cpsw_get_addr_by_node(fdt,
|
||||
subnode);
|
||||
|
||||
if (priv->data.gmii_sel == FDT_ADDR_T_NONE) {
|
||||
error("Not able to get gmii_sel reg address\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1236,20 +1269,11 @@ static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
|
|||
priv->data.slave_data[1].sliver_reg_ofs = CPSW_SLIVER1_OFFSET;
|
||||
}
|
||||
|
||||
subnode = fdtdec_lookup_phandle(fdt, node, "syscon");
|
||||
priv->data.mac_id = fdt_translate_address((void *)fdt, subnode, &gmii);
|
||||
priv->data.mac_id += AM335X_GMII_SEL_OFFSET;
|
||||
priv->data.mac_id += active_slave * 8;
|
||||
|
||||
/* try reading mac address from efuse */
|
||||
mac_lo = readl(priv->data.mac_id);
|
||||
mac_hi = readl(priv->data.mac_id + 4);
|
||||
pdata->enetaddr[0] = mac_hi & 0xFF;
|
||||
pdata->enetaddr[1] = (mac_hi & 0xFF00) >> 8;
|
||||
pdata->enetaddr[2] = (mac_hi & 0xFF0000) >> 16;
|
||||
pdata->enetaddr[3] = (mac_hi & 0xFF000000) >> 24;
|
||||
pdata->enetaddr[4] = mac_lo & 0xFF;
|
||||
pdata->enetaddr[5] = (mac_lo & 0xFF00) >> 8;
|
||||
ret = ti_cm_get_macid(dev, active_slave, pdata->enetaddr);
|
||||
if (ret < 0) {
|
||||
error("cpsw read efuse mac failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
pdata->phy_interface = priv->data.slave_data[active_slave].phy_if;
|
||||
if (pdata->phy_interface == -1) {
|
||||
|
@ -1270,6 +1294,7 @@ static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
|
|||
writel(RGMII_MODE_ENABLE, priv->data.gmii_sel);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2009
|
||||
* Marvell Semiconductor <www.marvell.com>
|
||||
* Prafulla Wadaskar <prafulla@marvell.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef _MV88E61XX_H
|
||||
#define _MV88E61XX_H
|
||||
|
||||
#include <miiphy.h>
|
||||
|
||||
#define MV88E61XX_CPU_PORT 0x5
|
||||
|
||||
#define MV88E61XX_PHY_TIMEOUT 100000
|
||||
|
||||
/* port dev-addr (= port + 0x10) */
|
||||
#define MV88E61XX_PRT_OFST 0x10
|
||||
/* port registers */
|
||||
#define MV88E61XX_PCS_CTRL_REG 0x1
|
||||
#define MV88E61XX_PRT_CTRL_REG 0x4
|
||||
#define MV88E61XX_PRT_VMAP_REG 0x6
|
||||
#define MV88E61XX_PRT_VID_REG 0x7
|
||||
#define MV88E61XX_RGMII_TIMECTRL_REG 0x1A
|
||||
|
||||
/* global registers dev-addr */
|
||||
#define MV88E61XX_GLBREG_DEVADR 0x1B
|
||||
/* global registers */
|
||||
#define MV88E61XX_SGSR 0x00
|
||||
#define MV88E61XX_SGCR 0x04
|
||||
|
||||
/* global 2 registers dev-addr */
|
||||
#define MV88E61XX_GLB2REG_DEVADR 0x1C
|
||||
/* global 2 registers */
|
||||
#define MV88E61XX_PHY_CMD 0x18
|
||||
#define MV88E61XX_PHY_DATA 0x19
|
||||
/* global 2 phy commands */
|
||||
#define MV88E61XX_PHY_WRITE_CMD 0x9400
|
||||
#define MV88E61XX_PHY_READ_CMD 0x9800
|
||||
|
||||
#define MV88E61XX_BUSY_OFST 15
|
||||
#define MV88E61XX_MODE_OFST 12
|
||||
#define MV88E61XX_OP_OFST 10
|
||||
#define MV88E61XX_ADDR_OFST 5
|
||||
|
||||
#ifdef CONFIG_MV88E61XX_MULTICHIP_ADRMODE
|
||||
static int mv88e61xx_busychk_multic(char *name, u32 devaddr);
|
||||
static void mv88e61xx_switch_write(char *name, u32 phy_adr,
|
||||
u32 reg_ofs, u16 data);
|
||||
static void mv88e61xx_switch_read(char *name, u32 phy_adr,
|
||||
u32 reg_ofs, u16 *data);
|
||||
#define wr_switch_reg mv88e61xx_switch_write
|
||||
#define rd_switch_reg mv88e61xx_switch_read
|
||||
#else
|
||||
/* switch appears a s simple PHY and can thus use miiphy */
|
||||
#define wr_switch_reg miiphy_write
|
||||
#define rd_switch_reg miiphy_read
|
||||
#endif /* CONFIG_MV88E61XX_MULTICHIP_ADRMODE */
|
||||
|
||||
#endif /* _MV88E61XX_H */
|
|
@ -461,6 +461,9 @@ static LIST_HEAD(phy_drivers);
|
|||
|
||||
int phy_init(void)
|
||||
{
|
||||
#ifdef CONFIG_MV88E61XX_SWITCH
|
||||
phy_mv88e61xx_init();
|
||||
#endif
|
||||
#ifdef CONFIG_PHY_AQUANTIA
|
||||
phy_aquantia_init();
|
||||
#endif
|
||||
|
|
|
@ -6,6 +6,14 @@
|
|||
*/
|
||||
#include <common.h>
|
||||
#include <phy.h>
|
||||
#include <linux/compat.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include <fdtdec.h>
|
||||
#include <dm.h>
|
||||
#include <dt-bindings/net/ti-dp83867.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/* TI DP83867 */
|
||||
#define DP83867_DEVADDR 0x1f
|
||||
|
@ -71,6 +79,17 @@
|
|||
#define MII_MMD_CTRL_INCR_RDWT 0x8000 /* post increment on reads & writes */
|
||||
#define MII_MMD_CTRL_INCR_ON_WT 0xC000 /* post increment on writes only */
|
||||
|
||||
/* User setting - can be taken from DTS */
|
||||
#define DEFAULT_RX_ID_DELAY DP83867_RGMIIDCTL_2_25_NS
|
||||
#define DEFAULT_TX_ID_DELAY DP83867_RGMIIDCTL_2_75_NS
|
||||
#define DEFAULT_FIFO_DEPTH DP83867_PHYCR_FIFO_DEPTH_4_B_NIB
|
||||
|
||||
struct dp83867_private {
|
||||
int rx_id_delay;
|
||||
int tx_id_delay;
|
||||
int fifo_depth;
|
||||
};
|
||||
|
||||
/**
|
||||
* phy_read_mmd_indirect - reads data from the MMD registers
|
||||
* @phydev: The PHY device bus
|
||||
|
@ -137,27 +156,60 @@ void phy_write_mmd_indirect(struct phy_device *phydev, int prtad,
|
|||
phy_write(phydev, addr, MII_MMD_DATA, data);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DM_ETH)
|
||||
/**
|
||||
* phy_interface_is_rgmii - Convenience function for testing if a PHY interface
|
||||
* is RGMII (all variants)
|
||||
* dp83867_data_init - Convenience function for setting PHY specific data
|
||||
*
|
||||
* @phydev: the phy_device struct
|
||||
*/
|
||||
static inline bool phy_interface_is_rgmii(struct phy_device *phydev)
|
||||
static int dp83867_of_init(struct phy_device *phydev)
|
||||
{
|
||||
return phydev->interface >= PHY_INTERFACE_MODE_RGMII &&
|
||||
phydev->interface <= PHY_INTERFACE_MODE_RGMII_TXID;
|
||||
}
|
||||
struct dp83867_private *dp83867 = phydev->priv;
|
||||
struct udevice *dev = phydev->dev;
|
||||
|
||||
/* User setting - can be taken from DTS */
|
||||
#define RX_ID_DELAY 8
|
||||
#define TX_ID_DELAY 0xa
|
||||
#define FIFO_DEPTH 1
|
||||
dp83867->rx_id_delay = fdtdec_get_uint(gd->fdt_blob, dev->of_offset,
|
||||
"ti,rx-internal-delay", -1);
|
||||
|
||||
dp83867->tx_id_delay = fdtdec_get_uint(gd->fdt_blob, dev->of_offset,
|
||||
"ti,tx-internal-delay", -1);
|
||||
|
||||
dp83867->fifo_depth = fdtdec_get_uint(gd->fdt_blob, dev->of_offset,
|
||||
"ti,fifo-depth", -1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int dp83867_of_init(struct phy_device *phydev)
|
||||
{
|
||||
struct dp83867_private *dp83867 = phydev->priv;
|
||||
|
||||
dp83867->rx_id_delay = DEFAULT_RX_ID_DELAY;
|
||||
dp83867->tx_id_delay = DEFAULT_TX_ID_DELAY;
|
||||
dp83867->fifo_depth = DEFAULT_FIFO_DEPTH;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int dp83867_config(struct phy_device *phydev)
|
||||
{
|
||||
struct dp83867_private *dp83867;
|
||||
unsigned int val, delay, cfg2;
|
||||
int ret;
|
||||
|
||||
if (!phydev->priv) {
|
||||
dp83867 = kzalloc(sizeof(*dp83867), GFP_KERNEL);
|
||||
if (!dp83867)
|
||||
return -ENOMEM;
|
||||
|
||||
phydev->priv = dp83867;
|
||||
ret = dp83867_of_init(phydev);
|
||||
if (ret)
|
||||
goto err_out;
|
||||
} else {
|
||||
dp83867 = (struct dp83867_private *)phydev->priv;
|
||||
}
|
||||
|
||||
/* Restart the PHY. */
|
||||
val = phy_read(phydev, MDIO_DEVAD_NONE, DP83867_CTRL);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, DP83867_CTRL,
|
||||
|
@ -166,10 +218,10 @@ static int dp83867_config(struct phy_device *phydev)
|
|||
if (phy_interface_is_rgmii(phydev)) {
|
||||
ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_PHYCTRL,
|
||||
(DP83867_MDI_CROSSOVER_AUTO << DP83867_MDI_CROSSOVER) |
|
||||
(FIFO_DEPTH << DP83867_PHYCR_FIFO_DEPTH_SHIFT));
|
||||
(dp83867->fifo_depth << DP83867_PHYCR_FIFO_DEPTH_SHIFT));
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
goto err_out;
|
||||
} else if (phy_interface_is_sgmii(phydev)) {
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR,
|
||||
(BMCR_ANENABLE | BMCR_FULLDPLX | BMCR_SPEED1000));
|
||||
|
||||
|
@ -189,8 +241,8 @@ static int dp83867_config(struct phy_device *phydev)
|
|||
DP83867_PHYCTRL_SGMIIEN |
|
||||
(DP83867_MDI_CROSSOVER_MDIX <<
|
||||
DP83867_MDI_CROSSOVER) |
|
||||
(FIFO_DEPTH << DP83867_PHYCTRL_RXFIFO_SHIFT) |
|
||||
(FIFO_DEPTH << DP83867_PHYCTRL_TXFIFO_SHIFT));
|
||||
(dp83867->fifo_depth << DP83867_PHYCTRL_RXFIFO_SHIFT) |
|
||||
(dp83867->fifo_depth << DP83867_PHYCTRL_TXFIFO_SHIFT));
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_BISCR, 0x0);
|
||||
}
|
||||
|
||||
|
@ -212,8 +264,8 @@ static int dp83867_config(struct phy_device *phydev)
|
|||
phy_write_mmd_indirect(phydev, DP83867_RGMIICTL,
|
||||
DP83867_DEVADDR, phydev->addr, val);
|
||||
|
||||
delay = (RX_ID_DELAY |
|
||||
(TX_ID_DELAY << DP83867_RGMII_TX_CLK_DELAY_SHIFT));
|
||||
delay = (dp83867->rx_id_delay |
|
||||
(dp83867->tx_id_delay << DP83867_RGMII_TX_CLK_DELAY_SHIFT));
|
||||
|
||||
phy_write_mmd_indirect(phydev, DP83867_RGMIIDCTL,
|
||||
DP83867_DEVADDR, phydev->addr, delay);
|
||||
|
@ -221,6 +273,10 @@ static int dp83867_config(struct phy_device *phydev)
|
|||
|
||||
genphy_config_aneg(phydev);
|
||||
return 0;
|
||||
|
||||
err_out:
|
||||
kfree(dp83867);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct phy_driver DP83867_driver = {
|
||||
|
|
|
@ -179,6 +179,7 @@ struct zynq_gem_priv {
|
|||
struct zynq_gem_regs *iobase;
|
||||
phy_interface_t interface;
|
||||
struct phy_device *phydev;
|
||||
int phy_of_handle;
|
||||
struct mii_dev *bus;
|
||||
};
|
||||
|
||||
|
@ -353,6 +354,9 @@ static int zynq_phy_init(struct udevice *dev)
|
|||
ADVERTISED_Asym_Pause;
|
||||
priv->phydev->advertising = priv->phydev->supported;
|
||||
|
||||
if (priv->phy_of_handle > 0)
|
||||
priv->phydev->dev->of_offset = priv->phy_of_handle;
|
||||
|
||||
return phy_config(priv->phydev);
|
||||
}
|
||||
|
||||
|
@ -677,7 +681,6 @@ static int zynq_gem_ofdata_to_platdata(struct udevice *dev)
|
|||
{
|
||||
struct eth_pdata *pdata = dev_get_platdata(dev);
|
||||
struct zynq_gem_priv *priv = dev_get_priv(dev);
|
||||
int offset = 0;
|
||||
const char *phy_mode;
|
||||
|
||||
pdata->iobase = (phys_addr_t)dev_get_addr(dev);
|
||||
|
@ -686,10 +689,11 @@ static int zynq_gem_ofdata_to_platdata(struct udevice *dev)
|
|||
priv->emio = 0;
|
||||
priv->phyaddr = -1;
|
||||
|
||||
offset = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset,
|
||||
"phy-handle");
|
||||
if (offset > 0)
|
||||
priv->phyaddr = fdtdec_get_int(gd->fdt_blob, offset, "reg", -1);
|
||||
priv->phy_of_handle = fdtdec_lookup_phandle(gd->fdt_blob,
|
||||
dev->of_offset, "phy-handle");
|
||||
if (priv->phy_of_handle > 0)
|
||||
priv->phyaddr = fdtdec_get_int(gd->fdt_blob,
|
||||
priv->phy_of_handle, "reg", -1);
|
||||
|
||||
phy_mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy-mode", NULL);
|
||||
if (phy_mode)
|
||||
|
|
|
@ -153,6 +153,7 @@
|
|||
#ifdef CONFIG_SPL_BUILD
|
||||
#undef CONFIG_DM_MMC
|
||||
#undef CONFIG_TIMER
|
||||
#undef CONFIG_DM_ETH
|
||||
#endif
|
||||
|
||||
#endif /* __CONFIG_TI_OMAP5_COMMON_H */
|
||||
|
|
|
@ -21,6 +21,7 @@ struct cpsw_slave_data {
|
|||
u32 sliver_reg_ofs;
|
||||
int phy_addr;
|
||||
int phy_if;
|
||||
int phy_of_handle;
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -51,5 +52,6 @@ struct cpsw_platform_data {
|
|||
};
|
||||
|
||||
int cpsw_register(struct cpsw_platform_data *data);
|
||||
int ti_cm_get_macid(struct udevice *dev, int slave, u8 *mac_addr);
|
||||
|
||||
#endif /* _CPSW_H_ */
|
||||
|
|
|
@ -547,6 +547,29 @@ int device_set_name(struct udevice *dev, const char *name);
|
|||
*/
|
||||
void device_set_name_alloced(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* of_device_is_compatible() - check if the device is compatible with the compat
|
||||
*
|
||||
* This allows to check whether the device is comaptible with the compat.
|
||||
*
|
||||
* @dev: udevice pointer for which compatible needs to be verified.
|
||||
* @compat: Compatible string which needs to verified in the given
|
||||
* device
|
||||
* @return true if OK, false if the compatible is not found
|
||||
*/
|
||||
bool of_device_is_compatible(struct udevice *dev, const char *compat);
|
||||
|
||||
/**
|
||||
* of_machine_is_compatible() - check if the machine is compatible with
|
||||
* the compat
|
||||
*
|
||||
* This allows to check whether the machine is comaptible with the compat.
|
||||
*
|
||||
* @compat: Compatible string which needs to verified
|
||||
* @return true if OK, false if the compatible is not found
|
||||
*/
|
||||
bool of_machine_is_compatible(const char *compat);
|
||||
|
||||
/**
|
||||
* device_is_on_pci_bus - Test if a device is on a PCI bus
|
||||
*
|
||||
|
|
35
include/dt-bindings/net/ti-dp83867.h
Normal file
35
include/dt-bindings/net/ti-dp83867.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* TI DP83867 PHY drivers
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_TI_DP83867_H
|
||||
#define _DT_BINDINGS_TI_DP83867_H
|
||||
|
||||
/* PHY CTRL bits */
|
||||
#define DP83867_PHYCR_FIFO_DEPTH_3_B_NIB 0x00
|
||||
#define DP83867_PHYCR_FIFO_DEPTH_4_B_NIB 0x01
|
||||
#define DP83867_PHYCR_FIFO_DEPTH_6_B_NIB 0x02
|
||||
#define DP83867_PHYCR_FIFO_DEPTH_8_B_NIB 0x03
|
||||
|
||||
/* RGMIIDCTL internal delay for rx and tx */
|
||||
#define DP83867_RGMIIDCTL_250_PS 0x0
|
||||
#define DP83867_RGMIIDCTL_500_PS 0x1
|
||||
#define DP83867_RGMIIDCTL_750_PS 0x2
|
||||
#define DP83867_RGMIIDCTL_1_NS 0x3
|
||||
#define DP83867_RGMIIDCTL_1_25_NS 0x4
|
||||
#define DP83867_RGMIIDCTL_1_50_NS 0x5
|
||||
#define DP83867_RGMIIDCTL_1_75_NS 0x6
|
||||
#define DP83867_RGMIIDCTL_2_00_NS 0x7
|
||||
#define DP83867_RGMIIDCTL_2_25_NS 0x8
|
||||
#define DP83867_RGMIIDCTL_2_50_NS 0x9
|
||||
#define DP83867_RGMIIDCTL_2_75_NS 0xa
|
||||
#define DP83867_RGMIIDCTL_3_00_NS 0xb
|
||||
#define DP83867_RGMIIDCTL_3_25_NS 0xc
|
||||
#define DP83867_RGMIIDCTL_3_50_NS 0xd
|
||||
#define DP83867_RGMIIDCTL_3_75_NS 0xe
|
||||
#define DP83867_RGMIIDCTL_4_00_NS 0xf
|
||||
|
||||
#endif
|
|
@ -134,64 +134,6 @@ static inline int pci_eth_init(bd_t *bis)
|
|||
return num;
|
||||
}
|
||||
|
||||
/*
|
||||
* Boards with mv88e61xx switch can use this by defining
|
||||
* CONFIG_MV88E61XX_SWITCH in respective board configheader file
|
||||
* the stuct and enums here are used to specify switch configuration params
|
||||
*/
|
||||
#if defined(CONFIG_MV88E61XX_SWITCH)
|
||||
|
||||
/* constants for any 88E61xx switch */
|
||||
#define MV88E61XX_MAX_PORTS_NUM 6
|
||||
|
||||
enum mv88e61xx_cfg_mdip {
|
||||
MV88E61XX_MDIP_NOCHANGE,
|
||||
MV88E61XX_MDIP_REVERSE
|
||||
};
|
||||
|
||||
enum mv88e61xx_cfg_ledinit {
|
||||
MV88E61XX_LED_INIT_DIS,
|
||||
MV88E61XX_LED_INIT_EN
|
||||
};
|
||||
|
||||
enum mv88e61xx_cfg_rgmiid {
|
||||
MV88E61XX_RGMII_DELAY_DIS,
|
||||
MV88E61XX_RGMII_DELAY_EN
|
||||
};
|
||||
|
||||
enum mv88e61xx_cfg_prtstt {
|
||||
MV88E61XX_PORTSTT_DISABLED,
|
||||
MV88E61XX_PORTSTT_BLOCKING,
|
||||
MV88E61XX_PORTSTT_LEARNING,
|
||||
MV88E61XX_PORTSTT_FORWARDING
|
||||
};
|
||||
|
||||
struct mv88e61xx_config {
|
||||
char *name;
|
||||
u8 vlancfg[MV88E61XX_MAX_PORTS_NUM];
|
||||
enum mv88e61xx_cfg_rgmiid rgmii_delay;
|
||||
enum mv88e61xx_cfg_prtstt portstate;
|
||||
enum mv88e61xx_cfg_ledinit led_init;
|
||||
enum mv88e61xx_cfg_mdip mdip;
|
||||
u32 ports_enabled;
|
||||
u8 cpuport;
|
||||
};
|
||||
|
||||
/*
|
||||
* Common mappings for Internal VLANs
|
||||
* These mappings consider that all ports are useable; the driver
|
||||
* will mask inexistent/unused ports.
|
||||
*/
|
||||
|
||||
/* Switch mode : routes any port to any port */
|
||||
#define MV88E61XX_VLANCFG_SWITCH { 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F }
|
||||
|
||||
/* Router mode: routes only CPU port 5 to/from non-CPU ports 0-4 */
|
||||
#define MV88E61XX_VLANCFG_ROUTER { 0x20, 0x20, 0x20, 0x20, 0x20, 0x1F }
|
||||
|
||||
int mv88e61xx_switch_initialize(struct mv88e61xx_config *swconfig);
|
||||
#endif /* CONFIG_MV88E61XX_SWITCH */
|
||||
|
||||
struct mii_dev *fec_get_miibus(uint32_t base_addr, int dev_id);
|
||||
#ifdef CONFIG_PHYLIB
|
||||
struct phy_device;
|
||||
|
|
|
@ -249,6 +249,7 @@ int gen10g_startup(struct phy_device *phydev);
|
|||
int gen10g_shutdown(struct phy_device *phydev);
|
||||
int gen10g_discover_mmds(struct phy_device *phydev);
|
||||
|
||||
int phy_mv88e61xx_init(void);
|
||||
int phy_aquantia_init(void);
|
||||
int phy_atheros_init(void);
|
||||
int phy_broadcom_init(void);
|
||||
|
@ -277,6 +278,28 @@ int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id);
|
|||
*/
|
||||
int phy_get_interface_by_name(const char *str);
|
||||
|
||||
/**
|
||||
* phy_interface_is_rgmii - Convenience function for testing if a PHY interface
|
||||
* is RGMII (all variants)
|
||||
* @phydev: the phy_device struct
|
||||
*/
|
||||
static inline bool phy_interface_is_rgmii(struct phy_device *phydev)
|
||||
{
|
||||
return phydev->interface >= PHY_INTERFACE_MODE_RGMII &&
|
||||
phydev->interface <= PHY_INTERFACE_MODE_RGMII_TXID;
|
||||
}
|
||||
|
||||
/**
|
||||
* phy_interface_is_sgmii - Convenience function for testing if a PHY interface
|
||||
* is SGMII (all variants)
|
||||
* @phydev: the phy_device struct
|
||||
*/
|
||||
static inline bool phy_interface_is_sgmii(struct phy_device *phydev)
|
||||
{
|
||||
return phydev->interface >= PHY_INTERFACE_MODE_SGMII &&
|
||||
phydev->interface <= PHY_INTERFACE_MODE_QSGMII;
|
||||
}
|
||||
|
||||
/* PHY UIDs for various PHYs that are referenced in external code */
|
||||
#define PHY_UID_CS4340 0x13e51002
|
||||
#define PHY_UID_TN2020 0x00a19410
|
||||
|
|
Loading…
Reference in a new issue