summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorStefano Babic <sbabic@denx.de>2014-09-22 15:51:01 +0200
committerStefano Babic <sbabic@denx.de>2014-09-22 15:51:01 +0200
commit42817eb85de1d7dec399c75dbd133ea6b5351a72 (patch)
treecf93368fd5642cc995055f764103f85d7abbedf1 /drivers
parent7a56bddd7fb9fe27c775cadd18ebde6f883d7cff (diff)
parent2a8c9c86b92a9ccee3c27286de317e19bb0530b3 (diff)
downloadblackbird-obmc-uboot-42817eb85de1d7dec399c75dbd133ea6b5351a72.tar.gz
blackbird-obmc-uboot-42817eb85de1d7dec399c75dbd133ea6b5351a72.zip
Merge branch 'master' of git://git.denx.de/u-boot-arm
Diffstat (limited to 'drivers')
-rw-r--r--drivers/core/lists.c10
-rw-r--r--drivers/core/root.c2
-rw-r--r--drivers/ddr/fsl/arm_ddr_gen3.c2
-rw-r--r--drivers/ddr/fsl/ctrl_regs.c8
-rw-r--r--drivers/ddr/fsl/interactive.c2
-rw-r--r--drivers/gpio/tegra_gpio.c327
-rw-r--r--drivers/i2c/mxc_i2c.c4
-rw-r--r--drivers/mmc/fsl_esdhc.c4
-rw-r--r--drivers/mtd/mtdconcat.c1
-rw-r--r--drivers/mtd/mtdcore.c5
-rw-r--r--drivers/mtd/mtdpart.c1
-rw-r--r--drivers/mtd/nand/atmel_nand.c22
-rw-r--r--drivers/mtd/nand/atmel_nand_ecc.h3
-rw-r--r--drivers/mtd/nand/davinci_nand.c1
-rw-r--r--drivers/mtd/nand/nand_base.c1
-rw-r--r--drivers/mtd/nand/nand_bbt.c1
-rw-r--r--drivers/mtd/nand/nand_ids.c1
-rw-r--r--drivers/mtd/ubi/attach.c1
-rw-r--r--drivers/mtd/ubi/build.c1
-rw-r--r--drivers/mtd/ubi/crc32.c1
-rw-r--r--drivers/mtd/ubi/debug.c1
-rw-r--r--drivers/mtd/ubi/debug.h1
-rw-r--r--drivers/mtd/ubi/eba.c1
-rw-r--r--drivers/mtd/ubi/fastmap.c1
-rw-r--r--drivers/mtd/ubi/io.c1
-rw-r--r--drivers/mtd/ubi/kapi.c1
-rw-r--r--drivers/mtd/ubi/ubi.h1
-rw-r--r--drivers/mtd/ubi/upd.c1
-rw-r--r--drivers/mtd/ubi/vmt.c1
-rw-r--r--drivers/mtd/ubi/vtbl.c1
-rw-r--r--drivers/mtd/ubi/wl.c1
-rw-r--r--drivers/net/ethoc.c8
-rw-r--r--drivers/net/fm/dtsec.c1
-rw-r--r--drivers/net/fm/fm.h2
-rw-r--r--drivers/net/fm/init.c1
-rw-r--r--drivers/net/fm/memac.c1
-rw-r--r--drivers/net/fm/tgec.c1
-rw-r--r--drivers/net/fsl_mdio.c10
-rw-r--r--drivers/net/rtl8169.c3
-rw-r--r--drivers/net/tsec.c7
-rw-r--r--drivers/qe/uec.h1
-rw-r--r--drivers/serial/Makefile7
-rw-r--r--drivers/serial/ns16550.c203
-rw-r--r--drivers/serial/sandbox.c140
-rw-r--r--drivers/serial/serial-uclass.c213
-rw-r--r--drivers/serial/serial.c1
-rw-r--r--drivers/serial/serial_lpuart.c118
-rw-r--r--drivers/serial/serial_ns16550.c14
-rw-r--r--drivers/serial/serial_tegra.c38
-rw-r--r--drivers/usb/eth/smsc95xx.c1
-rw-r--r--drivers/usb/host/ehci-atmel.c8
-rw-r--r--drivers/usb/host/ohci-at91.c8
-rw-r--r--drivers/usb/musb-new/am35x.c1
-rw-r--r--drivers/usb/musb-new/musb_core.c1
-rw-r--r--drivers/usb/musb-new/musb_dsps.c1
-rw-r--r--drivers/usb/musb-new/musb_gadget.c1
-rw-r--r--drivers/usb/musb-new/musb_gadget_ep0.c1
-rw-r--r--drivers/usb/musb-new/musb_host.c1
-rw-r--r--drivers/usb/musb-new/musb_uboot.c1
-rw-r--r--drivers/usb/musb-new/omap2430.c1
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/fsl_dcu_fb.c365
-rw-r--r--drivers/watchdog/Makefile2
63 files changed, 1390 insertions, 181 deletions
diff --git a/drivers/core/lists.c b/drivers/core/lists.c
index 0f08bfd6ff..699f94b435 100644
--- a/drivers/core/lists.c
+++ b/drivers/core/lists.c
@@ -118,7 +118,8 @@ static int driver_check_compatible(const void *blob, int offset,
return -ENOENT;
}
-int lists_bind_fdt(struct udevice *parent, const void *blob, int offset)
+int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
+ struct udevice **devp)
{
struct driver *driver = ll_entry_start(struct driver, driver);
const int n_ents = ll_entry_count(struct driver, driver);
@@ -130,6 +131,8 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset)
int ret = 0;
dm_dbg("bind node %s\n", fdt_get_name(blob, offset, NULL));
+ if (devp)
+ *devp = NULL;
for (entry = driver; entry != driver + n_ents; entry++) {
ret = driver_check_compatible(blob, offset, entry->of_match);
name = fdt_get_name(blob, offset, NULL);
@@ -149,10 +152,11 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset)
ret = device_bind(parent, entry, name, NULL, offset, &dev);
if (ret) {
dm_warn("Error binding driver '%s'\n", entry->name);
- if (!result || ret != -ENOENT)
- result = ret;
+ return ret;
} else {
found = true;
+ if (devp)
+ *devp = dev;
}
break;
}
diff --git a/drivers/core/root.c b/drivers/core/root.c
index 393dd98b9d..a328a4876f 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -91,7 +91,7 @@ int dm_scan_fdt_node(struct udevice *parent, const void *blob, int offset,
if (pre_reloc_only &&
!fdt_getprop(blob, offset, "u-boot,dm-pre-reloc", NULL))
continue;
- err = lists_bind_fdt(parent, blob, offset);
+ err = lists_bind_fdt(parent, blob, offset, NULL);
if (err && !ret)
ret = err;
}
diff --git a/drivers/ddr/fsl/arm_ddr_gen3.c b/drivers/ddr/fsl/arm_ddr_gen3.c
index d4ed9aec2a..59f2fd6610 100644
--- a/drivers/ddr/fsl/arm_ddr_gen3.c
+++ b/drivers/ddr/fsl/arm_ddr_gen3.c
@@ -194,7 +194,7 @@ step2:
* For example, 2GB on 666MT/s 64-bit bus takes about 402ms
* Let's wait for 800ms
*/
- bus_width = 3 - ((ddr->sdram_cfg & SDRAM_CFG_DBW_MASK)
+ bus_width = 3 - ((ddr_in32(&ddr->sdram_cfg) & SDRAM_CFG_DBW_MASK)
>> SDRAM_CFG_DBW_SHIFT);
timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 /
(get_ddr_freq(0) >> 20)) << 1;
diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c
index 04e4178b15..d9cac2296a 100644
--- a/drivers/ddr/fsl/ctrl_regs.c
+++ b/drivers/ddr/fsl/ctrl_regs.c
@@ -693,6 +693,7 @@ static void set_ddr_sdram_cfg(fsl_ddr_cfg_regs_t *ddr,
unsigned int x32_en = 0; /* x32 enable */
unsigned int pchb8 = 0; /* precharge bit 8 enable */
unsigned int hse; /* Global half strength override */
+ unsigned int acc_ecc_en = 0; /* Accumulated ECC enable */
unsigned int mem_halt = 0; /* memory controller halt */
unsigned int bi = 0; /* Bypass initialization */
@@ -736,6 +737,9 @@ static void set_ddr_sdram_cfg(fsl_ddr_cfg_regs_t *ddr,
ba_intlv_ctl = popts->ba_intlv_ctl;
hse = popts->half_strength_driver_enable;
+ /* set when ddr bus width < 64 */
+ acc_ecc_en = (dbw != 0 && ecc_en == 1) ? 1 : 0;
+
ddr->ddr_sdram_cfg = (0
| ((mem_en & 0x1) << 31)
| ((sren & 0x1) << 30)
@@ -752,6 +756,7 @@ static void set_ddr_sdram_cfg(fsl_ddr_cfg_regs_t *ddr,
| ((x32_en & 0x1) << 5)
| ((pchb8 & 0x1) << 4)
| ((hse & 0x1) << 3)
+ | ((acc_ecc_en & 0x1) << 2)
| ((mem_halt & 0x1) << 1)
| ((bi & 0x1) << 0)
);
@@ -2271,6 +2276,9 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,
if (ip_rev > 0x40400)
unq_mrs_en = 1;
+ if (ip_rev > 0x40700)
+ ddr->debug[18] = popts->cswl_override;
+
set_ddr_sdram_cfg_2(ddr, popts, unq_mrs_en);
set_ddr_sdram_mode(ddr, popts, common_dimm,
cas_latency, additive_latency, unq_mrs_en);
diff --git a/drivers/ddr/fsl/interactive.c b/drivers/ddr/fsl/interactive.c
index 7fb418744e..6aa16b23dd 100644
--- a/drivers/ddr/fsl/interactive.c
+++ b/drivers/ddr/fsl/interactive.c
@@ -511,6 +511,7 @@ static void fsl_ddr_options_edit(fsl_ddr_info_t *pinfo,
CTRL_OPTIONS(wrlvl_override),
CTRL_OPTIONS(wrlvl_sample),
CTRL_OPTIONS(wrlvl_start),
+ CTRL_OPTIONS(cswl_override),
CTRL_OPTIONS(rcw_override),
CTRL_OPTIONS(rcw_1),
CTRL_OPTIONS(rcw_2),
@@ -801,6 +802,7 @@ static void print_memctl_options(const memctl_options_t *popts)
CTRL_OPTIONS(wrlvl_override),
CTRL_OPTIONS(wrlvl_sample),
CTRL_OPTIONS(wrlvl_start),
+ CTRL_OPTIONS_HEX(cswl_override),
CTRL_OPTIONS(rcw_override),
CTRL_OPTIONS(rcw_1),
CTRL_OPTIONS(rcw_2),
diff --git a/drivers/gpio/tegra_gpio.c b/drivers/gpio/tegra_gpio.c
index fea9d17f8e..1cc4abb8a9 100644
--- a/drivers/gpio/tegra_gpio.c
+++ b/drivers/gpio/tegra_gpio.c
@@ -12,10 +12,17 @@
*/
#include <common.h>
+#include <dm.h>
+#include <malloc.h>
+#include <errno.h>
+#include <fdtdec.h>
#include <asm/io.h>
#include <asm/bitops.h>
#include <asm/arch/tegra.h>
#include <asm/gpio.h>
+#include <dm/device-internal.h>
+
+DECLARE_GLOBAL_DATA_PTR;
enum {
TEGRA_CMD_INFO,
@@ -24,14 +31,18 @@ enum {
TEGRA_CMD_INPUT,
};
-static struct gpio_names {
- char name[GPIO_NAME_SIZE];
-} gpio_names[MAX_NUM_GPIOS];
+struct tegra_gpio_platdata {
+ struct gpio_ctlr_bank *bank;
+ const char *port_name; /* Name of port, e.g. "B" */
+ int base_gpio; /* Port number for this port (0, 1,.., n-1) */
+};
-static char *get_name(int i)
-{
- return *gpio_names[i].name ? gpio_names[i].name : "UNKNOWN";
-}
+/* Information about each port at run-time */
+struct tegra_port_info {
+ char label[TEGRA_GPIOS_PER_PORT][GPIO_NAME_SIZE];
+ struct gpio_ctlr_bank *bank;
+ int base_gpio; /* Port number for this port (0, 1,.., n-1) */
+};
/* Return config of pin 'gpio' as GPIO (1) or SFPIO (0) */
static int get_config(unsigned gpio)
@@ -121,38 +132,72 @@ static void set_level(unsigned gpio, int high)
writel(u, &bank->gpio_out[GPIO_PORT(gpio)]);
}
+static int check_reserved(struct udevice *dev, unsigned offset,
+ const char *func)
+{
+ struct tegra_port_info *state = dev_get_priv(dev);
+ struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+
+ if (!*state->label[offset]) {
+ printf("tegra_gpio: %s: error: gpio %s%d not reserved\n",
+ func, uc_priv->bank_name, offset);
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+/* set GPIO pin 'gpio' as an output, with polarity 'value' */
+int tegra_spl_gpio_direction_output(int gpio, int value)
+{
+ /* Configure as a GPIO */
+ set_config(gpio, 1);
+
+ /* Configure GPIO output value. */
+ set_level(gpio, value);
+
+ /* Configure GPIO direction as output. */
+ set_direction(gpio, 1);
+
+ return 0;
+}
+
/*
* Generic_GPIO primitives.
*/
-int gpio_request(unsigned gpio, const char *label)
+static int tegra_gpio_request(struct udevice *dev, unsigned offset,
+ const char *label)
{
- if (gpio >= MAX_NUM_GPIOS)
- return -1;
+ struct tegra_port_info *state = dev_get_priv(dev);
- if (label != NULL) {
- strncpy(gpio_names[gpio].name, label, GPIO_NAME_SIZE);
- gpio_names[gpio].name[GPIO_NAME_SIZE - 1] = '\0';
- }
+ if (*state->label[offset])
+ return -EBUSY;
+
+ strncpy(state->label[offset], label, GPIO_NAME_SIZE);
+ state->label[offset][GPIO_NAME_SIZE - 1] = '\0';
/* Configure as a GPIO */
- set_config(gpio, 1);
+ set_config(state->base_gpio + offset, 1);
return 0;
}
-int gpio_free(unsigned gpio)
+static int tegra_gpio_free(struct udevice *dev, unsigned offset)
{
- if (gpio >= MAX_NUM_GPIOS)
- return -1;
+ struct tegra_port_info *state = dev_get_priv(dev);
+ int ret;
+
+ ret = check_reserved(dev, offset, __func__);
+ if (ret)
+ return ret;
+ state->label[offset][0] = '\0';
- gpio_names[gpio].name[0] = '\0';
- /* Do not configure as input or change pin mux here */
return 0;
}
/* read GPIO OUT value of pin 'gpio' */
-static int gpio_get_output_value(unsigned gpio)
+static int tegra_gpio_get_output_value(unsigned gpio)
{
struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)];
@@ -166,24 +211,34 @@ static int gpio_get_output_value(unsigned gpio)
return (val >> GPIO_BIT(gpio)) & 1;
}
+
/* set GPIO pin 'gpio' as an input */
-int gpio_direction_input(unsigned gpio)
+static int tegra_gpio_direction_input(struct udevice *dev, unsigned offset)
{
- debug("gpio_direction_input: pin = %d (port %d:bit %d)\n",
- gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio));
+ struct tegra_port_info *state = dev_get_priv(dev);
+ int ret;
+
+ ret = check_reserved(dev, offset, __func__);
+ if (ret)
+ return ret;
/* Configure GPIO direction as input. */
- set_direction(gpio, 0);
+ set_direction(state->base_gpio + offset, 0);
return 0;
}
/* set GPIO pin 'gpio' as an output, with polarity 'value' */
-int gpio_direction_output(unsigned gpio, int value)
+static int tegra_gpio_direction_output(struct udevice *dev, unsigned offset,
+ int value)
{
- debug("gpio_direction_output: pin = %d (port %d:bit %d) = %s\n",
- gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio),
- value ? "HIGH" : "LOW");
+ struct tegra_port_info *state = dev_get_priv(dev);
+ int gpio = state->base_gpio + offset;
+ int ret;
+
+ ret = check_reserved(dev, offset, __func__);
+ if (ret)
+ return ret;
/* Configure GPIO output value. */
set_level(gpio, value);
@@ -195,25 +250,38 @@ int gpio_direction_output(unsigned gpio, int value)
}
/* read GPIO IN value of pin 'gpio' */
-int gpio_get_value(unsigned gpio)
+static int tegra_gpio_get_value(struct udevice *dev, unsigned offset)
{
- struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
- struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)];
+ struct tegra_port_info *state = dev_get_priv(dev);
+ int gpio = state->base_gpio + offset;
+ int ret;
int val;
- debug("gpio_get_value: pin = %d (port %d:bit %d)\n",
- gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio));
+ ret = check_reserved(dev, offset, __func__);
+ if (ret)
+ return ret;
+
+ debug("%s: pin = %d (port %d:bit %d)\n", __func__,
+ gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio));
- val = readl(&bank->gpio_in[GPIO_PORT(gpio)]);
+ val = readl(&state->bank->gpio_in[GPIO_PORT(gpio)]);
return (val >> GPIO_BIT(gpio)) & 1;
}
/* write GPIO OUT value to pin 'gpio' */
-int gpio_set_value(unsigned gpio, int value)
+static int tegra_gpio_set_value(struct udevice *dev, unsigned offset, int value)
{
+ struct tegra_port_info *state = dev_get_priv(dev);
+ int gpio = state->base_gpio + offset;
+ int ret;
+
+ ret = check_reserved(dev, offset, __func__);
+ if (ret)
+ return ret;
+
debug("gpio_set_value: pin = %d (port %d:bit %d), value = %d\n",
- gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio), value);
+ gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio), value);
/* Configure GPIO output value. */
set_level(gpio, value);
@@ -241,26 +309,175 @@ void gpio_config_table(const struct tegra_gpio_config *config, int len)
}
}
-/*
- * Display Tegra GPIO information
+static int tegra_gpio_get_function(struct udevice *dev, unsigned offset)
+{
+ struct tegra_port_info *state = dev_get_priv(dev);
+ int gpio = state->base_gpio + offset;
+
+ if (!*state->label[offset])
+ return GPIOF_UNUSED;
+ if (!get_config(gpio))
+ return GPIOF_FUNC;
+ else if (get_direction(gpio))
+ return GPIOF_OUTPUT;
+ else
+ return GPIOF_INPUT;
+}
+
+static int tegra_gpio_get_state(struct udevice *dev, unsigned int offset,
+ char *buf, int bufsize)
+{
+ struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+ struct tegra_port_info *state = dev_get_priv(dev);
+ int gpio = state->base_gpio + offset;
+ const char *label;
+ int is_output;
+ int is_gpio;
+ int size;
+
+ label = state->label[offset];
+ is_gpio = get_config(gpio); /* GPIO, not SFPIO */
+ size = snprintf(buf, bufsize, "%s%d: ",
+ uc_priv->bank_name ? uc_priv->bank_name : "", offset);
+ buf += size;
+ bufsize -= size;
+ if (is_gpio) {
+ is_output = get_direction(gpio);
+
+ snprintf(buf, bufsize, "%s: %d [%c]%s%s",
+ is_output ? "out" : " in",
+ is_output ?
+ tegra_gpio_get_output_value(gpio) :
+ tegra_gpio_get_value(dev, offset),
+ *label ? 'x' : ' ',
+ *label ? " " : "",
+ label);
+ } else {
+ snprintf(buf, bufsize, "sfpio");
+ }
+
+ return 0;
+}
+
+static const struct dm_gpio_ops gpio_tegra_ops = {
+ .request = tegra_gpio_request,
+ .free = tegra_gpio_free,
+ .direction_input = tegra_gpio_direction_input,
+ .direction_output = tegra_gpio_direction_output,
+ .get_value = tegra_gpio_get_value,
+ .set_value = tegra_gpio_set_value,
+ .get_function = tegra_gpio_get_function,
+ .get_state = tegra_gpio_get_state,
+};
+
+/**
+ * Returns the name of a GPIO port
+ *
+ * GPIOs are named A, B, C, ..., Z, AA, BB, CC, ...
+ *
+ * @base_port: Base port number (0, 1..n-1)
+ * @return allocated string containing the name
*/
-void gpio_info(void)
+static char *gpio_port_name(int base_port)
{
- unsigned c;
- int type;
+ char *name, *s;
+
+ name = malloc(3);
+ if (name) {
+ s = name;
+ *s++ = 'A' + (base_port % 26);
+ if (base_port >= 26)
+ *s++ = *name;
+ *s = '\0';
+ }
- for (c = 0; c < MAX_NUM_GPIOS; c++) {
- type = get_config(c); /* GPIO, not SFPIO */
- if (type) {
- printf("GPIO_%d:\t%s is an %s, ", c,
- get_name(c),
- get_direction(c) ? "OUTPUT" : "INPUT");
- if (get_direction(c))
- printf("value = %d", gpio_get_output_value(c));
- else
- printf("value = %d", gpio_get_value(c));
- printf("\n");
- } else
- continue;
+ return name;
+}
+
+static const struct udevice_id tegra_gpio_ids[] = {
+ { .compatible = "nvidia,tegra30-gpio" },
+ { .compatible = "nvidia,tegra20-gpio" },
+ { }
+};
+
+static int gpio_tegra_probe(struct udevice *dev)
+{
+ struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+ struct tegra_port_info *priv = dev->priv;
+ struct tegra_gpio_platdata *plat = dev->platdata;
+
+ /* Only child devices have ports */
+ if (!plat)
+ return 0;
+
+ priv->bank = plat->bank;
+ priv->base_gpio = plat->base_gpio;
+
+ uc_priv->gpio_count = TEGRA_GPIOS_PER_PORT;
+ uc_priv->bank_name = plat->port_name;
+
+ return 0;
+}
+
+/**
+ * We have a top-level GPIO device with no actual GPIOs. It has a child
+ * device for each Tegra port.
+ */
+static int gpio_tegra_bind(struct udevice *parent)
+{
+ struct tegra_gpio_platdata *plat = parent->platdata;
+ struct gpio_ctlr *ctlr;
+ int bank_count;
+ int bank;
+ int ret;
+ int len;
+
+ /* If this is a child device, there is nothing to do here */
+ if (plat)
+ return 0;
+
+ /*
+ * This driver does not make use of interrupts, other than to figure
+ * out the number of GPIO banks
+ */
+ if (!fdt_getprop(gd->fdt_blob, parent->of_offset, "interrupts", &len))
+ return -EINVAL;
+ bank_count = len / 3 / sizeof(u32);
+ ctlr = (struct gpio_ctlr *)fdtdec_get_addr(gd->fdt_blob,
+ parent->of_offset, "reg");
+ for (bank = 0; bank < bank_count; bank++) {
+ int port;
+
+ for (port = 0; port < TEGRA_PORTS_PER_BANK; port++) {
+ struct tegra_gpio_platdata *plat;
+ struct udevice *dev;
+ int base_port;
+
+ plat = calloc(1, sizeof(*plat));
+ if (!plat)
+ return -ENOMEM;
+ plat->bank = &ctlr->gpio_bank[bank];
+ base_port = bank * TEGRA_PORTS_PER_BANK + port;
+ plat->base_gpio = TEGRA_GPIOS_PER_PORT * base_port;
+ plat->port_name = gpio_port_name(base_port);
+
+ ret = device_bind(parent, parent->driver,
+ plat->port_name, plat, -1, &dev);
+ if (ret)
+ return ret;
+ dev->of_offset = parent->of_offset;
+ }
}
+
+ return 0;
}
+
+U_BOOT_DRIVER(gpio_tegra) = {
+ .name = "gpio_tegra",
+ .id = UCLASS_GPIO,
+ .of_match = tegra_gpio_ids,
+ .bind = gpio_tegra_bind,
+ .probe = gpio_tegra_probe,
+ .priv_auto_alloc_size = sizeof(struct tegra_port_info),
+ .ops = &gpio_tegra_ops,
+};
diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index c14797ce0e..021b2fe511 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -423,7 +423,7 @@ static void * const i2c_bases[] = {
(void *)IMX_I2C2_BASE
#elif defined(CONFIG_MX31) || defined(CONFIG_MX35) || \
defined(CONFIG_MX51) || defined(CONFIG_MX53) || \
- defined(CONFIG_MX6)
+ defined(CONFIG_MX6) || defined(CONFIG_LS102XA)
(void *)I2C1_BASE_ADDR,
(void *)I2C2_BASE_ADDR,
(void *)I2C3_BASE_ADDR
@@ -545,7 +545,7 @@ U_BOOT_I2C_ADAP_COMPLETE(mxc1, mxc_i2c_init, mxc_i2c_probe,
CONFIG_SYS_MXC_I2C2_SLAVE, 1)
#if defined(CONFIG_MX31) || defined(CONFIG_MX35) ||\
defined(CONFIG_MX51) || defined(CONFIG_MX53) ||\
- defined(CONFIG_MX6)
+ defined(CONFIG_MX6) || defined(CONFIG_LS102XA)
U_BOOT_I2C_ADAP_COMPLETE(mxc2, mxc_i2c_init, mxc_i2c_probe,
mxc_i2c_read, mxc_i2c_write,
mxc_i2c_set_bus_speed,
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index 55416136ab..97d0389d9d 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -96,7 +96,7 @@ static uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data)
else if (cmd->resp_type & MMC_RSP_PRESENT)
xfertyp |= XFERTYP_RSPTYP_48;
-#if defined(CONFIG_MX53) || defined(CONFIG_PPC_T4240)
+#if defined(CONFIG_MX53) || defined(CONFIG_PPC_T4240) || defined(CONFIG_LS102XA)
if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
xfertyp |= XFERTYP_CMDTYP_ABORT;
#endif
@@ -561,7 +561,7 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
memset(&cfg->cfg, 0, sizeof(cfg->cfg));
voltage_caps = 0;
- caps = regs->hostcapblt;
+ caps = esdhc_read32(&regs->hostcapblt);
#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC135
caps = caps & ~(ESDHC_HOSTCAPBLT_SRS |
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index 39daeabd9f..3e36918f1c 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -10,7 +10,6 @@
*
*/
-#define __UBOOT__
#ifndef __UBOOT__
#include <linux/kernel.h>
#include <linux/module.h>
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 6ad03575f6..cb27ff22be 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -9,7 +9,6 @@
*
*/
-#define __UBOOT__
#ifndef __UBOOT__
#include <linux/module.h>
#include <linux/kernel.h>
@@ -804,7 +803,7 @@ void mtd_get_len_incl_bad(struct mtd_info *mtd, uint64_t offset,
*truncated = 0;
*len_incl_bad = 0;
- if (!mtd->block_isbad) {
+ if (!mtd->_block_isbad) {
*len_incl_bad = length;
return;
}
@@ -820,7 +819,7 @@ void mtd_get_len_incl_bad(struct mtd_info *mtd, uint64_t offset,
block_len = mtd->erasesize - (offset & (mtd->erasesize - 1));
- if (!mtd->block_isbad(mtd, offset & ~(mtd->erasesize - 1)))
+ if (!mtd->_block_isbad(mtd, offset & ~(mtd->erasesize - 1)))
len_excl_bad += block_len;
*len_incl_bad += block_len;
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 2f20b92a88..cfbaa3d9a0 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -9,7 +9,6 @@
*
*/
-#define __UBOOT__
#ifndef __UBOOT__
#include <linux/module.h>
#include <linux/types.h>
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index e73834d2ef..9114a86da2 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -164,7 +164,7 @@ static void pmecc_gen_syndrome(struct mtd_info *mtd, int sector)
/* Fill odd syndromes */
for (i = 0; i < host->pmecc_corr_cap; i++) {
- value = readl(&host->pmecc->rem_port[sector].rem[i / 2]);
+ value = pmecc_readl(host->pmecc, rem_port[sector].rem[i / 2]);
if (i & 1)
value >>= 16;
value &= 0xffff;
@@ -392,10 +392,11 @@ static int pmecc_err_location(struct mtd_info *mtd)
int16_t *smu = host->pmecc_smu;
int timeout = PMECC_MAX_TIMEOUT_US;
- writel(PMERRLOC_DISABLE, &host->pmerrloc->eldis);
+ pmecc_writel(host->pmerrloc, eldis, PMERRLOC_DISABLE);
for (i = 0; i <= host->pmecc_lmu[cap + 1] >> 1; i++) {
- writel(smu[(cap + 1) * num + i], &host->pmerrloc->sigma[i]);
+ pmecc_writel(host->pmerrloc, sigma[i],
+ smu[(cap + 1) * num + i]);
err_nbr++;
}
@@ -403,12 +404,12 @@ static int pmecc_err_location(struct mtd_info *mtd)
if (sector_size == 1024)
val |= PMERRLOC_ELCFG_SECTOR_1024;
- writel(val, &host->pmerrloc->elcfg);
- writel(sector_size * 8 + host->pmecc_degree * cap,
- &host->pmerrloc->elen);
+ pmecc_writel(host->pmerrloc, elcfg, val);
+ pmecc_writel(host->pmerrloc, elen,
+ sector_size * 8 + host->pmecc_degree * cap);
while (--timeout) {
- if (readl(&host->pmerrloc->elisr) & PMERRLOC_CALC_DONE)
+ if (pmecc_readl(host->pmerrloc, elisr) & PMERRLOC_CALC_DONE)
break;
WATCHDOG_RESET();
udelay(1);
@@ -419,7 +420,7 @@ static int pmecc_err_location(struct mtd_info *mtd)
return -1;
}
- roots_nbr = (readl(&host->pmerrloc->elisr) & PMERRLOC_ERR_NUM_MASK)
+ roots_nbr = (pmecc_readl(host->pmerrloc, elisr) & PMERRLOC_ERR_NUM_MASK)
>> 8;
/* Number of roots == degree of smu hence <= cap */
if (roots_nbr == host->pmecc_lmu[cap + 1] >> 1)
@@ -443,7 +444,7 @@ static void pmecc_correct_data(struct mtd_info *mtd, uint8_t *buf, uint8_t *ecc,
sector_size = host->pmecc_sector_size;
while (err_nbr) {
- tmp = readl(&host->pmerrloc->el[i]) - 1;
+ tmp = pmecc_readl(host->pmerrloc, el[i]) - 1;
byte_pos = tmp / 8;
bit_pos = tmp % 8;
@@ -597,7 +598,7 @@ static int atmel_nand_pmecc_write_page(struct mtd_info *mtd,
pos = i * host->pmecc_bytes_per_sector + j;
chip->oob_poi[eccpos[pos]] =
- readb(&host->pmecc->ecc_port[i].ecc[j]);
+ pmecc_readb(host->pmecc, ecc_port[i].ecc[j]);
}
}
chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
@@ -881,6 +882,7 @@ static int atmel_pmecc_nand_init_params(struct nand_chip *nand,
return -ENOMEM;
}
+ nand->options |= NAND_NO_SUBPAGE_WRITE;
nand->ecc.read_page = atmel_nand_pmecc_read_page;
nand->ecc.write_page = atmel_nand_pmecc_write_page;
nand->ecc.strength = cap;
diff --git a/drivers/mtd/nand/atmel_nand_ecc.h b/drivers/mtd/nand/atmel_nand_ecc.h
index 55d7711c8b..92d4ec59fd 100644
--- a/drivers/mtd/nand/atmel_nand_ecc.h
+++ b/drivers/mtd/nand/atmel_nand_ecc.h
@@ -34,6 +34,9 @@
#define pmecc_readl(addr, reg) \
readl(&addr->reg)
+#define pmecc_readb(addr, reg) \
+ readb(&addr->reg)
+
#define pmecc_writel(addr, reg, value) \
writel((value), &addr->reg)
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
index 02a1130af9..41689b5165 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -363,6 +363,7 @@ static struct nand_ecclayout nand_keystone_rbl_4bit_layout_oobfirst = {
* @raw: use _raw version of write_page
*/
static int nand_davinci_write_page(struct mtd_info *mtd, struct nand_chip *chip,
+ uint32_t offset, int data_len,
const uint8_t *buf, int oob_required,
int page, int cached, int raw)
{
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 085b1541cd..7153e3ca36 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -29,7 +29,6 @@
*
*/
-#define __UBOOT__
#ifndef __UBOOT__
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index c8f28c792b..cf4a82d93a 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -59,7 +59,6 @@
*
*/
-#define __UBOOT__
#ifndef __UBOOT__
#include <linux/slab.h>
#include <linux/types.h>
diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c
index 54f9f13896..9ed05778d3 100644
--- a/drivers/mtd/nand/nand_ids.c
+++ b/drivers/mtd/nand/nand_ids.c
@@ -8,7 +8,6 @@
* published by the Free Software Foundation.
*
*/
-#define __UBOOT__
#ifndef __UBOOT__
#include <linux/module.h>
#include <linux/mtd/nand.h>
diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c
index 9fce02ef26..1bdbfa71d9 100644
--- a/drivers/mtd/ubi/attach.c
+++ b/drivers/mtd/ubi/attach.c
@@ -70,7 +70,6 @@
* o Otherwise this is corruption type 2.
*/
-#define __UBOOT__
#ifndef __UBOOT__
#include <linux/err.h>
#include <linux/slab.h>
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index ff8bf0cedf..584cf5f22b 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -17,7 +17,6 @@
* later using the "UBI control device".
*/
-#define __UBOOT__
#ifndef __UBOOT__
#include <linux/module.h>
#include <linux/moduleparam.h>
diff --git a/drivers/mtd/ubi/crc32.c b/drivers/mtd/ubi/crc32.c
index 0d65bf4b8a..9c54ea4db0 100644
--- a/drivers/mtd/ubi/crc32.c
+++ b/drivers/mtd/ubi/crc32.c
@@ -20,7 +20,6 @@
* Version 2. See the file COPYING for more details.
*/
-#define __UBOOT__
#ifndef __UBOOT__
#include <linux/crc32.h>
#include <linux/kernel.h>
diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c
index af254da488..6dcc4e4844 100644
--- a/drivers/mtd/ubi/debug.c
+++ b/drivers/mtd/ubi/debug.c
@@ -8,7 +8,6 @@
#include <ubi_uboot.h>
#include "ubi.h"
-#define __UBOOT__
#ifndef __UBOOT__
#include <linux/debugfs.h>
#include <linux/uaccess.h>
diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h
index 980eb11ed2..bfa9dfb42b 100644
--- a/drivers/mtd/ubi/debug.h
+++ b/drivers/mtd/ubi/debug.h
@@ -13,7 +13,6 @@ void ubi_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len);
void ubi_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr);
void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr);
-#define __UBOOT__
#ifndef __UBOOT__
#include <linux/random.h>
#endif
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c
index 3c2a7e69e1..fce0ff8bdf 100644
--- a/drivers/mtd/ubi/eba.c
+++ b/drivers/mtd/ubi/eba.c
@@ -29,7 +29,6 @@
* 64 bits is enough to never overflow.
*/
-#define __UBOOT__
#ifndef __UBOOT__
#include <linux/slab.h>
#include <linux/crc32.h>
diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
index 787522fa2e..a2166e431c 100644
--- a/drivers/mtd/ubi/fastmap.c
+++ b/drivers/mtd/ubi/fastmap.c
@@ -6,7 +6,6 @@
*
*/
-#define __UBOOT__
#ifndef __UBOOT__
#include <linux/crc32.h>
#else
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
index 41d7eb7638..0e2e9335fe 100644
--- a/drivers/mtd/ubi/io.c
+++ b/drivers/mtd/ubi/io.c
@@ -73,7 +73,6 @@
* back and writes the whole sub-page.
*/
-#define __UBOOT__
#ifndef __UBOOT__
#include <linux/crc32.h>
#include <linux/err.h>
diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c
index 0183c93b0b..fd2bbd64f1 100644
--- a/drivers/mtd/ubi/kapi.c
+++ b/drivers/mtd/ubi/kapi.c
@@ -8,7 +8,6 @@
/* This file mostly implements UBI kernel API functions */
-#define __UBOOT__
#ifndef __UBOOT__
#include <linux/module.h>
#include <linux/slab.h>
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index 20fd704eca..754b3371d2 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -10,7 +10,6 @@
#ifndef __UBI_UBI_H__
#define __UBI_UBI_H__
-#define __UBOOT__
#ifndef __UBOOT__
#include <linux/types.h>
#include <linux/list.h>
diff --git a/drivers/mtd/ubi/upd.c b/drivers/mtd/ubi/upd.c
index 220c120515..c52c9ce776 100644
--- a/drivers/mtd/ubi/upd.c
+++ b/drivers/mtd/ubi/upd.c
@@ -26,7 +26,6 @@
* transaction with a roll-back capability.
*/
-#define __UBOOT__
#ifndef __UBOOT__
#include <linux/uaccess.h>
#else
diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c
index d9665a446a..f4392f5969 100644
--- a/drivers/mtd/ubi/vmt.c
+++ b/drivers/mtd/ubi/vmt.c
@@ -11,7 +11,6 @@
* resizing.
*/
-#define __UBOOT__
#ifndef __UBOOT__
#include <linux/err.h>
#include <linux/slab.h>
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c
index e6c8f5bbe0..ae8ea38c62 100644
--- a/drivers/mtd/ubi/vtbl.c
+++ b/drivers/mtd/ubi/vtbl.c
@@ -43,7 +43,6 @@
* damaged.
*/
-#define __UBOOT__
#ifndef __UBOOT__
#include <linux/crc32.h>
#include <linux/err.h>
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index 102309016a..6886f89df2 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -86,7 +86,6 @@
* room for future re-works of the WL sub-system.
*/
-#define __UBOOT__
#ifndef __UBOOT__
#include <linux/slab.h>
#include <linux/crc32.h>
diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c
index af06d4fb82..46c82bbb40 100644
--- a/drivers/net/ethoc.c
+++ b/drivers/net/ethoc.c
@@ -189,12 +189,12 @@ struct ethoc_bd {
u32 addr;
};
-static inline u32 ethoc_read(struct eth_device *dev, loff_t offset)
+static inline u32 ethoc_read(struct eth_device *dev, size_t offset)
{
return readl(dev->iobase + offset);
}
-static inline void ethoc_write(struct eth_device *dev, loff_t offset, u32 data)
+static inline void ethoc_write(struct eth_device *dev, size_t offset, u32 data)
{
writel(data, dev->iobase + offset);
}
@@ -202,7 +202,7 @@ static inline void ethoc_write(struct eth_device *dev, loff_t offset, u32 data)
static inline void ethoc_read_bd(struct eth_device *dev, int index,
struct ethoc_bd *bd)
{
- loff_t offset = ETHOC_BD_BASE + (index * sizeof(struct ethoc_bd));
+ size_t offset = ETHOC_BD_BASE + (index * sizeof(struct ethoc_bd));
bd->stat = ethoc_read(dev, offset + 0);
bd->addr = ethoc_read(dev, offset + 4);
}
@@ -210,7 +210,7 @@ static inline void ethoc_read_bd(struct eth_device *dev, int index,
static inline void ethoc_write_bd(struct eth_device *dev, int index,
const struct ethoc_bd *bd)
{
- loff_t offset = ETHOC_BD_BASE + (index * sizeof(struct ethoc_bd));
+ size_t offset = ETHOC_BD_BASE + (index * sizeof(struct ethoc_bd));
ethoc_write(dev, offset + 0, bd->stat);
ethoc_write(dev, offset + 4, bd->addr);
}
diff --git a/drivers/net/fm/dtsec.c b/drivers/net/fm/dtsec.c
index 78bbd439f1..8d3dc0e308 100644
--- a/drivers/net/fm/dtsec.c
+++ b/drivers/net/fm/dtsec.c
@@ -7,7 +7,6 @@
#include <common.h>
#include <asm/types.h>
#include <asm/io.h>
-#include <asm/fsl_enet.h>
#include <asm/fsl_dtsec.h>
#include <fsl_mdio.h>
#include <phy.h>
diff --git a/drivers/net/fm/fm.h b/drivers/net/fm/fm.h
index 316e06e17e..a9691c635a 100644
--- a/drivers/net/fm/fm.h
+++ b/drivers/net/fm/fm.h
@@ -8,8 +8,8 @@
#define __FM_H__
#include <common.h>
+#include <phy.h>
#include <fm_eth.h>
-#include <asm/fsl_enet.h>
#include <asm/fsl_fman.h>
/* Port ID */
diff --git a/drivers/net/fm/init.c b/drivers/net/fm/init.c
index ff04695c32..6cf21c6f65 100644
--- a/drivers/net/fm/init.c
+++ b/drivers/net/fm/init.c
@@ -6,6 +6,7 @@
#include <common.h>
#include <asm/io.h>
#include <asm/fsl_serdes.h>
+#include <fsl_mdio.h>
#include "fm.h"
diff --git a/drivers/net/fm/memac.c b/drivers/net/fm/memac.c
index 592a67f2a5..9499290bba 100644
--- a/drivers/net/fm/memac.c
+++ b/drivers/net/fm/memac.c
@@ -12,7 +12,6 @@
#include <phy.h>
#include <asm/types.h>
#include <asm/io.h>
-#include <asm/fsl_enet.h>
#include <asm/fsl_memac.h>
#include "fm.h"
diff --git a/drivers/net/fm/tgec.c b/drivers/net/fm/tgec.c
index f450f800e2..50171230ea 100644
--- a/drivers/net/fm/tgec.c
+++ b/drivers/net/fm/tgec.c
@@ -12,7 +12,6 @@
#include <phy.h>
#include <asm/types.h>
#include <asm/io.h>
-#include <asm/fsl_enet.h>
#include <asm/fsl_tgec.h>
#include "fm.h"
diff --git a/drivers/net/fsl_mdio.c b/drivers/net/fsl_mdio.c
index 1d88e6504b..d6b181b386 100644
--- a/drivers/net/fsl_mdio.c
+++ b/drivers/net/fsl_mdio.c
@@ -11,7 +11,6 @@
#include <fsl_mdio.h>
#include <asm/io.h>
#include <asm/errno.h>
-#include <asm/fsl_enet.h>
void tsec_local_mdio_write(struct tsec_mii_mng __iomem *phyregs, int port_addr,
int dev_addr, int regnum, int value)
@@ -20,7 +19,8 @@ void tsec_local_mdio_write(struct tsec_mii_mng __iomem *phyregs, int port_addr,
out_be32(&phyregs->miimadd, (port_addr << 8) | (regnum & 0x1f));
out_be32(&phyregs->miimcon, value);
- asm("sync");
+ /* Memory barrier */
+ mb();
while ((in_be32(&phyregs->miimind) & MIIMIND_BUSY) && timeout--)
;
@@ -38,11 +38,13 @@ int tsec_local_mdio_read(struct tsec_mii_mng __iomem *phyregs, int port_addr,
/* Clear the command register, and wait */
out_be32(&phyregs->miimcom, 0);
- asm("sync");
+ /* Memory barrier */
+ mb();
/* Initiate a read command, and wait */
out_be32(&phyregs->miimcom, MIIMCOM_READ_CYCLE);
- asm("sync");
+ /* Memory barrier */
+ mb();
/* Wait for the the indication that the read is done */
while ((in_be32(&phyregs->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY))
diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c
index d040ab171b..c3ce17516c 100644
--- a/drivers/net/rtl8169.c
+++ b/drivers/net/rtl8169.c
@@ -469,7 +469,6 @@ static int rtl_recv(struct eth_device *dev)
rtl_inval_buffer(tpc->RxBufferRing[cur_rx], length);
memcpy(rxdata, tpc->RxBufferRing[cur_rx], length);
- NetReceive(rxdata, length);
if (cur_rx == NUM_RX_DESC - 1)
tpc->RxDescArray[cur_rx].status =
@@ -480,6 +479,8 @@ static int rtl_recv(struct eth_device *dev)
tpc->RxDescArray[cur_rx].buf_addr =
cpu_to_le32(bus_to_phys(tpc->RxBufferRing[cur_rx]));
rtl_flush_rx_desc(&tpc->RxDescArray[cur_rx]);
+
+ NetReceive(rxdata, length);
} else {
puts("Error Rx");
}
diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c
index e9138f0338..79d656133a 100644
--- a/drivers/net/tsec.c
+++ b/drivers/net/tsec.c
@@ -20,6 +20,7 @@
#include <fsl_mdio.h>
#include <asm/errno.h>
#include <asm/processor.h>
+#include <asm/io.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -270,6 +271,9 @@ void redundant_init(struct eth_device *dev)
out_be32(&regs->tstat, TSTAT_CLEAR_THALT);
out_be32(&regs->rstat, RSTAT_CLEAR_RHALT);
clrbits_be32(&regs->dmactrl, DMACTRL_GRS | DMACTRL_GTS);
+#ifdef CONFIG_LS102XA
+ setbits_be32(&regs->dmactrl, DMACTRL_LE);
+#endif
do {
uint16_t status;
@@ -366,6 +370,9 @@ static void startup_tsec(struct eth_device *dev)
out_be32(&regs->tstat, TSTAT_CLEAR_THALT);
out_be32(&regs->rstat, RSTAT_CLEAR_RHALT);
clrbits_be32(&regs->dmactrl, DMACTRL_GRS | DMACTRL_GTS);
+#ifdef CONFIG_LS102XA
+ setbits_be32(&regs->dmactrl, DMACTRL_LE);
+#endif
}
/* This returns the status bits of the device. The return value
diff --git a/drivers/qe/uec.h b/drivers/qe/uec.h
index 48a163411c..6b559f7974 100644
--- a/drivers/qe/uec.h
+++ b/drivers/qe/uec.h
@@ -13,7 +13,6 @@
#include "qe.h"
#include "uccf.h"
#include <phy.h>
-#include <asm/fsl_enet.h>
#define MAX_TX_THREADS 8
#define MAX_RX_THREADS 8
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 571c18fa93..853a8c6919 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -5,7 +5,12 @@
# SPDX-License-Identifier: GPL-2.0+
#
+ifdef CONFIG_DM_SERIAL
+obj-y += serial-uclass.o
+else
obj-y += serial.o
+obj-$(CONFIG_SYS_NS16550_SERIAL) += serial_ns16550.o
+endif
obj-$(CONFIG_ALTERA_UART) += altera_uart.o
obj-$(CONFIG_ALTERA_JTAG_UART) += altera_jtag_uart.o
@@ -16,7 +21,6 @@ obj-$(CONFIG_MCFUART) += mcfuart.o
obj-$(CONFIG_OPENCORES_YANU) += opencores_yanu.o
obj-$(CONFIG_SYS_NS16550) += ns16550.o
obj-$(CONFIG_S5P) += serial_s5p.o
-obj-$(CONFIG_SYS_NS16550_SERIAL) += serial_ns16550.o
obj-$(CONFIG_IMX_SERIAL) += serial_imx.o
obj-$(CONFIG_KS8695_SERIAL) += serial_ks8695.o
obj-$(CONFIG_MAX3100_SERIAL) += serial_max3100.o
@@ -34,6 +38,7 @@ obj-$(CONFIG_BFIN_SERIAL) += serial_bfin.o
obj-$(CONFIG_FSL_LPUART) += serial_lpuart.o
obj-$(CONFIG_MXS_AUART) += mxs_auart.o
obj-$(CONFIG_ARC_SERIAL) += serial_arc.o
+obj-$(CONFIG_TEGRA_SERIAL) += serial_tegra.o
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_USB_TTY) += usbtty.o
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index 079f67d380..63a9ef6844 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -4,18 +4,26 @@
* modified to use CONFIG_SYS_ISA_MEM and new defines
*/
-#include <config.h>
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <fdtdec.h>
#include <ns16550.h>
+#include <serial.h>
#include <watchdog.h>
#include <linux/types.h>
#include <asm/io.h>
+DECLARE_GLOBAL_DATA_PTR;
+
#define UART_LCRVAL UART_LCR_8N1 /* 8 data, 1 stop, no parity */
#define UART_MCRVAL (UART_MCR_DTR | \
UART_MCR_RTS) /* RTS/DTR */
#define UART_FCRVAL (UART_FCR_FIFO_EN | \
UART_FCR_RXSR | \
UART_FCR_TXSR) /* Clear & enable FIFOs */
+
+#ifndef CONFIG_DM_SERIAL
#ifdef CONFIG_SYS_NS16550_PORT_MAPPED
#define serial_out(x, y) outb(x, (ulong)y)
#define serial_in(y) inb((ulong)y)
@@ -29,6 +37,7 @@
#define serial_out(x, y) writeb(x, y)
#define serial_in(y) readb(y)
#endif
+#endif /* !CONFIG_DM_SERIAL */
#if defined(CONFIG_SOC_KEYSTONE)
#define UART_REG_VAL_PWREMU_MGMT_UART_DISABLE 0
@@ -45,6 +54,82 @@
#define CONFIG_SYS_NS16550_IER 0x00
#endif /* CONFIG_SYS_NS16550_IER */
+#ifdef CONFIG_DM_SERIAL
+static void ns16550_writeb(NS16550_t port, int offset, int value)
+{
+ struct ns16550_platdata *plat = port->plat;
+ unsigned char *addr;
+
+ offset *= 1 << plat->reg_shift;
+ addr = plat->base + offset;
+ /*
+ * As far as we know it doesn't make sense to support selection of
+ * these options at run-time, so use the existing CONFIG options.
+ */
+#ifdef CONFIG_SYS_NS16550_PORT_MAPPED
+ outb(value, addr);
+#elif defined(CONFIG_SYS_NS16550_MEM32) && !defined(CONFIG_SYS_BIG_ENDIAN)
+ out_le32(addr, value);
+#elif defined(CONFIG_SYS_NS16550_MEM32) && defined(CONFIG_SYS_BIG_ENDIAN)
+ out_be32(addr, value);
+#elif defined(CONFIG_SYS_BIG_ENDIAN)
+ writeb(value, addr + (1 << plat->reg_shift) - 1);
+#else
+ writeb(value, addr);
+#endif
+}
+
+static int ns16550_readb(NS16550_t port, int offset)
+{
+ struct ns16550_platdata *plat = port->plat;
+ unsigned char *addr;
+
+ offset *= 1 << plat->reg_shift;
+ addr = plat->base + offset;
+#ifdef CONFIG_SYS_NS16550_PORT_MAPPED
+ return inb(addr);
+#elif defined(CONFIG_SYS_NS16550_MEM32) && !defined(CONFIG_SYS_BIG_ENDIAN)
+ return in_le32(addr);
+#elif defined(CONFIG_SYS_NS16550_MEM32) && defined(CONFIG_SYS_BIG_ENDIAN)
+ return in_be32(addr);
+#elif defined(CONFIG_SYS_BIG_ENDIAN)
+ return readb(addr + (1 << plat->reg_shift) - 1);
+#else
+ return readb(addr);
+#endif
+}
+
+/* We can clean these up once everything is moved to driver model */
+#define serial_out(value, addr) \
+ ns16550_writeb(com_port, addr - (unsigned char *)com_port, value)
+#define serial_in(addr) \
+ ns16550_readb(com_port, addr - (unsigned char *)com_port)
+#endif
+
+int ns16550_calc_divisor(NS16550_t port, int clock, int baudrate)
+{
+ const unsigned int mode_x_div = 16;
+
+#ifdef CONFIG_OMAP1510
+ /* If can't cleanly clock 115200 set div to 1 */
+ if ((clock == 12000000) && (baudrate == 115200)) {
+ port->osc_12m_sel = OSC_12M_SEL; /* enable 6.5 * divisor */
+ return 1; /* return 1 for base divisor */
+ }
+ port->osc_12m_sel = 0; /* clear if previsouly set */
+#endif
+
+ return DIV_ROUND_CLOSEST(clock, mode_x_div * baudrate);
+}
+
+static void NS16550_setbrg(NS16550_t com_port, int baud_divisor)
+{
+ serial_out(UART_LCR_BKSE | UART_LCRVAL, &com_port->lcr);
+ serial_out(baud_divisor & 0xff, &com_port->dll);
+ serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm);
+ serial_out(UART_LCRVAL, &com_port->lcr);
+}
+
void NS16550_init(NS16550_t com_port, int baud_divisor)
{
#if (defined(CONFIG_SPL_BUILD) && defined(CONFIG_OMAP34XX))
@@ -55,10 +140,8 @@ void NS16550_init(NS16550_t com_port, int baud_divisor)
*/
if ((serial_in(&com_port->lsr) & (UART_LSR_TEMT | UART_LSR_THRE))
== UART_LSR_THRE) {
- serial_out(UART_LCR_DLAB, &com_port->lcr);
- serial_out(baud_divisor & 0xff, &com_port->dll);
- serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm);
- serial_out(UART_LCRVAL, &com_port->lcr);
+ if (baud_divisor != -1)
+ NS16550_setbrg(com_port, baud_divisor);
serial_out(0, &com_port->mdr1);
}
#endif
@@ -71,16 +154,11 @@ void NS16550_init(NS16550_t com_port, int baud_divisor)
defined(CONFIG_TI81XX) || defined(CONFIG_AM43XX)
serial_out(0x7, &com_port->mdr1); /* mode select reset TL16C750*/
#endif
- serial_out(UART_LCR_BKSE | UART_LCRVAL, &com_port->lcr);
- serial_out(0, &com_port->dll);
- serial_out(0, &com_port->dlm);
- serial_out(UART_LCRVAL, &com_port->lcr);
+ NS16550_setbrg(com_port, 0);
serial_out(UART_MCRVAL, &com_port->mcr);
serial_out(UART_FCRVAL, &com_port->fcr);
- serial_out(UART_LCR_BKSE | UART_LCRVAL, &com_port->lcr);
- serial_out(baud_divisor & 0xff, &com_port->dll);
- serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm);
- serial_out(UART_LCRVAL, &com_port->lcr);
+ if (baud_divisor != -1)
+ NS16550_setbrg(com_port, baud_divisor);
#if defined(CONFIG_OMAP) || \
defined(CONFIG_AM33XX) || defined(CONFIG_SOC_DA8XX) || \
defined(CONFIG_TI81XX) || defined(CONFIG_AM43XX)
@@ -97,16 +175,10 @@ void NS16550_init(NS16550_t com_port, int baud_divisor)
void NS16550_reinit(NS16550_t com_port, int baud_divisor)
{
serial_out(CONFIG_SYS_NS16550_IER, &com_port->ier);
- serial_out(UART_LCR_BKSE | UART_LCRVAL, &com_port->lcr);
- serial_out(0, &com_port->dll);
- serial_out(0, &com_port->dlm);
- serial_out(UART_LCRVAL, &com_port->lcr);
+ NS16550_setbrg(com_port, 0);
serial_out(UART_MCRVAL, &com_port->mcr);
serial_out(UART_FCRVAL, &com_port->fcr);
- serial_out(UART_LCR_BKSE, &com_port->lcr);
- serial_out(baud_divisor & 0xff, &com_port->dll);
- serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm);
- serial_out(UART_LCRVAL, &com_port->lcr);
+ NS16550_setbrg(com_port, baud_divisor);
}
#endif /* CONFIG_NS16550_MIN_FUNCTIONS */
@@ -145,3 +217,92 @@ int NS16550_tstc(NS16550_t com_port)
}
#endif /* CONFIG_NS16550_MIN_FUNCTIONS */
+
+#ifdef CONFIG_DM_SERIAL
+static int ns16550_serial_putc(struct udevice *dev, const char ch)
+{
+ struct NS16550 *const com_port = dev_get_priv(dev);
+
+ if (!(serial_in(&com_port->lsr) & UART_LSR_THRE))
+ return -EAGAIN;
+ serial_out(ch, &com_port->thr);
+
+ /*
+ * Call watchdog_reset() upon newline. This is done here in putc
+ * since the environment code uses a single puts() to print the complete
+ * environment upon "printenv". So we can't put this watchdog call
+ * in puts().
+ */
+ if (ch == '\n')
+ WATCHDOG_RESET();
+
+ return 0;
+}
+
+static int ns16550_serial_pending(struct udevice *dev, bool input)
+{
+ struct NS16550 *const com_port = dev_get_priv(dev);
+
+ if (input)
+ return serial_in(&com_port->lsr) & UART_LSR_DR ? 1 : 0;
+ else
+ return serial_in(&com_port->lsr) & UART_LSR_THRE ? 0 : 1;
+}
+
+static int ns16550_serial_getc(struct udevice *dev)
+{
+ struct NS16550 *const com_port = dev_get_priv(dev);
+
+ if (!serial_in(&com_port->lsr) & UART_LSR_DR)
+ return -EAGAIN;
+
+ return serial_in(&com_port->rbr);
+}
+
+static int ns16550_serial_setbrg(struct udevice *dev, int baudrate)
+{
+ struct NS16550 *const com_port = dev_get_priv(dev);
+ struct ns16550_platdata *plat = com_port->plat;
+ int clock_divisor;
+
+ clock_divisor = ns16550_calc_divisor(com_port, plat->clock, baudrate);
+
+ NS16550_setbrg(com_port, clock_divisor);
+
+ return 0;
+}
+
+int ns16550_serial_probe(struct udevice *dev)
+{
+ struct NS16550 *const com_port = dev_get_priv(dev);
+
+ NS16550_init(com_port, -1);
+
+ return 0;
+}
+
+int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
+{
+ struct NS16550 *const com_port = dev_get_priv(dev);
+ struct ns16550_platdata *plat = dev->platdata;
+ fdt_addr_t addr;
+
+ addr = fdtdec_get_addr(gd->fdt_blob, dev->of_offset, "reg");
+ if (addr == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ plat->base = (unsigned char *)addr;
+ plat->reg_shift = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+ "reg-shift", 1);
+ com_port->plat = plat;
+
+ return 0;
+}
+
+const struct dm_serial_ops ns16550_serial_ops = {
+ .putc = ns16550_serial_putc,
+ .pending = ns16550_serial_pending,
+ .getc = ns16550_serial_getc,
+ .setbrg = ns16550_serial_setbrg,
+};
+#endif /* CONFIG_DM_SERIAL */
diff --git a/drivers/serial/sandbox.c b/drivers/serial/sandbox.c
index 51fd871dff..cd2f91e28e 100644
--- a/drivers/serial/sandbox.c
+++ b/drivers/serial/sandbox.c
@@ -11,12 +11,16 @@
*/
#include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
#include <lcd.h>
#include <os.h>
#include <serial.h>
#include <linux/compiler.h>
#include <asm/state.h>
+DECLARE_GLOBAL_DATA_PTR;
+
/*
*
* serial_buf: A buffer that holds keyboard characters for the
@@ -30,27 +34,69 @@ static char serial_buf[16];
static unsigned int serial_buf_write;
static unsigned int serial_buf_read;
-static int sandbox_serial_init(void)
+struct sandbox_serial_platdata {
+ int colour; /* Text colour to use for output, -1 for none */
+};
+
+struct sandbox_serial_priv {
+ bool start_of_line;
+};
+
+/**
+ * output_ansi_colour() - Output an ANSI colour code
+ *
+ * @colour: Colour to output (0-7)
+ */
+static void output_ansi_colour(int colour)
+{
+ char ansi_code[] = "\x1b[1;3Xm";
+
+ ansi_code[5] = '0' + colour;
+ os_write(1, ansi_code, sizeof(ansi_code) - 1);
+}
+
+static void output_ansi_reset(void)
+{
+ os_write(1, "\x1b[0m", 4);
+}
+
+static int sandbox_serial_probe(struct udevice *dev)
{
struct sandbox_state *state = state_get_current();
+ struct sandbox_serial_priv *priv = dev_get_priv(dev);
if (state->term_raw != STATE_TERM_COOKED)
os_tty_raw(0, state->term_raw == STATE_TERM_RAW_WITH_SIGS);
+ priv->start_of_line = 0;
+
return 0;
}
-static void sandbox_serial_setbrg(void)
+static int sandbox_serial_remove(struct udevice *dev)
{
+ struct sandbox_serial_platdata *plat = dev->platdata;
+
+ if (plat->colour != -1)
+ output_ansi_reset();
+
+ return 0;
}
-static void sandbox_serial_putc(const char ch)
+static int sandbox_serial_putc(struct udevice *dev, const char ch)
{
+ struct sandbox_serial_priv *priv = dev_get_priv(dev);
+ struct sandbox_serial_platdata *plat = dev->platdata;
+
+ if (priv->start_of_line && plat->colour != -1) {
+ priv->start_of_line = false;
+ output_ansi_colour(plat->colour);
+ }
+
os_write(1, &ch, 1);
-}
+ if (ch == '\n')
+ priv->start_of_line = true;
-static void sandbox_serial_puts(const char *str)
-{
- os_write(1, str, strlen(str));
+ return 0;
}
static unsigned int increment_buffer_index(unsigned int index)
@@ -58,12 +104,15 @@ static unsigned int increment_buffer_index(unsigned int index)
return (index + 1) % ARRAY_SIZE(serial_buf);
}
-static int sandbox_serial_tstc(void)
+static int sandbox_serial_pending(struct udevice *dev, bool input)
{
const unsigned int next_index =
increment_buffer_index(serial_buf_write);
ssize_t count;
+ if (!input)
+ return 0;
+
os_usleep(100);
#ifdef CONFIG_LCD
lcd_sync();
@@ -74,38 +123,77 @@ static int sandbox_serial_tstc(void)
count = os_read_no_block(0, &serial_buf[serial_buf_write], 1);
if (count == 1)
serial_buf_write = next_index;
+
return serial_buf_write != serial_buf_read;
}
-static int sandbox_serial_getc(void)
+static int sandbox_serial_getc(struct udevice *dev)
{
int result;
- while (!sandbox_serial_tstc())
- ; /* buffer empty */
+ if (!sandbox_serial_pending(dev, true))
+ return -EAGAIN; /* buffer empty */
result = serial_buf[serial_buf_read];
serial_buf_read = increment_buffer_index(serial_buf_read);
return result;
}
-static struct serial_device sandbox_serial_drv = {
- .name = "sandbox_serial",
- .start = sandbox_serial_init,
- .stop = NULL,
- .setbrg = sandbox_serial_setbrg,
- .putc = sandbox_serial_putc,
- .puts = sandbox_serial_puts,
- .getc = sandbox_serial_getc,
- .tstc = sandbox_serial_tstc,
+static const char * const ansi_colour[] = {
+ "black", "red", "green", "yellow", "blue", "megenta", "cyan",
+ "white",
};
-void sandbox_serial_initialize(void)
+static int sandbox_serial_ofdata_to_platdata(struct udevice *dev)
{
- serial_register(&sandbox_serial_drv);
-}
+ struct sandbox_serial_platdata *plat = dev->platdata;
+ const char *colour;
+ int i;
+
+ plat->colour = -1;
+ colour = fdt_getprop(gd->fdt_blob, dev->of_offset,
+ "sandbox,text-colour", NULL);
+ if (colour) {
+ for (i = 0; i < ARRAY_SIZE(ansi_colour); i++) {
+ if (!strcmp(colour, ansi_colour[i])) {
+ plat->colour = i;
+ break;
+ }
+ }
+ }
-__weak struct serial_device *default_serial_console(void)
-{
- return &sandbox_serial_drv;
+ return 0;
}
+
+static const struct dm_serial_ops sandbox_serial_ops = {
+ .putc = sandbox_serial_putc,
+ .pending = sandbox_serial_pending,
+ .getc = sandbox_serial_getc,
+};
+
+static const struct udevice_id sandbox_serial_ids[] = {
+ { .compatible = "sandbox,serial" },
+ { }
+};
+
+U_BOOT_DRIVER(serial_sandbox) = {
+ .name = "serial_sandbox",
+ .id = UCLASS_SERIAL,
+ .of_match = sandbox_serial_ids,
+ .ofdata_to_platdata = sandbox_serial_ofdata_to_platdata,
+ .platdata_auto_alloc_size = sizeof(struct sandbox_serial_platdata),
+ .priv_auto_alloc_size = sizeof(struct sandbox_serial_priv),
+ .probe = sandbox_serial_probe,
+ .remove = sandbox_serial_remove,
+ .ops = &sandbox_serial_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+static const struct sandbox_serial_platdata platdata_non_fdt = {
+ .colour = -1,
+};
+
+U_BOOT_DEVICE(serial_sandbox_non_fdt) = {
+ .name = "serial_sandbox",
+ .platdata = &platdata_non_fdt,
+};
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
new file mode 100644
index 0000000000..d04104e747
--- /dev/null
+++ b/drivers/serial/serial-uclass.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2014 The Chromium OS Authors.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <os.h>
+#include <serial.h>
+#include <stdio_dev.h>
+#include <dm/lists.h>
+#include <dm/device-internal.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* The currently-selected console serial device */
+struct udevice *cur_dev __attribute__ ((section(".data")));
+
+#ifndef CONFIG_SYS_MALLOC_F_LEN
+#error "Serial is required before relocation - define CONFIG_SYS_MALLOC_F_LEN to make this work"
+#endif
+
+static void serial_find_console_or_panic(void)
+{
+ int node;
+
+ /* Check for a chosen console */
+ node = fdtdec_get_chosen_node(gd->fdt_blob, "stdout-path");
+ if (node < 0)
+ node = fdtdec_get_alias_node(gd->fdt_blob, "console");
+ if (!uclass_get_device_by_of_offset(UCLASS_SERIAL, node, &cur_dev))
+ return;
+
+ /*
+ * If the console is not marked to be bound before relocation, bind
+ * it anyway.
+ */
+ if (node > 0 &&
+ !lists_bind_fdt(gd->dm_root, gd->fdt_blob, node, &cur_dev)) {
+ if (!device_probe(cur_dev))
+ return;
+ cur_dev = NULL;
+ }
+
+ /*
+ * Failing that, get the device with sequence number 0, or in extremis
+ * just the first serial device we can find. But we insist on having
+ * a console (even if it is silent).
+ */
+ if (uclass_get_device_by_seq(UCLASS_SERIAL, 0, &cur_dev) &&
+ (uclass_first_device(UCLASS_SERIAL, &cur_dev) || !cur_dev))
+ panic("No serial driver found");
+}
+
+/* Called prior to relocation */
+int serial_init(void)
+{
+ serial_find_console_or_panic();
+ gd->flags |= GD_FLG_SERIAL_READY;
+
+ return 0;
+}
+
+/* Called after relocation */
+void serial_initialize(void)
+{
+ serial_find_console_or_panic();
+}
+
+void serial_putc(char ch)
+{
+ struct dm_serial_ops *ops = serial_get_ops(cur_dev);
+ int err;
+
+ do {
+ err = ops->putc(cur_dev, ch);
+ } while (err == -EAGAIN);
+ if (ch == '\n')
+ serial_putc('\r');
+}
+
+void serial_setbrg(void)
+{
+ struct dm_serial_ops *ops = serial_get_ops(cur_dev);
+
+ if (ops->setbrg)
+ ops->setbrg(cur_dev, gd->baudrate);
+}
+
+void serial_puts(const char *str)
+{
+ while (*str)
+ serial_putc(*str++);
+}
+
+int serial_tstc(void)
+{
+ struct dm_serial_ops *ops = serial_get_ops(cur_dev);
+
+ if (ops->pending)
+ return ops->pending(cur_dev, true);
+
+ return 1;
+}
+
+int serial_getc(void)
+{
+ struct dm_serial_ops *ops = serial_get_ops(cur_dev);
+ int err;
+
+ do {
+ err = ops->getc(cur_dev);
+ } while (err == -EAGAIN);
+
+ return err >= 0 ? err : 0;
+}
+
+void serial_stdio_init(void)
+{
+}
+
+void serial_stub_putc(struct stdio_dev *sdev, const char ch)
+{
+ struct udevice *dev = sdev->priv;
+ struct dm_serial_ops *ops = serial_get_ops(dev);
+
+ ops->putc(dev, ch);
+}
+
+void serial_stub_puts(struct stdio_dev *sdev, const char *str)
+{
+ while (*str)
+ serial_stub_putc(sdev, *str++);
+}
+
+int serial_stub_getc(struct stdio_dev *sdev)
+{
+ struct udevice *dev = sdev->priv;
+ struct dm_serial_ops *ops = serial_get_ops(dev);
+
+ int err;
+
+ do {
+ err = ops->getc(dev);
+ } while (err == -EAGAIN);
+
+ return err >= 0 ? err : 0;
+}
+
+int serial_stub_tstc(struct stdio_dev *sdev)
+{
+ struct udevice *dev = sdev->priv;
+ struct dm_serial_ops *ops = serial_get_ops(dev);
+
+ if (ops->pending)
+ return ops->pending(dev, true);
+
+ return 1;
+}
+
+static int serial_post_probe(struct udevice *dev)
+{
+ struct stdio_dev sdev;
+ struct dm_serial_ops *ops = serial_get_ops(dev);
+ struct serial_dev_priv *upriv = dev->uclass_priv;
+ int ret;
+
+ /* Set the baud rate */
+ if (ops->setbrg) {
+ ret = ops->setbrg(dev, gd->baudrate);
+ if (ret)
+ return ret;
+ }
+
+ if (!(gd->flags & GD_FLG_RELOC))
+ return 0;
+
+ memset(&sdev, '\0', sizeof(sdev));
+
+ strncpy(sdev.name, dev->name, sizeof(sdev.name));
+ sdev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT;
+ sdev.priv = dev;
+ sdev.putc = serial_stub_putc;
+ sdev.puts = serial_stub_puts;
+ sdev.getc = serial_stub_getc;
+ sdev.tstc = serial_stub_tstc;
+ stdio_register_dev(&sdev, &upriv->sdev);
+
+ return 0;
+}
+
+static int serial_pre_remove(struct udevice *dev)
+{
+#ifdef CONFIG_SYS_STDIO_DEREGISTER
+ struct serial_dev_priv *upriv = dev->uclass_priv;
+
+ if (stdio_deregister_dev(upriv->sdev))
+ return -EPERM;
+#endif
+
+ return 0;
+}
+
+UCLASS_DRIVER(serial) = {
+ .id = UCLASS_SERIAL,
+ .name = "serial",
+ .post_probe = serial_post_probe,
+ .pre_remove = serial_pre_remove,
+ .per_device_auto_alloc_size = sizeof(struct serial_dev_priv),
+};
diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c
index d2eb7520d0..bbe60af627 100644
--- a/drivers/serial/serial.c
+++ b/drivers/serial/serial.c
@@ -320,6 +320,7 @@ void serial_stdio_init(void)
dev.puts = serial_stub_puts;
dev.getc = serial_stub_getc;
dev.tstc = serial_stub_tstc;
+ dev.priv = s;
stdio_register(&dev);
diff --git a/drivers/serial/serial_lpuart.c b/drivers/serial/serial_lpuart.c
index 0a5e15919f..63fc388b26 100644
--- a/drivers/serial/serial_lpuart.c
+++ b/drivers/serial/serial_lpuart.c
@@ -22,10 +22,34 @@
#define SFIFO_RXOF (1 << 2)
#define SFIFO_RXUF (1 << 0)
+#define STAT_LBKDIF (1 << 31)
+#define STAT_RXEDGIF (1 << 30)
+#define STAT_TDRE (1 << 23)
+#define STAT_RDRF (1 << 21)
+#define STAT_IDLE (1 << 20)
+#define STAT_OR (1 << 19)
+#define STAT_NF (1 << 18)
+#define STAT_FE (1 << 17)
+#define STAT_PF (1 << 16)
+#define STAT_MA1F (1 << 15)
+#define STAT_MA2F (1 << 14)
+#define STAT_FLAGS (STAT_LBKDIF | STAT_RXEDGIF | STAT_IDLE | STAT_OR | \
+ STAT_NF | STAT_FE | STAT_PF | STAT_MA1F | STAT_MA2F)
+
+#define CTRL_TE (1 << 19)
+#define CTRL_RE (1 << 18)
+
+#define FIFO_TXFE 0x80
+#define FIFO_RXFE 0x40
+
+#define WATER_TXWATER_OFF 1
+#define WATER_RXWATER_OFF 16
+
DECLARE_GLOBAL_DATA_PTR;
struct lpuart_fsl *base = (struct lpuart_fsl *)LPUART_BASE;
+#ifndef CONFIG_LPUART_32B_REG
static void lpuart_serial_setbrg(void)
{
u32 clk = mxc_get_clock(MXC_UART_CLK);
@@ -114,13 +138,107 @@ static struct serial_device lpuart_serial_drv = {
.getc = lpuart_serial_getc,
.tstc = lpuart_serial_tstc,
};
+#else
+static void lpuart32_serial_setbrg(void)
+{
+ u32 clk = CONFIG_SYS_CLK_FREQ;
+ u32 sbr;
+
+ if (!gd->baudrate)
+ gd->baudrate = CONFIG_BAUDRATE;
+
+ sbr = (clk / (16 * gd->baudrate));
+ /* place adjustment later - n/32 BRFA */
+
+ out_be32(&base->baud, sbr);
+}
+
+static int lpuart32_serial_getc(void)
+{
+ u32 stat;
+
+ while (((stat = in_be32(&base->stat)) & STAT_RDRF) == 0) {
+ out_be32(&base->stat, STAT_FLAGS);
+ WATCHDOG_RESET();
+ }
+
+ return in_be32(&base->data) & 0x3ff;
+}
+
+static void lpuart32_serial_putc(const char c)
+{
+ if (c == '\n')
+ serial_putc('\r');
+
+ while (!(in_be32(&base->stat) & STAT_TDRE))
+ WATCHDOG_RESET();
+
+ out_be32(&base->data, c);
+}
+
+/*
+ * Test whether a character is in the RX buffer
+ */
+static int lpuart32_serial_tstc(void)
+{
+ if ((in_be32(&base->water) >> 24) == 0)
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Initialise the serial port with the given baudrate. The settings
+ * are always 8 data bits, no parity, 1 stop bit, no start bits.
+ */
+static int lpuart32_serial_init(void)
+{
+ u8 ctrl;
+
+ ctrl = in_be32(&base->ctrl);
+ ctrl &= ~CTRL_RE;
+ ctrl &= ~CTRL_TE;
+ out_be32(&base->ctrl, ctrl);
+
+ out_be32(&base->modir, 0);
+ out_be32(&base->fifo, ~(FIFO_TXFE | FIFO_RXFE));
+
+ out_be32(&base->match, 0);
+ /* provide data bits, parity, stop bit, etc */
+
+ serial_setbrg();
+
+ out_be32(&base->ctrl, CTRL_RE | CTRL_TE);
+
+ return 0;
+}
+
+static struct serial_device lpuart32_serial_drv = {
+ .name = "lpuart32_serial",
+ .start = lpuart32_serial_init,
+ .stop = NULL,
+ .setbrg = lpuart32_serial_setbrg,
+ .putc = lpuart32_serial_putc,
+ .puts = default_serial_puts,
+ .getc = lpuart32_serial_getc,
+ .tstc = lpuart32_serial_tstc,
+};
+#endif
void lpuart_serial_initialize(void)
{
+#ifdef CONFIG_LPUART_32B_REG
+ serial_register(&lpuart32_serial_drv);
+#else
serial_register(&lpuart_serial_drv);
+#endif
}
__weak struct serial_device *default_serial_console(void)
{
+#ifdef CONFIG_LPUART_32B_REG
+ return &lpuart32_serial_drv;
+#else
return &lpuart_serial_drv;
+#endif
}
diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c
index dafeed742d..632da4cf70 100644
--- a/drivers/serial/serial_ns16550.c
+++ b/drivers/serial/serial_ns16550.c
@@ -81,7 +81,8 @@ static NS16550_t serial_ports[6] = {
static int eserial##port##_init(void) \
{ \
int clock_divisor; \
- clock_divisor = calc_divisor(serial_ports[port-1]); \
+ clock_divisor = ns16550_calc_divisor(serial_ports[port-1], \
+ CONFIG_SYS_NS16550_CLK, gd->baudrate); \
NS16550_init(serial_ports[port-1], clock_divisor); \
return 0 ; \
} \
@@ -118,14 +119,6 @@ static NS16550_t serial_ports[6] = {
.puts = eserial##port##_puts, \
}
-static int calc_divisor (NS16550_t port)
-{
- const unsigned int mode_x_div = 16;
-
- return DIV_ROUND_CLOSEST(CONFIG_SYS_NS16550_CLK,
- mode_x_div * gd->baudrate);
-}
-
void
_serial_putc(const char c,const int port)
{
@@ -167,7 +160,8 @@ _serial_setbrg (const int port)
{
int clock_divisor;
- clock_divisor = calc_divisor(PORT);
+ clock_divisor = ns16550_calc_divisor(PORT, CONFIG_SYS_NS16550_CLK,
+ gd->baudrate);
NS16550_reinit(PORT, clock_divisor);
}
diff --git a/drivers/serial/serial_tegra.c b/drivers/serial/serial_tegra.c
new file mode 100644
index 0000000000..7eb70e1de1
--- /dev/null
+++ b/drivers/serial/serial_tegra.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <ns16550.h>
+#include <serial.h>
+
+static const struct udevice_id tegra_serial_ids[] = {
+ { .compatible = "nvidia,tegra20-uart" },
+ { }
+};
+
+static int tegra_serial_ofdata_to_platdata(struct udevice *dev)
+{
+ struct ns16550_platdata *plat = dev_get_platdata(dev);
+ int ret;
+
+ ret = ns16550_serial_ofdata_to_platdata(dev);
+ if (ret)
+ return ret;
+ plat->clock = V_NS16550_CLK;
+
+ return 0;
+}
+U_BOOT_DRIVER(serial_ns16550) = {
+ .name = "serial_tegra20",
+ .id = UCLASS_SERIAL,
+ .of_match = tegra_serial_ids,
+ .ofdata_to_platdata = tegra_serial_ofdata_to_platdata,
+ .platdata_auto_alloc_size = sizeof(struct ns16550_platdata),
+ .priv_auto_alloc_size = sizeof(struct NS16550),
+ .probe = ns16550_serial_probe,
+ .ops = &ns16550_serial_ops,
+};
diff --git a/drivers/usb/eth/smsc95xx.c b/drivers/usb/eth/smsc95xx.c
index 7a7a6767c7..6bca34dcf5 100644
--- a/drivers/usb/eth/smsc95xx.c
+++ b/drivers/usb/eth/smsc95xx.c
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2011 The Chromium OS Authors.
* Copyright (C) 2009 NVIDIA, Corporation
+ * Copyright (C) 2007-2008 SMSC (Steve Glendinning)
*
* SPDX-License-Identifier: GPL-2.0+
*/
diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c
index 9ffe5010be..9a8f004ece 100644
--- a/drivers/usb/host/ehci-atmel.c
+++ b/drivers/usb/host/ehci-atmel.c
@@ -40,7 +40,11 @@ int ehci_hcd_init(int index, enum usb_init_type init,
}
/* Enable USB Host clock */
+#ifdef CPU_HAS_PCR
+ at91_periph_clk_enable(ATMEL_ID_UHPHS);
+#else
writel(1 << ATMEL_ID_UHPHS, &pmc->pcer);
+#endif
*hccr = (struct ehci_hccr *)ATMEL_BASE_EHCI;
*hcor = (struct ehci_hcor *)((uint32_t)*hccr +
@@ -55,7 +59,11 @@ int ehci_hcd_stop(int index)
ulong start_time, tmp_time;
/* Disable USB Host Clock */
+#ifdef CPU_HAS_PCR
+ at91_periph_clk_disable(ATMEL_ID_UHPHS);
+#else
writel(1 << ATMEL_ID_UHPHS, &pmc->pcdr);
+#endif
start_time = get_timer(0);
/* Disable UTMI PLL */
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index c24505e78e..820e2e56ef 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -38,8 +38,8 @@ int usb_cpu_init(void)
#endif
/* Enable USB host clock. */
-#ifdef CONFIG_SAMA5D3
- writel(1 << (ATMEL_ID_UHP - 32), &pmc->pcer1);
+#ifdef CPU_HAS_PCR
+ at91_periph_clk_enable(ATMEL_ID_UHP);
#else
writel(1 << ATMEL_ID_UHP, &pmc->pcer);
#endif
@@ -58,8 +58,8 @@ int usb_cpu_stop(void)
at91_pmc_t *pmc = (at91_pmc_t *)ATMEL_BASE_PMC;
/* Disable USB host clock. */
-#ifdef CONFIG_SAMA5D3
- writel(1 << (ATMEL_ID_UHP - 32), &pmc->pcdr1);
+#ifdef CPU_HAS_PCR
+ at91_periph_clk_disable(ATMEL_ID_UHP);
#else
writel(1 << ATMEL_ID_UHP, &pmc->pcdr);
#endif
diff --git a/drivers/usb/musb-new/am35x.c b/drivers/usb/musb-new/am35x.c
index 57c9bd393b..857d7eb0cc 100644
--- a/drivers/usb/musb-new/am35x.c
+++ b/drivers/usb/musb-new/am35x.c
@@ -26,7 +26,6 @@
*
*/
-#define __UBOOT__
#ifndef __UBOOT__
#include <linux/init.h>
#include <linux/module.h>
diff --git a/drivers/usb/musb-new/musb_core.c b/drivers/usb/musb-new/musb_core.c
index 36681b6fc8..4edd6d729d 100644
--- a/drivers/usb/musb-new/musb_core.c
+++ b/drivers/usb/musb-new/musb_core.c
@@ -89,7 +89,6 @@
* Most of the conditional compilation will (someday) vanish.
*/
-#define __UBOOT__
#ifndef __UBOOT__
#include <linux/module.h>
#include <linux/kernel.h>
diff --git a/drivers/usb/musb-new/musb_dsps.c b/drivers/usb/musb-new/musb_dsps.c
index 9a03917e87..17ed224488 100644
--- a/drivers/usb/musb-new/musb_dsps.c
+++ b/drivers/usb/musb-new/musb_dsps.c
@@ -29,7 +29,6 @@
* da8xx.c would be merged to this file after testing.
*/
-#define __UBOOT__
#ifndef __UBOOT__
#include <linux/init.h>
#include <linux/io.h>
diff --git a/drivers/usb/musb-new/musb_gadget.c b/drivers/usb/musb-new/musb_gadget.c
index d2cb91a898..97acf93d31 100644
--- a/drivers/usb/musb-new/musb_gadget.c
+++ b/drivers/usb/musb-new/musb_gadget.c
@@ -33,7 +33,6 @@
*
*/
-#define __UBOOT__
#ifndef __UBOOT__
#include <linux/kernel.h>
#include <linux/list.h>
diff --git a/drivers/usb/musb-new/musb_gadget_ep0.c b/drivers/usb/musb-new/musb_gadget_ep0.c
index 8c3b0a145a..5a715013a2 100644
--- a/drivers/usb/musb-new/musb_gadget_ep0.c
+++ b/drivers/usb/musb-new/musb_gadget_ep0.c
@@ -33,7 +33,6 @@
*
*/
-#define __UBOOT__
#ifndef __UBOOT__
#include <linux/kernel.h>
#include <linux/list.h>
diff --git a/drivers/usb/musb-new/musb_host.c b/drivers/usb/musb-new/musb_host.c
index 9a2cf59d92..bbcee88241 100644
--- a/drivers/usb/musb-new/musb_host.c
+++ b/drivers/usb/musb-new/musb_host.c
@@ -33,7 +33,6 @@
*
*/
-#define __UBOOT__
#ifndef __UBOOT__
#include <linux/module.h>
#include <linux/kernel.h>
diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c
index 0d7b89fcf6..2676f09c38 100644
--- a/drivers/usb/musb-new/musb_uboot.c
+++ b/drivers/usb/musb-new/musb_uboot.c
@@ -4,7 +4,6 @@
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
-#define __UBOOT__
#include <usb.h>
#include "linux-compat.h"
#include "usb-compat.h"
diff --git a/drivers/usb/musb-new/omap2430.c b/drivers/usb/musb-new/omap2430.c
index b1c4dc7828..98f4830912 100644
--- a/drivers/usb/musb-new/omap2430.c
+++ b/drivers/usb/musb-new/omap2430.c
@@ -24,7 +24,6 @@
* Suite 330, Boston, MA 02111-1307 USA
*
*/
-#define __UBOOT__
#ifndef __UBOOT__
#include <linux/module.h>
#include <linux/kernel.h>
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 248aa350b7..14a6781edc 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_EXYNOS_MIPI_DSIM) += exynos_mipi_dsi.o exynos_mipi_dsi_common.o \
exynos_mipi_dsi_lowlevel.o
obj-$(CONFIG_EXYNOS_PWM_BL) += exynos_pwm_bl.o
obj-$(CONFIG_FSL_DIU_FB) += fsl_diu_fb.o videomodes.o
+obj-$(CONFIG_FSL_DCU_FB) += fsl_dcu_fb.o videomodes.o
obj-$(CONFIG_L5F31188) += l5f31188.o
obj-$(CONFIG_MPC8XX_LCD) += mpc8xx_lcd.o
obj-$(CONFIG_PXA_LCD) += pxa_lcd.o
diff --git a/drivers/video/fsl_dcu_fb.c b/drivers/video/fsl_dcu_fb.c
new file mode 100644
index 0000000000..d4cd382776
--- /dev/null
+++ b/drivers/video/fsl_dcu_fb.c
@@ -0,0 +1,365 @@
+/*
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ *
+ * FSL DCU Framebuffer driver
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <asm/io.h>
+#include <common.h>
+#include <fsl_dcu_fb.h>
+#include <linux/fb.h>
+#include <malloc.h>
+#include <video_fb.h>
+#include "videomodes.h"
+
+/* Convert the X,Y resolution pair into a single number */
+#define RESOLUTION(x, y) (((u32)(x) << 16) | (y))
+
+#ifdef CONFIG_SYS_FSL_DCU_LE
+#define dcu_read32 in_le32
+#define dcu_write32 out_le32
+#elif defined(CONFIG_SYS_FSL_DCU_BE)
+#define dcu_read32 in_be32
+#define dcu_write32 out_be32
+#endif
+
+#define DCU_MODE_BLEND_ITER(x) ((x) << 20)
+#define DCU_MODE_RASTER_EN (1 << 14)
+#define DCU_MODE_NORMAL 1
+#define DCU_MODE_COLORBAR 3
+#define DCU_BGND_R(x) ((x) << 16)
+#define DCU_BGND_G(x) ((x) << 8)
+#define DCU_BGND_B(x) (x)
+#define DCU_DISP_SIZE_DELTA_Y(x) ((x) << 16)
+#define DCU_DISP_SIZE_DELTA_X(x) (x)
+#define DCU_HSYN_PARA_BP(x) ((x) << 22)
+#define DCU_HSYN_PARA_PW(x) ((x) << 11)
+#define DCU_HSYN_PARA_FP(x) (x)
+#define DCU_VSYN_PARA_BP(x) ((x) << 22)
+#define DCU_VSYN_PARA_PW(x) ((x) << 11)
+#define DCU_VSYN_PARA_FP(x) (x)
+#define DCU_SYN_POL_INV_PXCK_FALL (0 << 6)
+#define DCU_SYN_POL_NEG_REMAIN (0 << 5)
+#define DCU_SYN_POL_INV_VS_LOW (1 << 1)
+#define DCU_SYN_POL_INV_HS_LOW (1)
+#define DCU_THRESHOLD_LS_BF_VS(x) ((x) << 16)
+#define DCU_THRESHOLD_OUT_BUF_HIGH(x) ((x) << 8)
+#define DCU_THRESHOLD_OUT_BUF_LOW(x) (x)
+#define DCU_UPDATE_MODE_MODE (1 << 31)
+#define DCU_UPDATE_MODE_READREG (1 << 30)
+
+#define DCU_CTRLDESCLN_1_HEIGHT(x) ((x) << 16)
+#define DCU_CTRLDESCLN_1_WIDTH(x) (x)
+#define DCU_CTRLDESCLN_2_POSY(x) ((x) << 16)
+#define DCU_CTRLDESCLN_2_POSX(x) (x)
+#define DCU_CTRLDESCLN_4_EN (1 << 31)
+#define DCU_CTRLDESCLN_4_TILE_EN (1 << 30)
+#define DCU_CTRLDESCLN_4_DATA_SEL_CLUT (1 << 29)
+#define DCU_CTRLDESCLN_4_SAFETY_EN (1 << 28)
+#define DCU_CTRLDESCLN_4_TRANS(x) ((x) << 20)
+#define DCU_CTRLDESCLN_4_BPP(x) ((x) << 16)
+#define DCU_CTRLDESCLN_4_RLE_EN (1 << 15)
+#define DCU_CTRLDESCLN_4_LUOFFS(x) ((x) << 4)
+#define DCU_CTRLDESCLN_4_BB_ON (1 << 2)
+#define DCU_CTRLDESCLN_4_AB(x) (x)
+#define DCU_CTRLDESCLN_5_CKMAX_R(x) ((x) << 16)
+#define DCU_CTRLDESCLN_5_CKMAX_G(x) ((x) << 8)
+#define DCU_CTRLDESCLN_5_CKMAX_B(x) (x)
+#define DCU_CTRLDESCLN_6_CKMIN_R(x) ((x) << 16)
+#define DCU_CTRLDESCLN_6_CKMIN_G(x) ((x) << 8)
+#define DCU_CTRLDESCLN_6_CKMIN_B(x) (x)
+#define DCU_CTRLDESCLN_7_TILE_VER(x) ((x) << 16)
+#define DCU_CTRLDESCLN_7_TILE_HOR(x) (x)
+#define DCU_CTRLDESCLN_8_FG_FCOLOR(x) (x)
+#define DCU_CTRLDESCLN_9_BG_BCOLOR(x) (x)
+
+#define BPP_16_RGB565 4
+#define BPP_24_RGB888 5
+#define BPP_32_ARGB8888 6
+
+/*
+ * This setting is used for the TWR_LCD_RGB card
+ */
+static struct fb_videomode fsl_dcu_mode_480_272 = {
+ .name = "480x272-60",
+ .refresh = 60,
+ .xres = 480,
+ .yres = 272,
+ .pixclock = 91996,
+ .left_margin = 2,
+ .right_margin = 2,
+ .upper_margin = 1,
+ .lower_margin = 1,
+ .hsync_len = 41,
+ .vsync_len = 2,
+ .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED
+};
+
+/*
+ * This setting is used for Siliconimage SiI9022A HDMI
+ */
+static struct fb_videomode fsl_dcu_mode_640_480 = {
+ .name = "640x480-60",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 39722,
+ .left_margin = 48,
+ .right_margin = 16,
+ .upper_margin = 33,
+ .lower_margin = 10,
+ .hsync_len = 96,
+ .vsync_len = 2,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+};
+
+/*
+ * DCU register map
+ */
+struct dcu_reg {
+ u32 desc_cursor[4];
+ u32 mode;
+ u32 bgnd;
+ u32 disp_size;
+ u32 hsyn_para;
+ u32 vsyn_para;
+ u32 synpol;
+ u32 threshold;
+ u32 int_status;
+ u32 int_mask;
+ u32 colbar[8];
+ u32 div_ratio;
+ u32 sign_calc[2];
+ u32 crc_val;
+ u8 res_064[0x6c-0x64];
+ u32 parr_err_status1;
+ u8 res_070[0x7c-0x70];
+ u32 parr_err_status3;
+ u32 mparr_err_status1;
+ u8 res_084[0x90-0x84];
+ u32 mparr_err_status3;
+ u32 threshold_inp_buf[2];
+ u8 res_09c[0xa0-0x9c];
+ u32 luma_comp;
+ u32 chroma_red;
+ u32 chroma_green;
+ u32 chroma_blue;
+ u32 crc_pos;
+ u32 lyr_intpol_en;
+ u32 lyr_luma_comp;
+ u32 lyr_chrm_red;
+ u32 lyr_chrm_grn;
+ u32 lyr_chrm_blue;
+ u8 res_0c4[0xcc-0xc8];
+ u32 update_mode;
+ u32 underrun;
+ u8 res_0d4[0x100-0xd4];
+ u32 gpr;
+ u32 slr_l[2];
+ u32 slr_disp_size;
+ u32 slr_hvsync_para;
+ u32 slr_pol;
+ u32 slr_l_transp[2];
+ u8 res_120[0x200-0x120];
+ u32 ctrldescl[DCU_LAYER_MAX_NUM][16];
+};
+
+static struct fb_info info;
+
+static void reset_total_layers(void)
+{
+ struct dcu_reg *regs = (struct dcu_reg *)CONFIG_SYS_DCU_ADDR;
+ int i;
+
+ for (i = 0; i < DCU_LAYER_MAX_NUM; i++) {
+ dcu_write32(&regs->ctrldescl[i][0], 0);
+ dcu_write32(&regs->ctrldescl[i][1], 0);
+ dcu_write32(&regs->ctrldescl[i][2], 0);
+ dcu_write32(&regs->ctrldescl[i][3], 0);
+ dcu_write32(&regs->ctrldescl[i][4], 0);
+ dcu_write32(&regs->ctrldescl[i][5], 0);
+ dcu_write32(&regs->ctrldescl[i][6], 0);
+ dcu_write32(&regs->ctrldescl[i][7], 0);
+ dcu_write32(&regs->ctrldescl[i][8], 0);
+ dcu_write32(&regs->ctrldescl[i][9], 0);
+ dcu_write32(&regs->ctrldescl[i][10], 0);
+ }
+
+ dcu_write32(&regs->update_mode, DCU_UPDATE_MODE_READREG);
+}
+
+static int layer_ctrldesc_init(int index, u32 pixel_format)
+{
+ struct dcu_reg *regs = (struct dcu_reg *)CONFIG_SYS_DCU_ADDR;
+ unsigned int bpp = BPP_24_RGB888;
+
+ dcu_write32(&regs->ctrldescl[index][0],
+ DCU_CTRLDESCLN_1_HEIGHT(info.var.yres) |
+ DCU_CTRLDESCLN_1_WIDTH(info.var.xres));
+
+ dcu_write32(&regs->ctrldescl[index][1],
+ DCU_CTRLDESCLN_2_POSY(0) |
+ DCU_CTRLDESCLN_2_POSX(0));
+
+ dcu_write32(&regs->ctrldescl[index][2], (unsigned int)info.screen_base);
+
+ switch (pixel_format) {
+ case 16:
+ bpp = BPP_16_RGB565;
+ break;
+ case 24:
+ bpp = BPP_24_RGB888;
+ break;
+ case 32:
+ bpp = BPP_32_ARGB8888;
+ break;
+ default:
+ printf("unsupported color depth: %u\n", pixel_format);
+ }
+
+ dcu_write32(&regs->ctrldescl[index][3],
+ DCU_CTRLDESCLN_4_EN |
+ DCU_CTRLDESCLN_4_TRANS(0xff) |
+ DCU_CTRLDESCLN_4_BPP(bpp) |
+ DCU_CTRLDESCLN_4_AB(0));
+
+ dcu_write32(&regs->ctrldescl[index][4],
+ DCU_CTRLDESCLN_5_CKMAX_R(0xff) |
+ DCU_CTRLDESCLN_5_CKMAX_G(0xff) |
+ DCU_CTRLDESCLN_5_CKMAX_B(0xff));
+ dcu_write32(&regs->ctrldescl[index][5],
+ DCU_CTRLDESCLN_6_CKMIN_R(0) |
+ DCU_CTRLDESCLN_6_CKMIN_G(0) |
+ DCU_CTRLDESCLN_6_CKMIN_B(0));
+
+ dcu_write32(&regs->ctrldescl[index][6],
+ DCU_CTRLDESCLN_7_TILE_VER(0) |
+ DCU_CTRLDESCLN_7_TILE_HOR(0));
+
+ dcu_write32(&regs->ctrldescl[index][7], DCU_CTRLDESCLN_8_FG_FCOLOR(0));
+ dcu_write32(&regs->ctrldescl[index][8], DCU_CTRLDESCLN_9_BG_BCOLOR(0));
+
+ dcu_write32(&regs->update_mode, DCU_UPDATE_MODE_READREG);
+
+ return 0;
+}
+
+int fsl_dcu_init(unsigned int xres, unsigned int yres,
+ unsigned int pixel_format)
+{
+ struct dcu_reg *regs = (struct dcu_reg *)CONFIG_SYS_DCU_ADDR;
+ unsigned int div, mode;
+
+ /* Memory allocation for framebuffer */
+ info.screen_size =
+ info.var.xres * info.var.yres * (info.var.bits_per_pixel / 8);
+ info.screen_base = (char *)memalign(ARCH_DMA_MINALIGN,
+ roundup(info.screen_size, ARCH_DMA_MINALIGN));
+ memset(info.screen_base, 0, info.screen_size);
+
+ reset_total_layers();
+ div = dcu_set_pixel_clock(info.var.pixclock);
+ dcu_write32(&regs->div_ratio, (div - 1));
+
+ dcu_write32(&regs->disp_size,
+ DCU_DISP_SIZE_DELTA_Y(info.var.yres) |
+ DCU_DISP_SIZE_DELTA_X(info.var.xres / 16));
+
+ dcu_write32(&regs->hsyn_para,
+ DCU_HSYN_PARA_BP(info.var.left_margin) |
+ DCU_HSYN_PARA_PW(info.var.hsync_len) |
+ DCU_HSYN_PARA_FP(info.var.right_margin));
+
+ dcu_write32(&regs->vsyn_para,
+ DCU_VSYN_PARA_BP(info.var.upper_margin) |
+ DCU_VSYN_PARA_PW(info.var.vsync_len) |
+ DCU_VSYN_PARA_FP(info.var.lower_margin));
+
+ dcu_write32(&regs->synpol,
+ DCU_SYN_POL_INV_PXCK_FALL |
+ DCU_SYN_POL_NEG_REMAIN |
+ DCU_SYN_POL_INV_VS_LOW |
+ DCU_SYN_POL_INV_HS_LOW);
+
+ dcu_write32(&regs->bgnd,
+ DCU_BGND_R(0) | DCU_BGND_G(0) | DCU_BGND_B(0));
+
+ dcu_write32(&regs->mode,
+ DCU_MODE_BLEND_ITER(DCU_LAYER_MAX_NUM) |
+ DCU_MODE_RASTER_EN);
+
+ dcu_write32(&regs->threshold,
+ DCU_THRESHOLD_LS_BF_VS(0x3) |
+ DCU_THRESHOLD_OUT_BUF_HIGH(0x78) |
+ DCU_THRESHOLD_OUT_BUF_LOW(0));
+
+ mode = dcu_read32(&regs->mode);
+ dcu_write32(&regs->mode, mode | DCU_MODE_NORMAL);
+
+ layer_ctrldesc_init(0, pixel_format);
+
+ return 0;
+}
+
+void *video_hw_init(void)
+{
+ static GraphicDevice ctfb;
+ const char *options;
+ unsigned int depth = 0, freq = 0;
+ struct fb_videomode *fsl_dcu_mode_db = &fsl_dcu_mode_480_272;
+
+ if (!video_get_video_mode(&ctfb.winSizeX, &ctfb.winSizeY, &depth, &freq,
+ &options))
+ return NULL;
+
+ /* Find the monitor port, which is a required option */
+ if (!options)
+ return NULL;
+ if (strncmp(options, "monitor=", 8) != 0)
+ return NULL;
+
+ switch (RESOLUTION(ctfb.winSizeX, ctfb.winSizeY)) {
+ case RESOLUTION(480, 272):
+ fsl_dcu_mode_db = &fsl_dcu_mode_480_272;
+ break;
+ case RESOLUTION(640, 480):
+ fsl_dcu_mode_db = &fsl_dcu_mode_640_480;
+ break;
+ default:
+ printf("unsupported resolution %ux%u\n",
+ ctfb.winSizeX, ctfb.winSizeY);
+ }
+
+ info.var.xres = fsl_dcu_mode_db->xres;
+ info.var.yres = fsl_dcu_mode_db->yres;
+ info.var.bits_per_pixel = 32;
+ info.var.pixclock = fsl_dcu_mode_db->pixclock;
+ info.var.left_margin = fsl_dcu_mode_db->left_margin;
+ info.var.right_margin = fsl_dcu_mode_db->right_margin;
+ info.var.upper_margin = fsl_dcu_mode_db->upper_margin;
+ info.var.lower_margin = fsl_dcu_mode_db->lower_margin;
+ info.var.hsync_len = fsl_dcu_mode_db->hsync_len;
+ info.var.vsync_len = fsl_dcu_mode_db->vsync_len;
+ info.var.sync = fsl_dcu_mode_db->sync;
+ info.var.vmode = fsl_dcu_mode_db->vmode;
+ info.fix.line_length = info.var.xres * info.var.bits_per_pixel / 8;
+
+ if (platform_dcu_init(ctfb.winSizeX, ctfb.winSizeY,
+ options + 8, fsl_dcu_mode_db) < 0)
+ return NULL;
+
+ ctfb.frameAdrs = (unsigned int)info.screen_base;
+ ctfb.plnSizeX = ctfb.winSizeX;
+ ctfb.plnSizeY = ctfb.winSizeY;
+
+ ctfb.gdfBytesPP = 4;
+ ctfb.gdfIndex = GDF_32BIT_X888RGB;
+
+ ctfb.memSize = info.screen_size;
+
+ return &ctfb;
+}
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 0276a10564..1dc0f5aa10 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -7,7 +7,7 @@
obj-$(CONFIG_AT91SAM9_WATCHDOG) += at91sam9_wdt.o
obj-$(CONFIG_FTWDT010_WATCHDOG) += ftwdt010_wdt.o
-ifneq (,$(filter $(SOC), mx31 mx35 mx5 mx6 vf610))
+ifneq (,$(filter $(SOC), mx31 mx35 mx5 mx6 vf610 ls102xa))
obj-y += imx_watchdog.o
endif
obj-$(CONFIG_TNETV107X_WATCHDOG) += tnetv107x_wdt.o
OpenPOWER on IntegriCloud