summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpio/pca953x_gpio.c9
-rw-r--r--drivers/mtd/nand/am335x_spl_bch.c15
-rw-r--r--drivers/mtd/spi/spi_spl_load.c37
-rw-r--r--drivers/net/designware.c59
-rw-r--r--drivers/net/designware.h4
-rw-r--r--drivers/serial/Kconfig15
-rw-r--r--drivers/serial/Makefile1
-rw-r--r--drivers/serial/serial_meson.c162
-rw-r--r--drivers/usb/dwc3/Makefile2
9 files changed, 265 insertions, 39 deletions
diff --git a/drivers/gpio/pca953x_gpio.c b/drivers/gpio/pca953x_gpio.c
index 987d10e..065b181 100644
--- a/drivers/gpio/pca953x_gpio.c
+++ b/drivers/gpio/pca953x_gpio.c
@@ -16,8 +16,8 @@
*
* TODO:
* 1. Support PCA957X_TYPE
- * 2. Support max 40 gpio pins
- * 3. Support Plolarity Inversion
+ * 2. Support 24 gpio pins
+ * 3. Support Polarity Inversion
*/
#include <common.h>
@@ -47,7 +47,7 @@ enum {
PCA953X_DIRECTION_OUT,
};
-#define MAX_BANK 3
+#define MAX_BANK 5
#define BANK_SZ 8
DECLARE_GLOBAL_DATA_PTR;
@@ -121,6 +121,9 @@ static int pca953x_read_regs(struct udevice *dev, int reg, u8 *val)
ret = dm_i2c_read(dev, reg, val, 1);
} else if (info->gpio_count <= 16) {
ret = dm_i2c_read(dev, reg << 1, val, info->bank_count);
+ } else if (info->gpio_count == 40) {
+ /* Auto increment */
+ ret = dm_i2c_read(dev, (reg << 3) | 0x80, val, info->bank_count);
} else {
dev_err(dev, "Unsupported now\n");
return -EINVAL;
diff --git a/drivers/mtd/nand/am335x_spl_bch.c b/drivers/mtd/nand/am335x_spl_bch.c
index bf8b2ee..31c7825 100644
--- a/drivers/mtd/nand/am335x_spl_bch.c
+++ b/drivers/mtd/nand/am335x_spl_bch.c
@@ -173,7 +173,7 @@ static int nand_read_page(int block, int page, void *dst)
int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
{
unsigned int block, lastblock;
- unsigned int page;
+ unsigned int page, page_offset;
/*
* offs has to be aligned to a page address!
@@ -181,6 +181,7 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
block = offs / CONFIG_SYS_NAND_BLOCK_SIZE;
lastblock = (offs + size - 1) / CONFIG_SYS_NAND_BLOCK_SIZE;
page = (offs % CONFIG_SYS_NAND_BLOCK_SIZE) / CONFIG_SYS_NAND_PAGE_SIZE;
+ page_offset = offs % CONFIG_SYS_NAND_PAGE_SIZE;
while (block <= lastblock) {
if (!nand_is_bad_block(block)) {
@@ -189,6 +190,18 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
*/
while (page < CONFIG_SYS_NAND_PAGE_COUNT) {
nand_read_page(block, page, dst);
+ /*
+ * When offs is not aligned to page address the
+ * extra offset is copied to dst as well. Copy
+ * the image such that its first byte will be
+ * at the dst.
+ */
+ if (unlikely(page_offset)) {
+ memmove(dst, dst + page_offset,
+ CONFIG_SYS_NAND_PAGE_SIZE);
+ dst = (void *)((int)dst - page_offset);
+ page_offset = 0;
+ }
dst += CONFIG_SYS_NAND_PAGE_SIZE;
page++;
}
diff --git a/drivers/mtd/spi/spi_spl_load.c b/drivers/mtd/spi/spi_spl_load.c
index 46c98a9..bac1e85 100644
--- a/drivers/mtd/spi/spi_spl_load.c
+++ b/drivers/mtd/spi/spi_spl_load.c
@@ -48,6 +48,18 @@ static int spi_load_image_os(struct spi_flash *flash,
}
#endif
+static ulong spl_spi_fit_read(struct spl_load_info *load, ulong sector,
+ ulong count, void *buf)
+{
+ struct spi_flash *flash = load->dev;
+ ulong ret;
+
+ ret = spi_flash_read(flash, sector, count, buf);
+ if (!ret)
+ return count;
+ else
+ return 0;
+}
/*
* The main entry for SPI booting. It's necessary that SDRAM is already
* configured and available since this code loads the main U-Boot image
@@ -85,11 +97,26 @@ int spl_spi_load_image(void)
if (err)
return err;
- err = spl_parse_image_header(header);
- if (err)
- return err;
- err = spi_flash_read(flash, CONFIG_SYS_SPI_U_BOOT_OFFS,
- spl_image.size, (void *)spl_image.load_addr);
+ if (IS_ENABLED(CONFIG_SPL_LOAD_FIT)) {
+ struct spl_load_info load;
+
+ debug("Found FIT\n");
+ load.dev = flash;
+ load.priv = NULL;
+ load.filename = NULL;
+ load.bl_len = 1;
+ load.read = spl_spi_fit_read;
+ err = spl_load_simple_fit(&load,
+ CONFIG_SYS_SPI_U_BOOT_OFFS,
+ header);
+ } else {
+ err = spl_parse_image_header(header);
+ if (err)
+ return err;
+ err = spi_flash_read(flash, CONFIG_SYS_SPI_U_BOOT_OFFS,
+ spl_image.size,
+ (void *)spl_image.load_addr);
+ }
}
return err;
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index 14dd7b8..8858f07 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -145,8 +145,8 @@ static void tx_descs_init(struct dw_eth_dev *priv)
for (idx = 0; idx < CONFIG_TX_DESCR_NUM; idx++) {
desc_p = &desc_table_p[idx];
- desc_p->dmamac_addr = &txbuffs[idx * CONFIG_ETH_BUFSIZE];
- desc_p->dmamac_next = &desc_table_p[idx + 1];
+ desc_p->dmamac_addr = (ulong)&txbuffs[idx * CONFIG_ETH_BUFSIZE];
+ desc_p->dmamac_next = (ulong)&desc_table_p[idx + 1];
#if defined(CONFIG_DW_ALTDESCRIPTOR)
desc_p->txrx_status &= ~(DESC_TXSTS_TXINT | DESC_TXSTS_TXLAST |
@@ -164,11 +164,11 @@ static void tx_descs_init(struct dw_eth_dev *priv)
}
/* Correcting the last pointer of the chain */
- desc_p->dmamac_next = &desc_table_p[0];
+ desc_p->dmamac_next = (ulong)&desc_table_p[0];
/* Flush all Tx buffer descriptors at once */
- flush_dcache_range((unsigned int)priv->tx_mac_descrtable,
- (unsigned int)priv->tx_mac_descrtable +
+ flush_dcache_range((ulong)priv->tx_mac_descrtable,
+ (ulong)priv->tx_mac_descrtable +
sizeof(priv->tx_mac_descrtable));
writel((ulong)&desc_table_p[0], &dma_p->txdesclistaddr);
@@ -189,13 +189,12 @@ static void rx_descs_init(struct dw_eth_dev *priv)
* Otherwise there's a chance to get some of them flushed in RAM when
* GMAC is already pushing data to RAM via DMA. This way incoming from
* GMAC data will be corrupted. */
- flush_dcache_range((unsigned int)rxbuffs, (unsigned int)rxbuffs +
- RX_TOTAL_BUFSIZE);
+ flush_dcache_range((ulong)rxbuffs, (ulong)rxbuffs + RX_TOTAL_BUFSIZE);
for (idx = 0; idx < CONFIG_RX_DESCR_NUM; idx++) {
desc_p = &desc_table_p[idx];
- desc_p->dmamac_addr = &rxbuffs[idx * CONFIG_ETH_BUFSIZE];
- desc_p->dmamac_next = &desc_table_p[idx + 1];
+ desc_p->dmamac_addr = (ulong)&rxbuffs[idx * CONFIG_ETH_BUFSIZE];
+ desc_p->dmamac_next = (ulong)&desc_table_p[idx + 1];
desc_p->dmamac_cntl =
(MAC_MAX_FRAME_SZ & DESC_RXCTRL_SIZE1MASK) |
@@ -205,11 +204,11 @@ static void rx_descs_init(struct dw_eth_dev *priv)
}
/* Correcting the last pointer of the chain */
- desc_p->dmamac_next = &desc_table_p[0];
+ desc_p->dmamac_next = (ulong)&desc_table_p[0];
/* Flush all Rx buffer descriptors at once */
- flush_dcache_range((unsigned int)priv->rx_mac_descrtable,
- (unsigned int)priv->rx_mac_descrtable +
+ flush_dcache_range((ulong)priv->rx_mac_descrtable,
+ (ulong)priv->rx_mac_descrtable +
sizeof(priv->rx_mac_descrtable));
writel((ulong)&desc_table_p[0], &dma_p->rxdesclistaddr);
@@ -337,12 +336,11 @@ static int _dw_eth_send(struct dw_eth_dev *priv, void *packet, int length)
struct eth_dma_regs *dma_p = priv->dma_regs_p;
u32 desc_num = priv->tx_currdescnum;
struct dmamacdescr *desc_p = &priv->tx_mac_descrtable[desc_num];
- uint32_t desc_start = (uint32_t)desc_p;
- uint32_t desc_end = desc_start +
+ ulong desc_start = (ulong)desc_p;
+ ulong desc_end = desc_start +
roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN);
- uint32_t data_start = (uint32_t)desc_p->dmamac_addr;
- uint32_t data_end = data_start +
- roundup(length, ARCH_DMA_MINALIGN);
+ ulong data_start = desc_p->dmamac_addr;
+ ulong data_end = data_start + roundup(length, ARCH_DMA_MINALIGN);
/*
* Strictly we only need to invalidate the "txrx_status" field
* for the following check, but on some platforms we cannot
@@ -359,7 +357,7 @@ static int _dw_eth_send(struct dw_eth_dev *priv, void *packet, int length)
return -EPERM;
}
- memcpy(desc_p->dmamac_addr, packet, length);
+ memcpy((void *)data_start, packet, length);
/* Flush data to be sent */
flush_dcache_range(data_start, data_end);
@@ -399,11 +397,11 @@ static int _dw_eth_recv(struct dw_eth_dev *priv, uchar **packetp)
u32 status, desc_num = priv->rx_currdescnum;
struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num];
int length = -EAGAIN;
- uint32_t desc_start = (uint32_t)desc_p;
- uint32_t desc_end = desc_start +
+ ulong desc_start = (ulong)desc_p;
+ ulong desc_end = desc_start +
roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN);
- uint32_t data_start = (uint32_t)desc_p->dmamac_addr;
- uint32_t data_end;
+ ulong data_start = desc_p->dmamac_addr;
+ ulong data_end;
/* Invalidate entire buffer descriptor */
invalidate_dcache_range(desc_start, desc_end);
@@ -419,7 +417,7 @@ static int _dw_eth_recv(struct dw_eth_dev *priv, uchar **packetp)
/* Invalidate received data */
data_end = data_start + roundup(length, ARCH_DMA_MINALIGN);
invalidate_dcache_range(data_start, data_end);
- *packetp = desc_p->dmamac_addr;
+ *packetp = (uchar *)(ulong)desc_p->dmamac_addr;
}
return length;
@@ -429,8 +427,8 @@ static int _dw_free_pkt(struct dw_eth_dev *priv)
{
u32 desc_num = priv->rx_currdescnum;
struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num];
- uint32_t desc_start = (uint32_t)desc_p;
- uint32_t desc_end = desc_start +
+ ulong desc_start = (ulong)desc_p;
+ ulong desc_end = desc_start +
roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN);
/*
@@ -535,6 +533,11 @@ int designware_initialize(ulong base_addr, u32 interface)
return -ENOMEM;
}
+ if ((phys_addr_t)priv + sizeof(*priv) > (1ULL << 32)) {
+ printf("designware: buffers are outside DMA memory\n");
+ return -EINVAL;
+ }
+
memset(dev, 0, sizeof(struct eth_device));
memset(priv, 0, sizeof(struct dw_eth_dev));
@@ -630,6 +633,7 @@ static int designware_eth_probe(struct udevice *dev)
struct eth_pdata *pdata = dev_get_platdata(dev);
struct dw_eth_dev *priv = dev_get_priv(dev);
u32 iobase = pdata->iobase;
+ ulong ioaddr;
int ret;
#ifdef CONFIG_DM_PCI
@@ -648,8 +652,9 @@ static int designware_eth_probe(struct udevice *dev)
#endif
debug("%s, iobase=%x, priv=%p\n", __func__, iobase, priv);
- priv->mac_regs_p = (struct eth_mac_regs *)iobase;
- priv->dma_regs_p = (struct eth_dma_regs *)(iobase + DW_DMA_BASE_OFFSET);
+ ioaddr = iobase;
+ priv->mac_regs_p = (struct eth_mac_regs *)ioaddr;
+ priv->dma_regs_p = (struct eth_dma_regs *)(ioaddr + DW_DMA_BASE_OFFSET);
priv->interface = pdata->phy_interface;
priv->max_speed = pdata->max_speed;
diff --git a/drivers/net/designware.h b/drivers/net/designware.h
index 04a45e0..51ba769 100644
--- a/drivers/net/designware.h
+++ b/drivers/net/designware.h
@@ -112,8 +112,8 @@ struct eth_dma_regs {
struct dmamacdescr {
u32 txrx_status;
u32 dmamac_cntl;
- void *dmamac_addr;
- struct dmamacdescr *dmamac_next;
+ u32 dmamac_addr;
+ u32 dmamac_next;
} __aligned(ARCH_DMA_MINALIGN);
/*
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 2497ae9..0e38903 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -121,6 +121,14 @@ config DEBUG_UART_S5P
will need to provide parameters to make this work. The driver will
be available until the real driver-model serial is running.
+config DEBUG_UART_MESON
+ bool "Amlogic Meson"
+ depends on MESON_SERIAL
+ help
+ Select this to enable a debug UART using the serial_meson driver. You
+ will need to provide parameters to make this work. The driver will
+ be available until the real driver-model serial is running.
+
config DEBUG_UART_UARTLITE
bool "Xilinx Uartlite"
help
@@ -338,6 +346,13 @@ config XILINX_UARTLITE
If you have a Xilinx based board and want to use the uartlite
serial ports, say Y to this option. If unsure, say N.
+config MESON_SERIAL
+ bool "Support for Amlogic Meson UART"
+ depends on DM_SERIAL && ARCH_MESON
+ help
+ If you have an Amlogic Meson based board and want to use the on-chip
+ serial ports, say Y to this option. If unsure, say N.
+
config MSM_SERIAL
bool "Qualcomm on-chip UART"
depends on DM_SERIAL
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 9def128..e1e28de 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_SYS_NS16550) += ns16550.o
obj-$(CONFIG_S5P) += serial_s5p.o
obj-$(CONFIG_MXC_UART) += serial_mxc.o
obj-$(CONFIG_PXA_SERIAL) += serial_pxa.o
+obj-$(CONFIG_MESON_SERIAL) += serial_meson.o
obj-$(CONFIG_S3C24X0_SERIAL) += serial_s3c24x0.o
obj-$(CONFIG_XILINX_UARTLITE) += serial_xuartlite.o
obj-$(CONFIG_SANDBOX_SERIAL) += sandbox.o
diff --git a/drivers/serial/serial_meson.c b/drivers/serial/serial_meson.c
new file mode 100644
index 0000000..1b49426
--- /dev/null
+++ b/drivers/serial/serial_meson.c
@@ -0,0 +1,162 @@
+/*
+ * (C) Copyright 2016 Beniamino Galvani <b.galvani@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <linux/compiler.h>
+#include <serial.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct meson_uart {
+ u32 wfifo;
+ u32 rfifo;
+ u32 control;
+ u32 status;
+ u32 misc;
+};
+
+struct meson_serial_platdata {
+ struct meson_uart *reg;
+};
+
+/* AML_UART_STATUS bits */
+#define AML_UART_PARITY_ERR BIT(16)
+#define AML_UART_FRAME_ERR BIT(17)
+#define AML_UART_TX_FIFO_WERR BIT(18)
+#define AML_UART_RX_EMPTY BIT(20)
+#define AML_UART_TX_FULL BIT(21)
+#define AML_UART_TX_EMPTY BIT(22)
+#define AML_UART_XMIT_BUSY BIT(25)
+#define AML_UART_ERR (AML_UART_PARITY_ERR | \
+ AML_UART_FRAME_ERR | \
+ AML_UART_TX_FIFO_WERR)
+
+/* AML_UART_CONTROL bits */
+#define AML_UART_TX_EN BIT(12)
+#define AML_UART_RX_EN BIT(13)
+#define AML_UART_TX_RST BIT(22)
+#define AML_UART_RX_RST BIT(23)
+#define AML_UART_CLR_ERR BIT(24)
+
+static void meson_serial_init(struct meson_uart *uart)
+{
+ u32 val;
+
+ val = readl(&uart->control);
+ val |= (AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLR_ERR);
+ writel(val, &uart->control);
+ val &= ~(AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLR_ERR);
+ writel(val, &uart->control);
+ val |= (AML_UART_RX_EN | AML_UART_TX_EN);
+ writel(val, &uart->control);
+}
+
+static int meson_serial_probe(struct udevice *dev)
+{
+ struct meson_serial_platdata *plat = dev->platdata;
+ struct meson_uart *const uart = plat->reg;
+
+ meson_serial_init(uart);
+
+ return 0;
+}
+
+static int meson_serial_getc(struct udevice *dev)
+{
+ struct meson_serial_platdata *plat = dev->platdata;
+ struct meson_uart *const uart = plat->reg;
+
+ if (readl(&uart->status) & AML_UART_RX_EMPTY)
+ return -EAGAIN;
+
+ return readl(&uart->rfifo) & 0xff;
+}
+
+static int meson_serial_putc(struct udevice *dev, const char ch)
+{
+ struct meson_serial_platdata *plat = dev->platdata;
+ struct meson_uart *const uart = plat->reg;
+
+ if (readl(&uart->status) & AML_UART_TX_FULL)
+ return -EAGAIN;
+
+ writel(ch, &uart->wfifo);
+
+ return 0;
+}
+
+static int meson_serial_pending(struct udevice *dev, bool input)
+{
+ struct meson_serial_platdata *plat = dev->platdata;
+ struct meson_uart *const uart = plat->reg;
+ uint32_t status = readl(&uart->status);
+
+ if (input)
+ return !(status & AML_UART_RX_EMPTY);
+ else
+ return !(status & AML_UART_TX_FULL);
+}
+
+static int meson_serial_ofdata_to_platdata(struct udevice *dev)
+{
+ struct meson_serial_platdata *plat = dev->platdata;
+ fdt_addr_t addr;
+
+ addr = dev_get_addr(dev);
+ if (addr == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ plat->reg = (struct meson_uart *)addr;
+
+ return 0;
+}
+
+static const struct dm_serial_ops meson_serial_ops = {
+ .putc = meson_serial_putc,
+ .pending = meson_serial_pending,
+ .getc = meson_serial_getc,
+};
+
+static const struct udevice_id meson_serial_ids[] = {
+ { .compatible = "amlogic,meson-uart" },
+ { }
+};
+
+U_BOOT_DRIVER(serial_meson) = {
+ .name = "serial_meson",
+ .id = UCLASS_SERIAL,
+ .of_match = meson_serial_ids,
+ .probe = meson_serial_probe,
+ .ops = &meson_serial_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+ .ofdata_to_platdata = meson_serial_ofdata_to_platdata,
+ .platdata_auto_alloc_size = sizeof(struct meson_serial_platdata),
+};
+
+#ifdef CONFIG_DEBUG_UART_MESON
+
+#include <debug_uart.h>
+
+static inline void _debug_uart_init(void)
+{
+}
+
+static inline void _debug_uart_putc(int ch)
+{
+ struct meson_uart *regs = (struct meson_uart *)CONFIG_DEBUG_UART_BASE;
+
+ while (readl(&regs->status) & AML_UART_TX_FULL)
+ ;
+
+ writel(ch, &regs->wfifo);
+}
+
+DEBUG_UART_FUNCS
+
+#endif
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
index 0cd7302..2964bae 100644
--- a/drivers/usb/dwc3/Makefile
+++ b/drivers/usb/dwc3/Makefile
@@ -6,7 +6,7 @@ obj-$(CONFIG_USB_DWC3) += dwc3.o
dwc3-y := core.o
-dwc3-y += gadget.o ep0.o
+obj-$(CONFIG_USB_DWC3_GADGET) += gadget.o ep0.o
obj-$(CONFIG_USB_DWC3_OMAP) += dwc3-omap.o
obj-$(CONFIG_USB_DWC3_PHY_OMAP) += ti_usb_phy.o