9
0
Fork 0

net fec_imx: determine fec version based on device ids

This adds the device id mechanism to the i.MX fec driver and
uses it to determine the fec version. Also adds devicetree
probing support.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
Sascha Hauer 2011-08-14 10:05:29 +02:00
parent 3e1f8a05b9
commit 258e096e13
12 changed files with 95 additions and 23 deletions

View File

@ -236,7 +236,7 @@ static int mx28_evk_devices_init(void)
imx_enable_enetclk();
mx28_evk_fec_reset();
add_generic_device("fec_imx", 0, NULL, IMX_FEC0_BASE, 0x4000,
add_generic_device("imx28-fec", 0, NULL, IMX_FEC0_BASE, 0x4000,
IORESOURCE_MEM, &fec_info);
return 0;

View File

@ -393,7 +393,7 @@ void base_board_init(void)
tx28_get_ethaddr();
imx_enable_enetclk();
add_generic_device("fec_imx", 0, NULL, IMX_FEC0_BASE, 0x4000,
add_generic_device("imx28-fec", 0, NULL, IMX_FEC0_BASE, 0x4000,
IORESOURCE_MEM, &fec_info);
ret = register_persistent_environment();

View File

@ -8,9 +8,14 @@ static inline struct device_d *imx_add_device(char *name, int id, void *base, in
IORESOURCE_MEM, pdata);
}
struct device_d *imx_add_fec(void *base, struct fec_platform_data *pdata)
struct device_d *imx_add_fec_imx27(void *base, struct fec_platform_data *pdata)
{
return imx_add_device("fec_imx", -1, base, 0x1000, pdata);
return imx_add_device("imx27-fec", -1, base, 0x1000, pdata);
}
struct device_d *imx_add_fec_imx6(void *base, struct fec_platform_data *pdata)
{
return imx_add_device("imx6-fec", -1, base, 0x1000, pdata);
}
struct device_d *imx_add_spi(void *base, int id, struct spi_imx_master *pdata)

View File

@ -68,7 +68,7 @@ static inline struct device_d *imx25_add_fb(struct imx_fb_platform_data *pdata)
static inline struct device_d *imx25_add_fec(struct fec_platform_data *pdata)
{
return imx_add_fec((void *)MX25_FEC_BASE_ADDR, pdata);
return imx_add_fec_imx27((void *)MX25_FEC_BASE_ADDR, pdata);
}
static inline struct device_d *imx25_add_mmc0(struct esdhc_platform_data *pdata)

View File

@ -53,7 +53,7 @@ static inline struct device_d *imx27_add_fb(struct imx_fb_platform_data *pdata)
static inline struct device_d *imx27_add_fec(struct fec_platform_data *pdata)
{
return imx_add_fec((void *)MX27_FEC_BASE_ADDR, pdata);
return imx_add_fec_imx27((void *)MX27_FEC_BASE_ADDR, pdata);
}
static inline struct device_d *imx27_add_mmc0(void *pdata)

View File

@ -53,7 +53,7 @@ static inline struct device_d *imx35_add_fb(struct imx_ipu_fb_platform_data *pda
static inline struct device_d *imx35_add_fec(struct fec_platform_data *pdata)
{
return imx_add_fec((void *)MX35_FEC_BASE_ADDR, pdata);
return imx_add_fec_imx27((void *)MX35_FEC_BASE_ADDR, pdata);
}
static inline struct device_d *imx35_add_mmc0(struct esdhc_platform_data *pdata)

View File

@ -44,7 +44,7 @@ static inline struct device_d *imx51_add_uart2(void)
static inline struct device_d *imx51_add_fec(struct fec_platform_data *pdata)
{
return imx_add_fec((void *)MX51_MXC_FEC_BASE_ADDR, pdata);
return imx_add_fec_imx27((void *)MX51_MXC_FEC_BASE_ADDR, pdata);
}
static inline struct device_d *imx51_add_mmc0(struct esdhc_platform_data *pdata)

View File

@ -38,7 +38,7 @@ static inline struct device_d *imx53_add_uart2(void)
static inline struct device_d *imx53_add_fec(struct fec_platform_data *pdata)
{
return imx_add_fec((void *)MX53_FEC_BASE_ADDR, pdata);
return imx_add_fec_imx27((void *)MX53_FEC_BASE_ADDR, pdata);
}
static inline struct device_d *imx53_add_mmc0(struct esdhc_platform_data *pdata)

View File

@ -42,7 +42,7 @@ static inline struct device_d *imx6_add_mmc3(struct esdhc_platform_data *pdata)
static inline struct device_d *imx6_add_fec(struct fec_platform_data *pdata)
{
return imx_add_fec((void *)MX6_ENET_BASE_ADDR, pdata);
return imx_add_fec_imx6((void *)MX6_ENET_BASE_ADDR, pdata);
}
static inline struct device_d *imx6_add_spi0(struct spi_imx_master *pdata)

View File

@ -8,7 +8,8 @@
#include <mach/imx-ipu-fb.h>
#include <mach/esdhc.h>
struct device_d *imx_add_fec(void *base, struct fec_platform_data *pdata);
struct device_d *imx_add_fec_imx27(void *base, struct fec_platform_data *pdata);
struct device_d *imx_add_fec_imx6(void *base, struct fec_platform_data *pdata);
struct device_d *imx_add_spi(void *base, int id, struct spi_imx_master *pdata);
struct device_d *imx_add_i2c(void *base, int id, struct i2c_platform_data *pdata);
struct device_d *imx_add_uart_imx1(void *base, int id);

View File

@ -310,7 +310,7 @@ static int fec_init(struct eth_device *dev)
}
if (fec->xcv_type == RMII) {
if (cpu_is_mx28()) {
if (fec_is_imx28(fec)) {
rcntl |= FEC_R_CNTRL_RMII_MODE | FEC_R_CNTRL_FCE |
FEC_R_CNTRL_NO_LGTH_CHECK;
} else {
@ -340,7 +340,7 @@ static int fec_init(struct eth_device *dev)
xwmrk = 0x2;
/* set ENET tx at store and forward mode */
if (cpu_is_mx6())
if (fec_is_imx6(fec))
xwmrk |= 1 << 8;
writel(xwmrk, fec->regs + FEC_X_WMRK);
@ -407,7 +407,7 @@ static int fec_open(struct eth_device *edev)
ecr = FEC_ECNTRL_ETHER_EN;
/* Enable Swap to support little-endian device */
if (cpu_is_mx6())
if (fec_is_imx6(fec))
ecr |= 0x100;
writel(ecr, fec->regs + FEC_ECNTRL);
@ -481,7 +481,7 @@ static int fec_send(struct eth_device *dev, void *eth_data, int data_length)
* Note: We are always using the first buffer for transmission,
* the second will be empty and only used to stop the DMA engine
*/
if (cpu_is_mx28())
if (fec_is_imx28(fec))
eth_data = imx28_fix_endianess_wr(eth_data, (data_length + 3) >> 2);
writew(data_length, &fec->tbd_base[fec->tbd_index].data_length);
@ -548,7 +548,7 @@ static int fec_recv(struct eth_device *dev)
printf("some error: 0x%08x\n", ievent);
return 0;
}
if (!cpu_is_mx28()) {
if (!fec_is_imx28(fec)) {
if (ievent & FEC_IEVENT_HBERR) {
/* Heartbeat error */
writel(readl(fec->regs + FEC_X_CNTRL) | 0x1,
@ -574,7 +574,7 @@ static int fec_recv(struct eth_device *dev)
if ((bd_status & FEC_RBD_LAST) && !(bd_status & FEC_RBD_ERR) &&
((readw(&rbd->data_length) - 4) > 14)) {
if (cpu_is_mx28())
if (fec_is_imx28(fec))
imx28_fix_endianess_rd(
phys_to_virt(readl(&rbd->data_pointer)),
(readw(&rbd->data_length) + 3) >> 2);
@ -628,10 +628,17 @@ static int fec_probe(struct device_d *dev)
struct fec_priv *fec;
void *base;
int ret;
enum fec_type type;
ret = dev_get_drvdata(dev, (unsigned long *)&type);
if (ret)
return ret;
#ifdef CONFIG_ARCH_IMX27
PCCR0 |= PCCR0_FEC_EN;
#endif
fec = xzalloc(sizeof(*fec));
fec->type = type;
edev = &fec->edev;
dev->priv = fec;
edev->priv = fec;
@ -675,14 +682,19 @@ static int fec_probe(struct device_d *dev)
fec_alloc_receive_packets(fec, FEC_RBD_NUM, FEC_MAX_PKT_SIZE);
fec->xcv_type = pdata->xcv_type;
if (pdata) {
fec->xcv_type = pdata->xcv_type;
fec->phy_init = pdata->phy_init;
fec->phy_addr = pdata->phy_addr;
} else {
fec->xcv_type = MII100;
fec->phy_addr = -1;
}
if (fec->xcv_type != SEVENWIRE) {
fec->phy_init = pdata->phy_init;
fec->miibus.read = fec_miibus_read;
fec->miibus.write = fec_miibus_write;
fec->phy_addr = pdata->phy_addr;
switch (pdata->xcv_type) {
switch (fec->xcv_type) {
case RMII:
fec->interface = PHY_INTERFACE_MODE_RMII;
break;
@ -719,13 +731,45 @@ static void fec_remove(struct device_d *dev)
fec_halt(&fec->edev);
}
static __maybe_unused struct of_device_id imx_fec_dt_ids[] = {
{
.compatible = "fsl,imx27-fec",
.data = FEC_TYPE_IMX27,
}, {
.compatible = "fsl,imx28-fec",
.data = FEC_TYPE_IMX28,
}, {
.compatible = "fsl,imx6q-fec",
.data = FEC_TYPE_IMX6,
}, {
/* sentinel */
}
};
static struct platform_device_id imx_fec_ids[] = {
{
.name = "imx27-fec",
.driver_data = (unsigned long)FEC_TYPE_IMX27,
}, {
.name = "imx28-fec",
.driver_data = (unsigned long)FEC_TYPE_IMX28,
}, {
.name = "imx6-fec",
.driver_data = (unsigned long)FEC_TYPE_IMX6,
}, {
/* sentinel */
},
};
/**
* Driver description for registering
*/
static struct driver_d fec_driver = {
.name = "fec_imx",
.probe = fec_probe,
.name = "fec_imx",
.probe = fec_probe,
.remove = fec_remove,
.of_compatible = DRV_OF_COMPAT(imx_fec_dt_ids),
.id_table = imx_fec_ids,
};
static int fec_register(void)

View File

@ -122,6 +122,12 @@ struct buffer_descriptor {
uint32_t data_pointer; /**< payload's buffer address */
};
enum fec_type {
FEC_TYPE_IMX27,
FEC_TYPE_IMX28,
FEC_TYPE_IMX6,
};
/**
* @brief i.MX27-FEC private structure
*/
@ -139,8 +145,24 @@ struct fec_priv {
struct mii_bus miibus;
void (*phy_init)(struct phy_device *dev);
struct clk *clk;
enum fec_type type;
};
static inline int fec_is_imx27(struct fec_priv *priv)
{
return priv->type == FEC_TYPE_IMX27;
}
static inline int fec_is_imx28(struct fec_priv *priv)
{
return priv->type == FEC_TYPE_IMX28;
}
static inline int fec_is_imx6(struct fec_priv *priv)
{
return priv->type == FEC_TYPE_IMX6;
}
/**
* @brief Numbers of buffer descriptors for receiving
*