Merge branch 'master' of git://www.denx.de/git/u-boot-imx

Migrate CONFIG_ARCH_USE_MEMSET/MEMCPY with this merge.

Signed-off-by: Tom Rini <trini@konsulko.com>
This commit is contained in:
Tom Rini
2016-12-18 13:54:25 -05:00
150 changed files with 16818 additions and 473 deletions
+20
View File
@@ -3,6 +3,26 @@ menu "FPGA support"
config FPGA
bool
config FPGA_ALTERA
bool "Enable Altera FPGA drivers"
select FPGA
help
Say Y here to enable the Altera FPGA driver
This provides basic infrastructure to support Altera FPGA devices.
Enable Altera FPGA specific functions which includes bitstream
(in BIT format), fpga and device validation.
config FPGA_CYCLON2
bool "Enable Altera FPGA driver for Cyclone II"
depends on FPGA_ALTERA
help
Say Y here to enable the Altera Cyclone II FPGA specific driver
This provides common functionality for Altera Cyclone II devices.
Enable FPGA driver for loading bitstream in BIT and BIN format
on Altera Cyclone II device.
config FPGA_XILINX
bool "Enable Xilinx FPGA drivers"
select FPGA
+8
View File
@@ -109,6 +109,14 @@ config SYS_I2C_INTEL
the I2C API meaning that any I2C operations will immediately fail
for now.
config SYS_I2C_MXC
bool "NXP i.MX I2C driver"
depends on MX6
help
Add support for the NXP i.MX I2C driver. This supports upto for bus
channels and operating on standard mode upto 100 kbits/s and fast
mode upto 400 kbits/s.
config SYS_I2C_ROCKCHIP
bool "Rockchip I2C driver"
depends on DM_I2C
+1 -1
View File
@@ -775,7 +775,7 @@ static int mxc_i2c_probe(struct udevice *bus)
*/
ret = fdt_stringlist_search(fdt, node, "pinctrl-names", "gpio");
if (ret < 0) {
dev_info(dev, "i2c bus %d at %lu, no gpio pinctrl state.\n", bus->seq, i2c_bus->base);
debug("i2c bus %d at 0x%2lx, no gpio pinctrl state.\n", bus->seq, i2c_bus->base);
} else {
ret = gpio_request_by_name_nodev(fdt, node, "scl-gpios",
0, &i2c_bus->scl_gpio,
+8 -8
View File
@@ -62,7 +62,7 @@
#define FUSE_BANK_SIZE 0x80
#ifdef CONFIG_MX6SL
#define FUSE_BANKS 8
#elif defined(CONFIG_MX6ULL)
#elif defined(CONFIG_MX6ULL) || defined(CONFIG_MX6SLL)
#define FUSE_BANKS 9
#else
#define FUSE_BANKS 16
@@ -79,7 +79,7 @@
/*
* There is a hole in shadow registers address map of size 0x100
* between bank 5 and bank 6 on iMX6QP, iMX6DQ, iMX6SDL, iMX6SX,
* iMX6UL and i.MX6ULL.
* iMX6UL, i.MX6ULL and i.MX6SLL.
* Bank 5 ends at 0x6F0 and Bank 6 starts at 0x800. When reading the fuses,
* we should account for this hole in address space.
*
@@ -100,8 +100,8 @@ u32 fuse_bank_physical(int index)
if (is_mx6sl()) {
phy_index = index;
} else if (is_mx6ul() || is_mx6ull()) {
if (is_mx6ull() && index == 8)
} else if (is_mx6ul() || is_mx6ull() || is_mx6sll()) {
if ((is_mx6ull() || is_mx6sll()) && index == 8)
index = 7;
if (index >= 6)
@@ -121,7 +121,7 @@ u32 fuse_bank_physical(int index)
u32 fuse_word_physical(u32 bank, u32 word_index)
{
if (is_mx6ull()) {
if (is_mx6ull() || is_mx6sll()) {
if (bank == 8)
word_index = word_index + 4;
}
@@ -164,10 +164,10 @@ static int prepare_access(struct ocotp_regs **regs, u32 bank, u32 word,
return -EINVAL;
}
if (is_mx6ull()) {
if (is_mx6ull() || is_mx6sll()) {
if ((bank == 7 || bank == 8) &&
word >= ARRAY_SIZE((*regs)->bank[0].fuse_regs) >> 3) {
printf("mxc_ocotp %s(): Invalid argument on 6ULL\n", caller);
printf("mxc_ocotp %s(): Invalid argument\n", caller);
return -EINVAL;
}
}
@@ -271,7 +271,7 @@ static void setup_direct_access(struct ocotp_regs *regs, u32 bank, u32 word,
#else
u32 addr;
/* Bank 7 and Bank 8 only supports 4 words each for i.MX6ULL */
if ((is_mx6ull()) && (bank > 7)) {
if ((is_mx6ull() || is_mx6sll()) && (bank > 7)) {
bank = bank - 1;
word += 4;
}
+1 -1
View File
@@ -142,7 +142,7 @@ config ETHOC
config FEC_MXC
bool "FEC Ethernet controller"
depends on MX6
depends on MX5 || MX6
help
This driver supports the 10/100 Fast Ethernet controller for
NXP i.MX processors.
+318 -155
View File
@@ -9,19 +9,21 @@
*/
#include <common.h>
#include <dm.h>
#include <malloc.h>
#include <memalign.h>
#include <miiphy.h>
#include <net.h>
#include <netdev.h>
#include <miiphy.h>
#include "fec_mxc.h"
#include <asm/io.h>
#include <linux/errno.h>
#include <linux/compiler.h>
#include <asm/arch/clock.h>
#include <asm/arch/imx-regs.h>
#include <asm/imx-common/sys_proto.h>
#include <asm/io.h>
#include <linux/errno.h>
#include <linux/compiler.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -79,11 +81,9 @@ static void swap_packet(uint32_t *packet, int length)
}
#endif
/*
* MII-interface related functions
*/
static int fec_mdio_read(struct ethernet_regs *eth, uint8_t phyAddr,
uint8_t regAddr)
/* MII-interface related functions */
static int fec_mdio_read(struct ethernet_regs *eth, uint8_t phyaddr,
uint8_t regaddr)
{
uint32_t reg; /* convenient holder for the PHY register */
uint32_t phy; /* convenient holder for the PHY */
@@ -95,15 +95,13 @@ static int fec_mdio_read(struct ethernet_regs *eth, uint8_t phyAddr,
* programming the FEC's MII data register.
*/
writel(FEC_IEVENT_MII, &eth->ievent);
reg = regAddr << FEC_MII_DATA_RA_SHIFT;
phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
reg = regaddr << FEC_MII_DATA_RA_SHIFT;
phy = phyaddr << FEC_MII_DATA_PA_SHIFT;
writel(FEC_MII_DATA_ST | FEC_MII_DATA_OP_RD | FEC_MII_DATA_TA |
phy | reg, &eth->mii_data);
/*
* wait for the related interrupt
*/
/* wait for the related interrupt */
start = get_timer(0);
while (!(readl(&eth->ievent) & FEC_IEVENT_MII)) {
if (get_timer(start) > (CONFIG_SYS_HZ / 1000)) {
@@ -112,17 +110,13 @@ static int fec_mdio_read(struct ethernet_regs *eth, uint8_t phyAddr,
}
}
/*
* clear mii interrupt bit
*/
/* clear mii interrupt bit */
writel(FEC_IEVENT_MII, &eth->ievent);
/*
* it's now safe to read the PHY's register
*/
/* it's now safe to read the PHY's register */
val = (unsigned short)readl(&eth->mii_data);
debug("%s: phy: %02x reg:%02x val:%#x\n", __func__, phyAddr,
regAddr, val);
debug("%s: phy: %02x reg:%02x val:%#x\n", __func__, phyaddr,
regaddr, val);
return val;
}
@@ -153,22 +147,20 @@ static void fec_mii_setspeed(struct ethernet_regs *eth)
debug("%s: mii_speed %08x\n", __func__, readl(&eth->mii_speed));
}
static int fec_mdio_write(struct ethernet_regs *eth, uint8_t phyAddr,
uint8_t regAddr, uint16_t data)
static int fec_mdio_write(struct ethernet_regs *eth, uint8_t phyaddr,
uint8_t regaddr, uint16_t data)
{
uint32_t reg; /* convenient holder for the PHY register */
uint32_t phy; /* convenient holder for the PHY */
uint32_t start;
reg = regAddr << FEC_MII_DATA_RA_SHIFT;
phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
reg = regaddr << FEC_MII_DATA_RA_SHIFT;
phy = phyaddr << FEC_MII_DATA_PA_SHIFT;
writel(FEC_MII_DATA_ST | FEC_MII_DATA_OP_WR |
FEC_MII_DATA_TA | phy | reg | data, &eth->mii_data);
/*
* wait for the MII interrupt
*/
/* wait for the MII interrupt */
start = get_timer(0);
while (!(readl(&eth->ievent) & FEC_IEVENT_MII)) {
if (get_timer(start) > (CONFIG_SYS_HZ / 1000)) {
@@ -177,26 +169,24 @@ static int fec_mdio_write(struct ethernet_regs *eth, uint8_t phyAddr,
}
}
/*
* clear MII interrupt bit
*/
/* clear MII interrupt bit */
writel(FEC_IEVENT_MII, &eth->ievent);
debug("%s: phy: %02x reg:%02x val:%#x\n", __func__, phyAddr,
regAddr, data);
debug("%s: phy: %02x reg:%02x val:%#x\n", __func__, phyaddr,
regaddr, data);
return 0;
}
static int fec_phy_read(struct mii_dev *bus, int phyAddr, int dev_addr,
int regAddr)
static int fec_phy_read(struct mii_dev *bus, int phyaddr, int dev_addr,
int regaddr)
{
return fec_mdio_read(bus->priv, phyAddr, regAddr);
return fec_mdio_read(bus->priv, phyaddr, regaddr);
}
static int fec_phy_write(struct mii_dev *bus, int phyAddr, int dev_addr,
int regAddr, u16 data)
static int fec_phy_write(struct mii_dev *bus, int phyaddr, int dev_addr,
int regaddr, u16 data)
{
return fec_mdio_write(bus->priv, phyAddr, regAddr, data);
return fec_mdio_write(bus->priv, phyaddr, regaddr, data);
}
#ifndef CONFIG_PHYLIB
@@ -217,14 +207,12 @@ static int miiphy_restart_aneg(struct eth_device *dev)
fec_mdio_write(eth, fec->phy_id, MII_BMCR, BMCR_RESET);
udelay(1000);
/*
* Set the auto-negotiation advertisement register bits
*/
/* Set the auto-negotiation advertisement register bits */
fec_mdio_write(eth, fec->phy_id, MII_ADVERTISE,
LPA_100FULL | LPA_100HALF | LPA_10FULL |
LPA_10HALF | PHY_ANLPAR_PSB_802_3);
LPA_100FULL | LPA_100HALF | LPA_10FULL |
LPA_10HALF | PHY_ANLPAR_PSB_802_3);
fec_mdio_write(eth, fec->phy_id, MII_BMCR,
BMCR_ANENABLE | BMCR_ANRESTART);
BMCR_ANENABLE | BMCR_ANRESTART);
if (fec->mii_postcall)
ret = fec->mii_postcall(fec->phy_id);
@@ -241,9 +229,7 @@ static int miiphy_wait_aneg(struct eth_device *dev)
struct fec_priv *fec = (struct fec_priv *)dev->priv;
struct ethernet_regs *eth = fec->bus->priv;
/*
* Wait for AN completion
*/
/* Wait for AN completion */
start = get_timer(0);
do {
if (get_timer(start) > (CONFIG_SYS_HZ * 5)) {
@@ -254,7 +240,7 @@ static int miiphy_wait_aneg(struct eth_device *dev)
status = fec_mdio_read(eth, fec->phy_id, MII_BMSR);
if (status < 0) {
printf("%s: Autonegotiation failed. status: %d\n",
dev->name, status);
dev->name, status);
return -1;
}
} while (!(status & BMSR_LSTATUS));
@@ -351,65 +337,63 @@ static void fec_tbd_init(struct fec_priv *fec)
/**
* Mark the given read buffer descriptor as free
* @param[in] last 1 if this is the last buffer descriptor in the chain, else 0
* @param[in] pRbd buffer descriptor to mark free again
* @param[in] prbd buffer descriptor to mark free again
*/
static void fec_rbd_clean(int last, struct fec_bd *pRbd)
static void fec_rbd_clean(int last, struct fec_bd *prbd)
{
unsigned short flags = FEC_RBD_EMPTY;
if (last)
flags |= FEC_RBD_WRAP;
writew(flags, &pRbd->status);
writew(0, &pRbd->data_length);
writew(flags, &prbd->status);
writew(0, &prbd->data_length);
}
static int fec_get_hwaddr(struct eth_device *dev, int dev_id,
unsigned char *mac)
static int fec_get_hwaddr(int dev_id, unsigned char *mac)
{
imx_get_mac_from_fuse(dev_id, mac);
return !is_valid_ethaddr(mac);
}
#ifdef CONFIG_DM_ETH
static int fecmxc_set_hwaddr(struct udevice *dev)
#else
static int fec_set_hwaddr(struct eth_device *dev)
#endif
{
#ifdef CONFIG_DM_ETH
struct fec_priv *fec = dev_get_priv(dev);
struct eth_pdata *pdata = dev_get_platdata(dev);
uchar *mac = pdata->enetaddr;
#else
uchar *mac = dev->enetaddr;
struct fec_priv *fec = (struct fec_priv *)dev->priv;
#endif
writel(0, &fec->eth->iaddr1);
writel(0, &fec->eth->iaddr2);
writel(0, &fec->eth->gaddr1);
writel(0, &fec->eth->gaddr2);
/*
* Set physical address
*/
/* Set physical address */
writel((mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac[3],
&fec->eth->paddr1);
&fec->eth->paddr1);
writel((mac[4] << 24) + (mac[5] << 16) + 0x8808, &fec->eth->paddr2);
return 0;
}
/*
* Do initial configuration of the FEC registers
*/
/* Do initial configuration of the FEC registers */
static void fec_reg_setup(struct fec_priv *fec)
{
uint32_t rcntrl;
/*
* Set interrupt mask register
*/
/* Set interrupt mask register */
writel(0x00000000, &fec->eth->imask);
/*
* Clear FEC-Lite interrupt event register(IEVENT)
*/
/* Clear FEC-Lite interrupt event register(IEVENT) */
writel(0xffffffff, &fec->eth->ievent);
/*
* Set FEC-Lite receive control register(R_CNTRL):
*/
/* Set FEC-Lite receive control register(R_CNTRL): */
/* Start with frame length = 1518, common for all modes. */
rcntrl = PKTSIZE << FEC_RCNTRL_MAX_FL_SHIFT;
@@ -427,9 +411,17 @@ static void fec_reg_setup(struct fec_priv *fec)
* Start the FEC engine
* @param[in] dev Our device to handle
*/
#ifdef CONFIG_DM_ETH
static int fec_open(struct udevice *dev)
#else
static int fec_open(struct eth_device *edev)
#endif
{
#ifdef CONFIG_DM_ETH
struct fec_priv *fec = dev_get_priv(dev);
#else
struct fec_priv *fec = (struct fec_priv *)edev->priv;
#endif
int speed;
uint32_t addr, size;
int i;
@@ -453,22 +445,19 @@ static int fec_open(struct eth_device *edev)
#ifdef FEC_QUIRK_ENET_MAC
/* Enable ENET HW endian SWAP */
writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_DBSWAP,
&fec->eth->ecntrl);
&fec->eth->ecntrl);
/* Enable ENET store and forward mode */
writel(readl(&fec->eth->x_wmrk) | FEC_X_WMRK_STRFWD,
&fec->eth->x_wmrk);
&fec->eth->x_wmrk);
#endif
/*
* Enable FEC-Lite controller
*/
/* Enable FEC-Lite controller */
writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_ETHER_EN,
&fec->eth->ecntrl);
&fec->eth->ecntrl);
#if defined(CONFIG_MX25) || defined(CONFIG_MX53) || defined(CONFIG_MX6SL)
udelay(100);
/*
* setup the MII gasket for RMII mode
*/
/* setup the MII gasket for RMII mode */
/* disable the gasket */
writew(0, &fec->eth->miigsk_enr);
@@ -526,27 +515,35 @@ static int fec_open(struct eth_device *edev)
#endif
debug("%s:Speed=%i\n", __func__, speed);
/*
* Enable SmartDMA receive task
*/
/* Enable SmartDMA receive task */
fec_rx_task_enable(fec);
udelay(100000);
return 0;
}
static int fec_init(struct eth_device *dev, bd_t* bd)
#ifdef CONFIG_DM_ETH
static int fecmxc_init(struct udevice *dev)
#else
static int fec_init(struct eth_device *dev, bd_t *bd)
#endif
{
#ifdef CONFIG_DM_ETH
struct fec_priv *fec = dev_get_priv(dev);
#else
struct fec_priv *fec = (struct fec_priv *)dev->priv;
#endif
uint32_t mib_ptr = (uint32_t)&fec->eth->rmon_t_drop;
int i;
/* Initialize MAC address */
#ifdef CONFIG_DM_ETH
fecmxc_set_hwaddr(dev);
#else
fec_set_hwaddr(dev);
#endif
/*
* Setup transmit descriptors, there are two in total.
*/
/* Setup transmit descriptors, there are two in total. */
fec_tbd_init(fec);
/* Setup receive descriptors. */
@@ -557,18 +554,14 @@ static int fec_init(struct eth_device *dev, bd_t* bd)
if (fec->xcv_type != SEVENWIRE)
fec_mii_setspeed(fec->bus->priv);
/*
* Set Opcode/Pause Duration Register
*/
/* Set Opcode/Pause Duration Register */
writel(0x00010020, &fec->eth->op_pause); /* FIXME 0xffff0020; */
writel(0x2, &fec->eth->x_wmrk);
/*
* Set multicast address filter
*/
/* Set multicast address filter */
writel(0x00000000, &fec->eth->gaddr1);
writel(0x00000000, &fec->eth->gaddr2);
/* Do not access reserved register for i.MX6UL */
if (!is_mx6ul()) {
/* clear MIB RAM */
@@ -596,27 +589,29 @@ static int fec_init(struct eth_device *dev, bd_t* bd)
* Halt the FEC engine
* @param[in] dev Our device to handle
*/
#ifdef CONFIG_DM_ETH
static void fecmxc_halt(struct udevice *dev)
#else
static void fec_halt(struct eth_device *dev)
#endif
{
#ifdef CONFIG_DM_ETH
struct fec_priv *fec = dev_get_priv(dev);
#else
struct fec_priv *fec = (struct fec_priv *)dev->priv;
#endif
int counter = 0xffff;
/*
* issue graceful stop command to the FEC transmitter if necessary
*/
/* issue graceful stop command to the FEC transmitter if necessary */
writel(FEC_TCNTRL_GTS | readl(&fec->eth->x_cntrl),
&fec->eth->x_cntrl);
&fec->eth->x_cntrl);
debug("eth_halt: wait for stop regs\n");
/*
* wait for graceful stop to register
*/
/* wait for graceful stop to register */
while ((counter--) && (!(readl(&fec->eth->ievent) & FEC_IEVENT_GRA)))
udelay(1);
/*
* Disable SmartDMA tasks
*/
/* Disable SmartDMA tasks */
fec_tx_task_disable(fec);
fec_rx_task_disable(fec);
@@ -625,7 +620,7 @@ static void fec_halt(struct eth_device *dev)
* Note: this will also reset the BD index counter!
*/
writel(readl(&fec->eth->ecntrl) & ~FEC_ECNTRL_ETHER_EN,
&fec->eth->ecntrl);
&fec->eth->ecntrl);
fec->rbd_index = 0;
fec->tbd_index = 0;
debug("eth_halt: done\n");
@@ -638,7 +633,11 @@ static void fec_halt(struct eth_device *dev)
* @param[in] length Data count in bytes
* @return 0 on success
*/
#ifdef CONFIG_DM_ETH
static int fecmxc_send(struct udevice *dev, void *packet, int length)
#else
static int fec_send(struct eth_device *dev, void *packet, int length)
#endif
{
unsigned int status;
uint32_t size, end;
@@ -650,7 +649,11 @@ static int fec_send(struct eth_device *dev, void *packet, int length)
* This routine transmits one frame. This routine only accepts
* 6-byte Ethernet addresses.
*/
#ifdef CONFIG_DM_ETH
struct fec_priv *fec = dev_get_priv(dev);
#else
struct fec_priv *fec = (struct fec_priv *)dev->priv;
#endif
/*
* Check for valid length of data.
@@ -720,9 +723,7 @@ static int fec_send(struct eth_device *dev, void *packet, int length)
*/
readl(addr + size - 4);
/*
* Enable SmartDMA transmit task
*/
/* Enable SmartDMA transmit task */
fec_tx_task_enable(fec);
/*
@@ -767,8 +768,8 @@ static int fec_send(struct eth_device *dev, void *packet, int length)
out:
debug("fec_send: status 0x%x index %d ret %i\n",
readw(&fec->tbd_base[fec->tbd_index].status),
fec->tbd_index, ret);
readw(&fec->tbd_base[fec->tbd_index].status),
fec->tbd_index, ret);
/* for next transmission use the other buffer */
if (fec->tbd_index)
fec->tbd_index = 0;
@@ -783,9 +784,17 @@ out:
* @param[in] dev Our ethernet device to handle
* @return Length of packet read
*/
#ifdef CONFIG_DM_ETH
static int fecmxc_recv(struct udevice *dev, int flags, uchar **packetp)
#else
static int fec_recv(struct eth_device *dev)
#endif
{
#ifdef CONFIG_DM_ETH
struct fec_priv *fec = dev_get_priv(dev);
#else
struct fec_priv *fec = (struct fec_priv *)dev->priv;
#endif
struct fec_bd *rbd = &fec->rbd_base[fec->rbd_index];
unsigned long ievent;
int frame_length, len = 0;
@@ -794,30 +803,41 @@ static int fec_recv(struct eth_device *dev)
int i;
ALLOC_CACHE_ALIGN_BUFFER(uchar, buff, FEC_MAX_PKT_SIZE);
/*
* Check if any critical events have happened
*/
/* Check if any critical events have happened */
ievent = readl(&fec->eth->ievent);
writel(ievent, &fec->eth->ievent);
debug("fec_recv: ievent 0x%lx\n", ievent);
if (ievent & FEC_IEVENT_BABR) {
#ifdef CONFIG_DM_ETH
fecmxc_halt(dev);
fecmxc_init(dev);
#else
fec_halt(dev);
fec_init(dev, fec->bd);
#endif
printf("some error: 0x%08lx\n", ievent);
return 0;
}
if (ievent & FEC_IEVENT_HBERR) {
/* Heartbeat error */
writel(0x00000001 | readl(&fec->eth->x_cntrl),
&fec->eth->x_cntrl);
&fec->eth->x_cntrl);
}
if (ievent & FEC_IEVENT_GRA) {
/* Graceful stop complete */
if (readl(&fec->eth->x_cntrl) & 0x00000001) {
#ifdef CONFIG_DM_ETH
fecmxc_halt(dev);
#else
fec_halt(dev);
#endif
writel(~0x00000001 & readl(&fec->eth->x_cntrl),
&fec->eth->x_cntrl);
&fec->eth->x_cntrl);
#ifdef CONFIG_DM_ETH
fecmxc_init(dev);
#else
fec_init(dev, fec->bd);
#endif
}
}
@@ -844,22 +864,16 @@ static int fec_recv(struct eth_device *dev)
if (!(bd_status & FEC_RBD_EMPTY)) {
if ((bd_status & FEC_RBD_LAST) && !(bd_status & FEC_RBD_ERR) &&
((readw(&rbd->data_length) - 4) > 14)) {
/*
* Get buffer address and size
*/
((readw(&rbd->data_length) - 4) > 14)) {
/* Get buffer address and size */
addr = readl(&rbd->data_pointer);
frame_length = readw(&rbd->data_length) - 4;
/*
* Invalidate data cache over the buffer
*/
/* Invalidate data cache over the buffer */
end = roundup(addr + frame_length, ARCH_DMA_MINALIGN);
addr &= ~(ARCH_DMA_MINALIGN - 1);
invalidate_dcache_range(addr, end);
/*
* Fill the buffer and pass it to upper layers
*/
/* Fill the buffer and pass it to upper layers */
#ifdef CONFIG_FEC_MXC_SWAP_PACKET
swap_packet((uint32_t *)addr, frame_length);
#endif
@@ -887,7 +901,7 @@ static int fec_recv(struct eth_device *dev)
&fec->rbd_base[i]);
}
flush_dcache_range(addr,
addr + ARCH_DMA_MINALIGN);
addr + ARCH_DMA_MINALIGN);
}
fec_rx_task_enable(fec);
@@ -971,6 +985,33 @@ static void fec_free_descs(struct fec_priv *fec)
free(fec->tbd_base);
}
struct mii_dev *fec_get_miibus(uint32_t base_addr, int dev_id)
{
struct ethernet_regs *eth = (struct ethernet_regs *)base_addr;
struct mii_dev *bus;
int ret;
bus = mdio_alloc();
if (!bus) {
printf("mdio_alloc failed\n");
return NULL;
}
bus->read = fec_phy_read;
bus->write = fec_phy_write;
bus->priv = eth;
fec_set_dev_name(bus->name, dev_id);
ret = mdio_register(bus);
if (ret) {
printf("mdio_register failed\n");
free(bus);
return NULL;
}
fec_mii_setspeed(eth);
return bus;
}
#ifndef CONFIG_DM_ETH
#ifdef CONFIG_PHYLIB
int fec_probe(bd_t *bd, int dev_id, uint32_t base_addr,
struct mii_dev *bus, struct phy_device *phydev)
@@ -1045,7 +1086,7 @@ static int fec_probe(bd_t *bd, int dev_id, uint32_t base_addr,
#endif
eth_register(edev);
if (fec_get_hwaddr(edev, dev_id, ethaddr) == 0) {
if (fec_get_hwaddr(dev_id, ethaddr) == 0) {
debug("got MAC%d address from fuse: %pM\n", dev_id, ethaddr);
memcpy(edev->enetaddr, ethaddr, 6);
if (!getenv("ethaddr"))
@@ -1062,32 +1103,6 @@ err1:
return ret;
}
struct mii_dev *fec_get_miibus(uint32_t base_addr, int dev_id)
{
struct ethernet_regs *eth = (struct ethernet_regs *)base_addr;
struct mii_dev *bus;
int ret;
bus = mdio_alloc();
if (!bus) {
printf("mdio_alloc failed\n");
return NULL;
}
bus->read = fec_phy_read;
bus->write = fec_phy_write;
bus->priv = eth;
fec_set_dev_name(bus->name, dev_id);
ret = mdio_register(bus);
if (ret) {
printf("mdio_register failed\n");
free(bus);
return NULL;
}
fec_mii_setspeed(eth);
return bus;
}
int fecmxc_initialize_multi(bd_t *bd, int dev_id, int phy_id, uint32_t addr)
{
uint32_t base_mii;
@@ -1147,3 +1162,151 @@ int fecmxc_register_mii_postcall(struct eth_device *dev, int (*cb)(int))
return 0;
}
#endif
#else
static int fecmxc_read_rom_hwaddr(struct udevice *dev)
{
struct fec_priv *priv = dev_get_priv(dev);
struct eth_pdata *pdata = dev_get_platdata(dev);
return fec_get_hwaddr(priv->dev_id, pdata->enetaddr);
}
static const struct eth_ops fecmxc_ops = {
.start = fecmxc_init,
.send = fecmxc_send,
.recv = fecmxc_recv,
.stop = fecmxc_halt,
.write_hwaddr = fecmxc_set_hwaddr,
.read_rom_hwaddr = fecmxc_read_rom_hwaddr,
};
static int fec_phy_init(struct fec_priv *priv, struct udevice *dev)
{
struct phy_device *phydev;
int mask = 0xffffffff;
#ifdef CONFIG_PHYLIB
mask = 1 << CONFIG_FEC_MXC_PHYADDR;
#endif
phydev = phy_find_by_mask(priv->bus, mask, priv->interface);
if (!phydev)
return -ENODEV;
phy_connect_dev(phydev, dev);
priv->phydev = phydev;
phy_config(phydev);
return 0;
}
static int fecmxc_probe(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_platdata(dev);
struct fec_priv *priv = dev_get_priv(dev);
struct mii_dev *bus = NULL;
int dev_id = -1;
uint32_t start;
int ret;
ret = fec_alloc_descs(priv);
if (ret)
return ret;
bus = fec_get_miibus((uint32_t)priv->eth, dev_id);
if (!bus)
goto err_mii;
priv->bus = bus;
priv->xcv_type = CONFIG_FEC_XCV_TYPE;
priv->interface = pdata->phy_interface;
ret = fec_phy_init(priv, dev);
if (ret)
goto err_phy;
/* Reset chip. */
writel(readl(&priv->eth->ecntrl) | FEC_ECNTRL_RESET,
&priv->eth->ecntrl);
start = get_timer(0);
while (readl(&priv->eth->ecntrl) & FEC_ECNTRL_RESET) {
if (get_timer(start) > (CONFIG_SYS_HZ * 5)) {
printf("FEC MXC: Timeout reseting chip\n");
goto err_timeout;
}
udelay(10);
}
fec_reg_setup(priv);
fec_set_dev_name((char *)dev->name, dev_id);
priv->dev_id = (dev_id == -1) ? 0 : dev_id;
return 0;
err_timeout:
free(priv->phydev);
err_phy:
mdio_unregister(bus);
free(bus);
err_mii:
fec_free_descs(priv);
return ret;
}
static int fecmxc_remove(struct udevice *dev)
{
struct fec_priv *priv = dev_get_priv(dev);
free(priv->phydev);
fec_free_descs(priv);
mdio_unregister(priv->bus);
mdio_free(priv->bus);
return 0;
}
static int fecmxc_ofdata_to_platdata(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_platdata(dev);
struct fec_priv *priv = dev_get_priv(dev);
const char *phy_mode;
pdata->iobase = (phys_addr_t)dev_get_addr(dev);
priv->eth = (struct ethernet_regs *)pdata->iobase;
pdata->phy_interface = -1;
phy_mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy-mode", NULL);
if (phy_mode)
pdata->phy_interface = phy_get_interface_by_name(phy_mode);
if (pdata->phy_interface == -1) {
debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
return -EINVAL;
}
/* TODO
* Need to get the reset-gpio and related properties from DT
* and implemet the enet reset code on .probe call
*/
return 0;
}
static const struct udevice_id fecmxc_ids[] = {
{ .compatible = "fsl,imx6q-fec" },
{ }
};
U_BOOT_DRIVER(fecmxc_gem) = {
.name = "fecmxc",
.id = UCLASS_ETH,
.of_match = fecmxc_ids,
.ofdata_to_platdata = fecmxc_ofdata_to_platdata,
.probe = fecmxc_probe,
.remove = fecmxc_remove,
.ops = &fecmxc_ops,
.priv_auto_alloc_size = sizeof(struct fec_priv),
.platdata_auto_alloc_size = sizeof(struct eth_pdata),
};
#endif
+12 -19
View File
@@ -14,21 +14,14 @@
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __FEC_MXC_H
#define __FEC_MXC_H
void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);
/**
* Layout description of the FEC
*/
/* Layout description of the FEC */
struct ethernet_regs {
/* [10:2]addr = 00 */
/* [10:2]addr = 00 */
/* Control and status Registers (offset 000-1FF) */
/* Control and status Registers (offset 000-1FF) */
uint32_t res0[1]; /* MBAR_ETH + 0x000 */
uint32_t ievent; /* MBAR_ETH + 0x004 */
uint32_t imask; /* MBAR_ETH + 0x008 */
@@ -71,8 +64,7 @@ struct ethernet_regs {
uint32_t emrbr; /* MBAR_ETH + 0x188 */
uint32_t res12[29]; /* MBAR_ETH + 0x18C-1FC */
/* MIB COUNTERS (Offset 200-2FF) */
/* MIB COUNTERS (Offset 200-2FF) */
uint32_t rmon_t_drop; /* MBAR_ETH + 0x200 */
uint32_t rmon_t_packets; /* MBAR_ETH + 0x204 */
uint32_t rmon_t_bc_pkt; /* MBAR_ETH + 0x208 */
@@ -174,7 +166,6 @@ struct ethernet_regs {
#define FEC_IMASKT_RL 0x00100000
#define FEC_IMASK_UN 0x00080000
#define FEC_RCNTRL_MAX_FL_SHIFT 16
#define FEC_RCNTRL_LOOP 0x00000001
#define FEC_RCNTRL_DRT 0x00000002
@@ -233,9 +224,7 @@ struct fec_bd {
uint32_t data_pointer; /* payload's buffer address */
};
/**
* Supported phy types on this platform
*/
/* Supported phy types on this platform */
enum xceiver_type {
SEVENWIRE, /* 7-wire */
MII10, /* MII 10Mbps */
@@ -244,9 +233,7 @@ enum xceiver_type {
RGMII, /* RGMII */
};
/**
* @brief i.MX27-FEC private structure
*/
/* @brief i.MX27-FEC private structure */
struct fec_priv {
struct ethernet_regs *eth; /* pointer to register'S base */
enum xceiver_type xcv_type; /* transceiver type */
@@ -264,8 +251,14 @@ struct fec_priv {
int phy_id;
int (*mii_postcall)(int);
#endif
#ifdef CONFIG_DM_ETH
u32 interface;
#endif
};
void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);
/**
* @brief Numbers of buffer descriptors for receiving
*
+14
View File
@@ -1,6 +1,20 @@
config PINCTRL_IMX
bool
config PINCTRL_IMX5
bool "IMX5 pinctrl driver"
depends on ARCH_MX5 && PINCTRL_FULL
select DEVRES
select PINCTRL_IMX
help
Say Y here to enable the imx5 pinctrl driver
This provides a simple pinctrl driver for i.MX 53SoC familiy,
i.MX53. This feature depends on device tree
configuration. This driver is different from the linux one,
this is a simple implementation, only parses the 'fsl,pins'
property and configure related registers.
config PINCTRL_IMX6
bool "IMX6 pinctrl driver"
depends on ARCH_MX6 && PINCTRL_FULL
+1
View File
@@ -1,3 +1,4 @@
obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o
obj-$(CONFIG_PINCTRL_IMX5) += pinctrl-imx5.o
obj-$(CONFIG_PINCTRL_IMX6) += pinctrl-imx6.o
obj-$(CONFIG_PINCTRL_IMX7) += pinctrl-imx7.o
+44
View File
@@ -0,0 +1,44 @@
/*
* Copyright (C) 2016 Peng Fan <van.freenix@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <dm/device.h>
#include <dm/pinctrl.h>
#include "pinctrl-imx.h"
static struct imx_pinctrl_soc_info imx5_pinctrl_soc_info;
static int imx5_pinctrl_probe(struct udevice *dev)
{
struct imx_pinctrl_soc_info *info =
(struct imx_pinctrl_soc_info *)dev_get_driver_data(dev);
return imx_pinctrl_probe(dev, info);
}
static const struct udevice_id imx5_pinctrl_match[] = {
{
.compatible = "fsl,imx53-iomuxc",
.data = (ulong)&imx5_pinctrl_soc_info
},
{
.compatible = "fsl,imx53-iomuxc-gpr",
.data = (ulong)&imx5_pinctrl_soc_info
},
{ /* sentinel */ }
};
U_BOOT_DRIVER(imx5_pinctrl) = {
.name = "imx5-pinctrl",
.id = UCLASS_PINCTRL,
.of_match = of_match_ptr(imx5_pinctrl_match),
.probe = imx5_pinctrl_probe,
.remove = imx_pinctrl_remove,
.priv_auto_alloc_size = sizeof(struct imx_pinctrl_priv),
.ops = &imx_pinctrl_ops,
.flags = DM_FLAG_PRE_RELOC,
};
+2
View File
@@ -28,6 +28,8 @@ static const struct udevice_id imx6_pinctrl_match[] = {
{ .compatible = "fsl,imx6q-iomuxc", .data = (ulong)&imx6_pinctrl_soc_info },
{ .compatible = "fsl,imx6dl-iomuxc", .data = (ulong)&imx6_pinctrl_soc_info },
{ .compatible = "fsl,imx6sl-iomuxc", .data = (ulong)&imx6_pinctrl_soc_info },
{ .compatible = "fsl,imx6sll-iomuxc-snvs", .data = (ulong)&imx6_snvs_pinctrl_soc_info },
{ .compatible = "fsl,imx6sll-iomuxc", .data = (ulong)&imx6_pinctrl_soc_info },
{ .compatible = "fsl,imx6sx-iomuxc", .data = (ulong)&imx6_pinctrl_soc_info },
{ .compatible = "fsl,imx6ul-iomuxc", .data = (ulong)&imx6_pinctrl_soc_info },
{ .compatible = "fsl,imx6ull-iomuxc-snvs", .data = (ulong)&imx6_snvs_pinctrl_soc_info },
+1 -1
View File
@@ -325,7 +325,7 @@ config MVEBU_A3700_UART
config MXC_UART
bool "IMX serial port support"
depends on MX6
depends on MX5 || MX6
help
If you have a machine based on a Motorola IMX CPU you
can enable its onboard serial port by enabling this option.
+7
View File
@@ -443,6 +443,13 @@ config VIDEO
model. Video drivers typically provide a colour text console and
cursor.
config VIDEO_IPUV3
bool "i.MX IPUv3 Core video support"
depends on VIDEO && MX6
help
This enables framebuffer driver for i.MX processors working
on the IPUv3(Image Processing Unit) internal graphic processor.
config CFB_CONSOLE
bool "Enable colour frame buffer console"
depends on VIDEO