diff options
Diffstat (limited to 'drivers')
43 files changed, 1305 insertions, 525 deletions
diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c index c8f65739e9..4df804671a 100644 --- a/drivers/block/ahci.c +++ b/drivers/block/ahci.c @@ -41,7 +41,7 @@ u16 *ataid[AHCI_MAX_PORTS]; #define WAIT_MS_SPINUP 20000 #define WAIT_MS_DATAIO 5000 #define WAIT_MS_FLUSH 5000 -#define WAIT_MS_LINKUP 40 +#define WAIT_MS_LINKUP 200 static inline u32 ahci_port_base(u32 base, u32 port) { diff --git a/drivers/core/device.c b/drivers/core/device.c index c73c339d18..166b0732ab 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -10,6 +10,7 @@ */ #include <common.h> +#include <fdtdec.h> #include <malloc.h> #include <dm/device.h> #include <dm/device-internal.h> @@ -21,6 +22,8 @@ #include <linux/err.h> #include <linux/list.h> +DECLARE_GLOBAL_DATA_PTR; + /** * device_chld_unbind() - Unbind all device's children from the device * @@ -95,6 +98,21 @@ int device_bind(struct udevice *parent, struct driver *drv, const char *name, dev->parent = parent; dev->driver = drv; dev->uclass = uc; + + /* + * For some devices, such as a SPI or I2C bus, the 'reg' property + * is a reasonable indicator of the sequence number. But if there is + * an alias, we use that in preference. In any case, this is just + * a 'requested' sequence, and will be resolved (and ->seq updated) + * when the device is probed. + */ + dev->req_seq = fdtdec_get_int(gd->fdt_blob, of_offset, "reg", -1); + dev->seq = -1; + if (uc->uc_drv->name && of_offset != -1) { + fdtdec_get_alias_seq(gd->fdt_blob, uc->uc_drv->name, of_offset, + &dev->req_seq); + } + if (!dev->platdata && drv->platdata_auto_alloc_size) dev->flags |= DM_FLAG_ALLOC_PDATA; @@ -129,14 +147,16 @@ fail_bind: return ret; } -int device_bind_by_name(struct udevice *parent, const struct driver_info *info, - struct udevice **devp) +int device_bind_by_name(struct udevice *parent, bool pre_reloc_only, + const struct driver_info *info, struct udevice **devp) { struct driver *drv; drv = lists_driver_lookup_name(info->name); if (!drv) return -ENOENT; + if (pre_reloc_only && !(drv->flags & DM_FLAG_PRE_RELOC)) + return -EPERM; return device_bind(parent, drv, info->name, (void *)info->platdata, -1, devp); @@ -198,6 +218,13 @@ static void device_free(struct udevice *dev) free(dev->uclass_priv); dev->uclass_priv = NULL; } + if (dev->parent) { + size = dev->parent->driver->per_child_auto_alloc_size; + if (size) { + free(dev->parent_priv); + dev->parent_priv = NULL; + } + } } int device_probe(struct udevice *dev) @@ -205,6 +232,7 @@ int device_probe(struct udevice *dev) struct driver *drv; int size = 0; int ret; + int seq; if (!dev) return -EINVAL; @@ -242,11 +270,33 @@ int device_probe(struct udevice *dev) /* Ensure all parents are probed */ if (dev->parent) { + size = dev->parent->driver->per_child_auto_alloc_size; + if (size) { + dev->parent_priv = calloc(1, size); + if (!dev->parent_priv) { + ret = -ENOMEM; + goto fail; + } + } + ret = device_probe(dev->parent); if (ret) goto fail; } + seq = uclass_resolve_seq(dev); + if (seq < 0) { + ret = seq; + goto fail; + } + dev->seq = seq; + + if (dev->parent && dev->parent->driver->child_pre_probe) { + ret = dev->parent->driver->child_pre_probe(dev); + if (ret) + goto fail; + } + if (drv->ofdata_to_platdata && dev->of_offset >= 0) { ret = drv->ofdata_to_platdata(dev); if (ret) @@ -274,6 +324,7 @@ fail_uclass: __func__, dev->name); } fail: + dev->seq = -1; device_free(dev); return ret; @@ -307,11 +358,20 @@ int device_remove(struct udevice *dev) goto err_remove; } + if (dev->parent && dev->parent->driver->child_post_remove) { + ret = dev->parent->driver->child_post_remove(dev); + if (ret) { + dm_warn("%s: Device '%s' failed child_post_remove()", + __func__, dev->name); + } + } + device_free(dev); + dev->seq = -1; dev->flags &= ~DM_FLAG_ACTIVATED; - return 0; + return ret; err_remove: /* We can't put the children back */ @@ -346,3 +406,106 @@ void *dev_get_priv(struct udevice *dev) return dev->priv; } + +void *dev_get_parentdata(struct udevice *dev) +{ + if (!dev) { + dm_warn("%s: null device", __func__); + return NULL; + } + + return dev->parent_priv; +} + +static int device_get_device_tail(struct udevice *dev, int ret, + struct udevice **devp) +{ + if (ret) + return ret; + + ret = device_probe(dev); + if (ret) + return ret; + + *devp = dev; + + return 0; +} + +int device_get_child(struct udevice *parent, int index, struct udevice **devp) +{ + struct udevice *dev; + + list_for_each_entry(dev, &parent->child_head, sibling_node) { + if (!index--) + return device_get_device_tail(dev, 0, devp); + } + + return -ENODEV; +} + +int device_find_child_by_seq(struct udevice *parent, int seq_or_req_seq, + bool find_req_seq, struct udevice **devp) +{ + struct udevice *dev; + + *devp = NULL; + if (seq_or_req_seq == -1) + return -ENODEV; + + list_for_each_entry(dev, &parent->child_head, sibling_node) { + if ((find_req_seq ? dev->req_seq : dev->seq) == + seq_or_req_seq) { + *devp = dev; + return 0; + } + } + + return -ENODEV; +} + +int device_get_child_by_seq(struct udevice *parent, int seq, + struct udevice **devp) +{ + struct udevice *dev; + int ret; + + *devp = NULL; + ret = device_find_child_by_seq(parent, seq, false, &dev); + if (ret == -ENODEV) { + /* + * We didn't find it in probed devices. See if there is one + * that will request this seq if probed. + */ + ret = device_find_child_by_seq(parent, seq, true, &dev); + } + return device_get_device_tail(dev, ret, devp); +} + +int device_find_child_by_of_offset(struct udevice *parent, int of_offset, + struct udevice **devp) +{ + struct udevice *dev; + + *devp = NULL; + + list_for_each_entry(dev, &parent->child_head, sibling_node) { + if (dev->of_offset == of_offset) { + *devp = dev; + return 0; + } + } + + return -ENODEV; +} + +int device_get_child_by_of_offset(struct udevice *parent, int seq, + struct udevice **devp) +{ + struct udevice *dev; + int ret; + + *devp = NULL; + ret = device_find_child_by_of_offset(parent, seq, &dev); + return device_get_device_tail(dev, ret, devp); +} diff --git a/drivers/core/lists.c b/drivers/core/lists.c index afb59d1d8d..0f08bfd6ff 100644 --- a/drivers/core/lists.c +++ b/drivers/core/lists.c @@ -11,6 +11,7 @@ #include <errno.h> #include <dm/device.h> #include <dm/device-internal.h> +#include <dm/lists.h> #include <dm/platdata.h> #include <dm/uclass.h> #include <dm/util.h> @@ -61,7 +62,7 @@ struct uclass_driver *lists_uclass_lookup(enum uclass_id id) return NULL; } -int lists_bind_drivers(struct udevice *parent) +int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only) { struct driver_info *info = ll_entry_start(struct driver_info, driver_info); @@ -72,8 +73,8 @@ int lists_bind_drivers(struct udevice *parent) int ret; for (entry = info; entry != info + n_ents; entry++) { - ret = device_bind_by_name(parent, entry, &dev); - if (ret) { + ret = device_bind_by_name(parent, pre_reloc_only, entry, &dev); + if (ret && ret != -EPERM) { dm_warn("No match for driver '%s'\n", entry->name); if (!result || ret != -ENOENT) result = ret; @@ -123,16 +124,19 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset) const int n_ents = ll_entry_count(struct driver, driver); struct driver *entry; struct udevice *dev; + bool found = false; const char *name; int result = 0; - int ret; + int ret = 0; dm_dbg("bind node %s\n", fdt_get_name(blob, offset, 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); if (ret == -ENOENT) { continue; } else if (ret == -ENODEV) { + dm_dbg("Device '%s' has no compatible string\n", name); break; } else if (ret) { dm_warn("Device tree error at offset %d\n", offset); @@ -141,14 +145,21 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset) break; } - name = fdt_get_name(blob, offset, NULL); dm_dbg(" - found match at '%s'\n", entry->name); ret = device_bind(parent, entry, name, NULL, offset, &dev); if (ret) { - dm_warn("No match for driver '%s'\n", entry->name); + dm_warn("Error binding driver '%s'\n", entry->name); if (!result || ret != -ENOENT) result = ret; + } else { + found = true; } + break; + } + + if (!found && !result && ret != -ENODEV) { + dm_dbg("No match for node '%s'\n", + fdt_get_name(blob, offset, NULL)); } return result; diff --git a/drivers/core/root.c b/drivers/core/root.c index 1cbb096494..393dd98b9d 100644 --- a/drivers/core/root.c +++ b/drivers/core/root.c @@ -15,6 +15,7 @@ #include <dm/device-internal.h> #include <dm/lists.h> #include <dm/platdata.h> +#include <dm/root.h> #include <dm/uclass.h> #include <dm/util.h> #include <linux/list.h> @@ -45,18 +46,29 @@ int dm_init(void) } INIT_LIST_HEAD(&DM_UCLASS_ROOT_NON_CONST); - ret = device_bind_by_name(NULL, &root_info, &DM_ROOT_NON_CONST); + ret = device_bind_by_name(NULL, false, &root_info, &DM_ROOT_NON_CONST); if (ret) return ret; + ret = device_probe(DM_ROOT_NON_CONST); + if (ret) + return ret; + + return 0; +} + +int dm_uninit(void) +{ + device_remove(dm_root()); + device_unbind(dm_root()); return 0; } -int dm_scan_platdata(void) +int dm_scan_platdata(bool pre_reloc_only) { int ret; - ret = lists_bind_drivers(DM_ROOT_NON_CONST); + ret = lists_bind_drivers(DM_ROOT_NON_CONST, pre_reloc_only); if (ret == -ENOENT) { dm_warn("Some drivers were not found\n"); ret = 0; @@ -68,27 +80,66 @@ int dm_scan_platdata(void) } #ifdef CONFIG_OF_CONTROL -int dm_scan_fdt(const void *blob) +int dm_scan_fdt_node(struct udevice *parent, const void *blob, int offset, + bool pre_reloc_only) { - int offset = 0; int ret = 0, err; - int depth = 0; - do { - offset = fdt_next_node(blob, offset, &depth); - if (offset > 0 && depth == 1) { - err = lists_bind_fdt(gd->dm_root, blob, offset); - if (err && !ret) - ret = err; - } - } while (offset > 0); + for (offset = fdt_first_subnode(blob, offset); + offset > 0; + offset = fdt_next_subnode(blob, offset)) { + if (pre_reloc_only && + !fdt_getprop(blob, offset, "u-boot,dm-pre-reloc", NULL)) + continue; + err = lists_bind_fdt(parent, blob, offset); + if (err && !ret) + ret = err; + } if (ret) dm_warn("Some drivers failed to bind\n"); return ret; } + +int dm_scan_fdt(const void *blob, bool pre_reloc_only) +{ + return dm_scan_fdt_node(gd->dm_root, blob, 0, pre_reloc_only); +} +#endif + +__weak int dm_scan_other(bool pre_reloc_only) +{ + return 0; +} + +int dm_init_and_scan(bool pre_reloc_only) +{ + int ret; + + ret = dm_init(); + if (ret) { + debug("dm_init() failed: %d\n", ret); + return ret; + } + ret = dm_scan_platdata(pre_reloc_only); + if (ret) { + debug("dm_scan_platdata() failed: %d\n", ret); + return ret; + } +#ifdef CONFIG_OF_CONTROL + ret = dm_scan_fdt(gd->fdt_blob, pre_reloc_only); + if (ret) { + debug("dm_scan_fdt() failed: %d\n", ret); + return ret; + } #endif + ret = dm_scan_other(pre_reloc_only); + if (ret) + return ret; + + return 0; +} /* This is the root driver - all drivers are children of this */ U_BOOT_DRIVER(root_driver) = { diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index 34723ec42a..61ca17e564 100644 --- a/drivers/core/uclass.c +++ b/drivers/core/uclass.c @@ -23,6 +23,8 @@ struct uclass *uclass_find(enum uclass_id key) { struct uclass *uc; + if (!gd->dm_root) + return NULL; /* * TODO(sjg@chromium.org): Optimise this, perhaps moving the found * node to the start of the list, or creating a linear array mapping @@ -158,13 +160,72 @@ int uclass_find_device(enum uclass_id id, int index, struct udevice **devp) return -ENODEV; } -int uclass_get_device(enum uclass_id id, int index, struct udevice **devp) +int uclass_find_device_by_seq(enum uclass_id id, int seq_or_req_seq, + bool find_req_seq, struct udevice **devp) { + struct uclass *uc; struct udevice *dev; int ret; *devp = NULL; - ret = uclass_find_device(id, index, &dev); + debug("%s: %d %d\n", __func__, find_req_seq, seq_or_req_seq); + if (seq_or_req_seq == -1) + return -ENODEV; + ret = uclass_get(id, &uc); + if (ret) + return ret; + + list_for_each_entry(dev, &uc->dev_head, uclass_node) { + debug(" - %d %d\n", dev->req_seq, dev->seq); + if ((find_req_seq ? dev->req_seq : dev->seq) == + seq_or_req_seq) { + *devp = dev; + debug(" - found\n"); + return 0; + } + } + debug(" - not found\n"); + + return -ENODEV; +} + +static int uclass_find_device_by_of_offset(enum uclass_id id, int node, + struct udevice **devp) +{ + struct uclass *uc; + struct udevice *dev; + int ret; + + *devp = NULL; + if (node < 0) + return -ENODEV; + ret = uclass_get(id, &uc); + if (ret) + return ret; + + list_for_each_entry(dev, &uc->dev_head, uclass_node) { + if (dev->of_offset == node) { + *devp = dev; + return 0; + } + } + + return -ENODEV; +} + +/** + * uclass_get_device_tail() - handle the end of a get_device call + * + * This handles returning an error or probing a device as needed. + * + * @dev: Device that needs to be probed + * @ret: Error to return. If non-zero then the device is not probed + * @devp: Returns the value of 'dev' if there is no error + * @return ret, if non-zero, else the result of the device_probe() call + */ +static int uclass_get_device_tail(struct udevice *dev, int ret, + struct udevice **devp) +{ if (ret) return ret; @@ -177,6 +238,44 @@ int uclass_get_device(enum uclass_id id, int index, struct udevice **devp) return 0; } +int uclass_get_device(enum uclass_id id, int index, struct udevice **devp) +{ + struct udevice *dev; + int ret; + + *devp = NULL; + ret = uclass_find_device(id, index, &dev); + return uclass_get_device_tail(dev, ret, devp); +} + +int uclass_get_device_by_seq(enum uclass_id id, int seq, struct udevice **devp) +{ + struct udevice *dev; + int ret; + + *devp = NULL; + ret = uclass_find_device_by_seq(id, seq, false, &dev); + if (ret == -ENODEV) { + /* + * We didn't find it in probed devices. See if there is one + * that will request this seq if probed. + */ + ret = uclass_find_device_by_seq(id, seq, true, &dev); + } + return uclass_get_device_tail(dev, ret, devp); +} + +int uclass_get_device_by_of_offset(enum uclass_id id, int node, + struct udevice **devp) +{ + struct udevice *dev; + int ret; + + *devp = NULL; + ret = uclass_find_device_by_of_offset(id, node, &dev); + return uclass_get_device_tail(dev, ret, devp); +} + int uclass_first_device(enum uclass_id id, struct udevice **devp) { struct uclass *uc; @@ -254,6 +353,37 @@ int uclass_unbind_device(struct udevice *dev) return 0; } +int uclass_resolve_seq(struct udevice *dev) +{ + struct udevice *dup; + int seq; + int ret; + + assert(dev->seq == -1); + ret = uclass_find_device_by_seq(dev->uclass->uc_drv->id, dev->req_seq, + false, &dup); + if (!ret) { + dm_warn("Device '%s': seq %d is in use by '%s'\n", + dev->name, dev->req_seq, dup->name); + } else if (ret == -ENODEV) { + /* Our requested sequence number is available */ + if (dev->req_seq != -1) + return dev->req_seq; + } else { + return ret; + } + + for (seq = 0; seq < DM_MAX_SEQ; seq++) { + ret = uclass_find_device_by_seq(dev->uclass->uc_drv->id, seq, + false, &dup); + if (ret == -ENODEV) + break; + if (ret) + return ret; + } + return seq; +} + int uclass_post_probe_device(struct udevice *dev) { struct uclass_driver *uc_drv = dev->uclass->uc_drv; @@ -281,6 +411,7 @@ int uclass_pre_remove_device(struct udevice *dev) free(dev->uclass_priv); dev->uclass_priv = NULL; } + dev->seq = -1; return 0; } diff --git a/drivers/demo/demo-uclass.c b/drivers/demo/demo-uclass.c index 636fd8831f..f6510d602c 100644 --- a/drivers/demo/demo-uclass.c +++ b/drivers/demo/demo-uclass.c @@ -19,6 +19,7 @@ DECLARE_GLOBAL_DATA_PTR; UCLASS_DRIVER(demo) = { + .name = "demo", .id = UCLASS_DEMO, }; diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 4e001e12bd..aa11f15423 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -5,7 +5,9 @@ # SPDX-License-Identifier: GPL-2.0+ # +ifndef CONFIG_SPL_BUILD obj-$(CONFIG_DM_GPIO) += gpio-uclass.o +endif obj-$(CONFIG_AT91_GPIO) += at91_gpio.o obj-$(CONFIG_INTEL_ICH6_GPIO) += intel_ich6_gpio.o @@ -34,3 +36,4 @@ obj-$(CONFIG_XILINX_GPIO) += xilinx_gpio.o obj-$(CONFIG_ADI_GPIO2) += adi_gpio2.o obj-$(CONFIG_TCA642X) += tca642x.o oby-$(CONFIG_SX151X) += sx151x.o +obj-$(CONFIG_SUNXI_GPIO) += sunxi_gpio.o diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c new file mode 100644 index 0000000000..0c50a8f332 --- /dev/null +++ b/drivers/gpio/sunxi_gpio.c @@ -0,0 +1,102 @@ +/* + * (C) Copyright 2012 Henrik Nordstrom <henrik@henriknordstrom.net> + * + * Based on earlier arch/arm/cpu/armv7/sunxi/gpio.c: + * + * (C) Copyright 2007-2011 + * Allwinner Technology Co., Ltd. <www.allwinnertech.com> + * Tom Cubie <tangliang@allwinnertech.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/gpio.h> + +static int sunxi_gpio_output(u32 pin, u32 val) +{ + u32 dat; + u32 bank = GPIO_BANK(pin); + u32 num = GPIO_NUM(pin); + struct sunxi_gpio *pio = BANK_TO_GPIO(bank); + + dat = readl(&pio->dat); + if (val) + dat |= 0x1 << num; + else + dat &= ~(0x1 << num); + + writel(dat, &pio->dat); + + return 0; +} + +static int sunxi_gpio_input(u32 pin) +{ + u32 dat; + u32 bank = GPIO_BANK(pin); + u32 num = GPIO_NUM(pin); + struct sunxi_gpio *pio = BANK_TO_GPIO(bank); + + dat = readl(&pio->dat); + dat >>= num; + + return dat & 0x1; +} + +int gpio_request(unsigned gpio, const char *label) +{ + return 0; +} + +int gpio_free(unsigned gpio) +{ + return 0; +} + +int gpio_direction_input(unsigned gpio) +{ + sunxi_gpio_set_cfgpin(gpio, SUNXI_GPIO_INPUT); + + return sunxi_gpio_input(gpio); +} + +int gpio_direction_output(unsigned gpio, int value) +{ + sunxi_gpio_set_cfgpin(gpio, SUNXI_GPIO_OUTPUT); + + return sunxi_gpio_output(gpio, value); +} + +int gpio_get_value(unsigned gpio) +{ + return sunxi_gpio_input(gpio); +} + +int gpio_set_value(unsigned gpio, int value) +{ + return sunxi_gpio_output(gpio, value); +} + +int sunxi_name_to_gpio(const char *name) +{ + int group = 0; + int groupsize = 9 * 32; + long pin; + char *eptr; + if (*name == 'P' || *name == 'p') + name++; + if (*name >= 'A') { + group = *name - (*name > 'a' ? 'a' : 'A'); + groupsize = 32; + name++; + } + + pin = simple_strtol(name, &eptr, 10); + if (!*name || *eptr) + return -1; + if (pin < 0 || pin > groupsize || group >= 9) + return -1; + return group * 32 + pin; +} diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index e33586d8a6..416ea4f2c8 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -7,7 +7,6 @@ obj-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o obj-$(CONFIG_DW_I2C) += designware_i2c.o -obj-$(CONFIG_I2C_MVTWSI) += mvtwsi.o obj-$(CONFIG_I2C_MV) += mv_i2c.o obj-$(CONFIG_I2C_MXS) += mxs_i2c.o obj-$(CONFIG_PCA9564_I2C) += pca9564_i2c.o @@ -18,7 +17,9 @@ obj-$(CONFIG_SYS_I2C) += i2c_core.o obj-$(CONFIG_SYS_I2C_DAVINCI) += davinci_i2c.o obj-$(CONFIG_SYS_I2C_FSL) += fsl_i2c.o obj-$(CONFIG_SYS_I2C_FTI2C010) += fti2c010.o +obj-$(CONFIG_SYS_I2C_IHS) += ihs_i2c.o obj-$(CONFIG_SYS_I2C_KONA) += kona_i2c.o +obj-$(CONFIG_SYS_I2C_MVTWSI) += mvtwsi.o obj-$(CONFIG_SYS_I2C_MXC) += mxc_i2c.o obj-$(CONFIG_SYS_I2C_OMAP24XX) += omap24xx_i2c.o obj-$(CONFIG_SYS_I2C_OMAP34XX) += omap24xx_i2c.o diff --git a/drivers/i2c/fsl_i2c.c b/drivers/i2c/fsl_i2c.c index aa159f8d41..811033b0b8 100644 --- a/drivers/i2c/fsl_i2c.c +++ b/drivers/i2c/fsl_i2c.c @@ -46,10 +46,16 @@ DECLARE_GLOBAL_DATA_PTR; -static const struct fsl_i2c *i2c_dev[2] = { +static const struct fsl_i2c *i2c_dev[4] = { (struct fsl_i2c *)(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_I2C_OFFSET), #ifdef CONFIG_SYS_FSL_I2C2_OFFSET - (struct fsl_i2c *)(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_I2C2_OFFSET) + (struct fsl_i2c *)(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_I2C2_OFFSET), +#endif +#ifdef CONFIG_SYS_FSL_I2C3_OFFSET + (struct fsl_i2c *)(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_I2C3_OFFSET), +#endif +#ifdef CONFIG_SYS_FSL_I2C4_OFFSET + (struct fsl_i2c *)(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_I2C4_OFFSET) #endif }; @@ -539,3 +545,15 @@ U_BOOT_I2C_ADAP_COMPLETE(fsl_1, fsl_i2c_init, fsl_i2c_probe, fsl_i2c_read, CONFIG_SYS_FSL_I2C2_SPEED, CONFIG_SYS_FSL_I2C2_SLAVE, 1) #endif +#ifdef CONFIG_SYS_FSL_I2C3_OFFSET +U_BOOT_I2C_ADAP_COMPLETE(fsl_2, fsl_i2c_init, fsl_i2c_probe, fsl_i2c_read, + fsl_i2c_write, fsl_i2c_set_bus_speed, + CONFIG_SYS_FSL_I2C3_SPEED, CONFIG_SYS_FSL_I2C3_SLAVE, + 2) +#endif +#ifdef CONFIG_SYS_FSL_I2C4_OFFSET +U_BOOT_I2C_ADAP_COMPLETE(fsl_3, fsl_i2c_init, fsl_i2c_probe, fsl_i2c_read, + fsl_i2c_write, fsl_i2c_set_bus_speed, + CONFIG_SYS_FSL_I2C4_SPEED, CONFIG_SYS_FSL_I2C4_SLAVE, + 3) +#endif diff --git a/drivers/i2c/ihs_i2c.c b/drivers/i2c/ihs_i2c.c new file mode 100644 index 0000000000..fe66ce2a4a --- /dev/null +++ b/drivers/i2c/ihs_i2c.c @@ -0,0 +1,203 @@ +/* + * (C) Copyright 2013 + * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <i2c.h> +#include <gdsys_fpga.h> + +DECLARE_GLOBAL_DATA_PTR; + +enum { + I2CINT_ERROR_EV = 1 << 13, + I2CINT_TRANSMIT_EV = 1 << 14, + I2CINT_RECEIVE_EV = 1 << 15, +}; + +enum { + I2CMB_WRITE = 1 << 10, + I2CMB_2BYTE = 1 << 11, + I2CMB_HOLD_BUS = 1 << 13, + I2CMB_NATIVE = 2 << 14, +}; + +static int wait_for_int(bool read) +{ + u16 val; + unsigned int ctr = 0; + + FPGA_GET_REG(I2C_ADAP_HWNR, i2c.interrupt_status, &val); + while (!(val & (I2CINT_ERROR_EV + | (read ? I2CINT_RECEIVE_EV : I2CINT_TRANSMIT_EV)))) { + udelay(10); + if (ctr++ > 5000) { + return 1; + } + FPGA_GET_REG(I2C_ADAP_HWNR, i2c.interrupt_status, &val); + } + + return (val & I2CINT_ERROR_EV) ? 1 : 0; +} + +static int ihs_i2c_transfer(uchar chip, uchar *buffer, int len, bool read, + bool is_last) +{ + u16 val; + + FPGA_SET_REG(I2C_ADAP_HWNR, i2c.interrupt_status, I2CINT_ERROR_EV + | I2CINT_RECEIVE_EV | I2CINT_TRANSMIT_EV); + FPGA_GET_REG(I2C_ADAP_HWNR, i2c.interrupt_status, &val); + + if (!read && len) { + val = buffer[0]; + + if (len > 1) + val |= buffer[1] << 8; + FPGA_SET_REG(I2C_ADAP_HWNR, i2c.write_mailbox_ext, val); + } + + FPGA_SET_REG(I2C_ADAP_HWNR, i2c.write_mailbox, + I2CMB_NATIVE + | (read ? 0 : I2CMB_WRITE) + | (chip << 1) + | ((len > 1) ? I2CMB_2BYTE : 0) + | (is_last ? 0 : I2CMB_HOLD_BUS)); + + if (wait_for_int(read)) + return 1; + + if (read) { + FPGA_GET_REG(I2C_ADAP_HWNR, i2c.read_mailbox_ext, &val); + buffer[0] = val & 0xff; + if (len > 1) + buffer[1] = val >> 8; + } + + return 0; +} + +static int ihs_i2c_address(uchar chip, uint addr, int alen, bool hold_bus) +{ + int shift = (alen-1) * 8; + + while (alen) { + int transfer = MIN(alen, 2); + uchar buf[2]; + bool is_last = alen <= transfer; + + buf[0] = addr >> shift; + if (alen > 1) + buf[1] = addr >> (shift - 8); + + if (ihs_i2c_transfer(chip, buf, transfer, false, + hold_bus ? false : is_last)) + return 1; + + shift -= 16; + alen -= transfer; + } + + return 0; +} + +static int ihs_i2c_access(struct i2c_adapter *adap, uchar chip, uint addr, + int alen, uchar *buffer, int len, bool read) +{ + if (len <= 0) + return 1; + + if (ihs_i2c_address(chip, addr, alen, !read)) + return 1; + + while (len) { + int transfer = MIN(len, 2); + + if (ihs_i2c_transfer(chip, buffer, transfer, read, + len <= transfer)) + return 1; + + buffer += transfer; + addr += transfer; + len -= transfer; + } + + return 0; +} + + +static void ihs_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr) +{ +#ifdef CONFIG_SYS_I2C_INIT_BOARD + /* + * Call board specific i2c bus reset routine before accessing the + * environment, which might be in a chip on that bus. For details + * about this problem see doc/I2C_Edge_Conditions. + */ + i2c_init_board(); +#endif +} + +static int ihs_i2c_probe(struct i2c_adapter *adap, uchar chip) +{ + uchar buffer[2]; + + if (ihs_i2c_transfer(chip, buffer, 0, true, true)) + return 1; + + return 0; +} + +static int ihs_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, + int alen, uchar *buffer, int len) +{ + return ihs_i2c_access(adap, chip, addr, alen, buffer, len, true); +} + +static int ihs_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, + int alen, uchar *buffer, int len) +{ + return ihs_i2c_access(adap, chip, addr, alen, buffer, len, false); +} + +static unsigned int ihs_i2c_set_bus_speed(struct i2c_adapter *adap, + unsigned int speed) +{ + if (speed != adap->speed) + return 1; + return speed; +} + +/* + * Register IHS i2c adapters + */ +#ifdef CONFIG_SYS_I2C_IHS_CH0 +U_BOOT_I2C_ADAP_COMPLETE(ihs0, ihs_i2c_init, ihs_i2c_probe, + ihs_i2c_read, ihs_i2c_write, + ihs_i2c_set_bus_speed, + CONFIG_SYS_I2C_IHS_SPEED_0, + CONFIG_SYS_I2C_IHS_SLAVE_0, 0) +#endif +#ifdef CONFIG_SYS_I2C_IHS_CH1 +U_BOOT_I2C_ADAP_COMPLETE(ihs1, ihs_i2c_init, ihs_i2c_probe, + ihs_i2c_read, ihs_i2c_write, + ihs_i2c_set_bus_speed, + CONFIG_SYS_I2C_IHS_SPEED_1, + CONFIG_SYS_I2C_IHS_SLAVE_1, 1) +#endif +#ifdef CONFIG_SYS_I2C_IHS_CH2 +U_BOOT_I2C_ADAP_COMPLETE(ihs2, ihs_i2c_init, ihs_i2c_probe, + ihs_i2c_read, ihs_i2c_write, + ihs_i2c_set_bus_speed, + CONFIG_SYS_I2C_IHS_SPEED_2, + CONFIG_SYS_I2C_IHS_SLAVE_2, 2) +#endif +#ifdef CONFIG_SYS_I2C_IHS_CH3 +U_BOOT_I2C_ADAP_COMPLETE(ihs3, ihs_i2c_init, ihs_i2c_probe, + ihs_i2c_read, ihs_i2c_write, + ihs_i2c_set_bus_speed, + CONFIG_SYS_I2C_IHS_SPEED_3, + CONFIG_SYS_I2C_IHS_SLAVE_3, 3) +#endif diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c index 5ba0e03862..ab3ffa0fc1 100644 --- a/drivers/i2c/mvtwsi.c +++ b/drivers/i2c/mvtwsi.c @@ -22,6 +22,8 @@ #include <asm/arch/orion5x.h> #elif defined(CONFIG_KIRKWOOD) #include <asm/arch/kirkwood.h> +#elif defined(CONFIG_SUNXI) +#include <asm/arch/i2c.h> #else #error Driver mvtwsi not supported by SoC or board #endif @@ -30,6 +32,20 @@ * TWSI register structure */ +#ifdef CONFIG_SUNXI + +struct mvtwsi_registers { + u32 slave_address; + u32 xtnd_slave_addr; + u32 data; + u32 control; + u32 status; + u32 baudrate; + u32 soft_reset; +}; + +#else + struct mvtwsi_registers { u32 slave_address; u32 data; @@ -43,6 +59,8 @@ struct mvtwsi_registers { u32 soft_reset; }; +#endif + /* * Control register fields */ @@ -220,11 +238,10 @@ static int twsi_stop(int status) /* * Reset controller. - * Called at end of i2c_init unsuccessful i2c transactions. * Controller reset also resets the baud rate and slave address, so - * re-establish them. + * they must be re-established afterwards. */ -static void twsi_reset(u8 baud_rate, u8 slave_address) +static void twsi_reset(struct i2c_adapter *adap) { /* ensure controller will be enabled by any twsi*() function */ twsi_control_flags = MVTWSI_CONTROL_TWSIEN; @@ -232,23 +249,17 @@ static void twsi_reset(u8 baud_rate, u8 slave_address) writel(0, &twsi->soft_reset); /* wait 2 ms -- this is what the Marvell LSP does */ udelay(20000); - /* set baud rate */ - writel(baud_rate, &twsi->baudrate); - /* set slave address even though we don't use it */ - writel(slave_address, &twsi->slave_address); - writel(0, &twsi->xtnd_slave_addr); - /* assert STOP but don't care for the result */ - (void) twsi_stop(0); } /* * I2C init called by cmd_i2c when doing 'i2c reset'. * Sets baud to the highest possible value not exceeding requested one. */ -void i2c_init(int requested_speed, int slaveadd) +static unsigned int twsi_i2c_set_bus_speed(struct i2c_adapter *adap, + unsigned int requested_speed) { - int tmp_speed, highest_speed, n, m; - int baud = 0x44; /* baudrate at controller reset */ + unsigned int tmp_speed, highest_speed, n, m; + unsigned int baud = 0x44; /* baudrate at controller reset */ /* use actual speed to collect progressively higher values */ highest_speed = 0; @@ -263,8 +274,21 @@ void i2c_init(int requested_speed, int slaveadd) } } } + writel(baud, &twsi->baudrate); + return 0; +} + +static void twsi_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) +{ /* reset controller */ - twsi_reset(baud, slaveadd); + twsi_reset(adap); + /* set speed */ + twsi_i2c_set_bus_speed(adap, speed); + /* set slave address even though we don't use it */ + writel(slaveadd, &twsi->slave_address); + writel(0, &twsi->xtnd_slave_addr); + /* assert STOP but don't care for the result */ + (void) twsi_stop(0); } /* @@ -294,7 +318,7 @@ static int i2c_begin(int expected_start_status, u8 addr) * I2C probe called by cmd_i2c when doing 'i2c probe'. * Begin read, nak data byte, end. */ -int i2c_probe(uchar chip) +static int twsi_i2c_probe(struct i2c_adapter *adap, uchar chip) { u8 dummy_byte; int status; @@ -320,12 +344,13 @@ int i2c_probe(uchar chip) * cmd_eeprom, so we have to choose here, and for the moment that'll be * a repeated start without a preceding stop. */ -int i2c_read(u8 dev, uint addr, int alen, u8 *data, int length) +static int twsi_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, + int alen, uchar *data, int length) { int status; /* begin i2c write to send the address bytes */ - status = i2c_begin(MVTWSI_STATUS_START, (dev << 1)); + status = i2c_begin(MVTWSI_STATUS_START, (chip << 1)); /* send addr bytes */ while ((status == 0) && alen--) status = twsi_send(addr >> (8*alen), @@ -333,7 +358,7 @@ int i2c_read(u8 dev, uint addr, int alen, u8 *data, int length) /* begin i2c read to receive eeprom data bytes */ if (status == 0) status = i2c_begin( - MVTWSI_STATUS_REPEATED_START, (dev << 1) | 1); + MVTWSI_STATUS_REPEATED_START, (chip << 1) | 1); /* prepare ACK if at least one byte must be received */ if (length > 0) twsi_control_flags |= MVTWSI_CONTROL_ACK; @@ -355,12 +380,13 @@ int i2c_read(u8 dev, uint addr, int alen, u8 *data, int length) * I2C write called by cmd_i2c when doing 'i2c write' and by cmd_eeprom.c * Begin write, send address byte(s), send data bytes, end. */ -int i2c_write(u8 dev, uint addr, int alen, u8 *data, int length) +static int twsi_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, + int alen, uchar *data, int length) { int status; /* begin i2c write to send the eeprom adress bytes then data bytes */ - status = i2c_begin(MVTWSI_STATUS_START, (dev << 1)); + status = i2c_begin(MVTWSI_STATUS_START, (chip << 1)); /* send addr bytes */ while ((status == 0) && alen--) status = twsi_send(addr >> (8*alen), @@ -374,21 +400,7 @@ int i2c_write(u8 dev, uint addr, int alen, u8 *data, int length) return status; } -/* - * Bus set routine: we only support bus 0. - */ -int i2c_set_bus_num(unsigned int bus) -{ - if (bus > 0) { - return -1; - } - return 0; -} - -/* - * Bus get routine: hard-return bus 0. - */ -unsigned int i2c_get_bus_num(void) -{ - return 0; -} +U_BOOT_I2C_ADAP_COMPLETE(twsi0, twsi_i2c_init, twsi_i2c_probe, + twsi_i2c_read, twsi_i2c_write, + twsi_i2c_set_bus_speed, + CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 0) diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c index a39b5917ec..0f1e35c460 100644 --- a/drivers/i2c/omap24xx_i2c.c +++ b/drivers/i2c/omap24xx_i2c.c @@ -153,11 +153,60 @@ static uint omap24_i2c_setspeed(struct i2c_adapter *adap, uint speed) return 0; } + +static void omap24_i2c_deblock(struct i2c_adapter *adap) +{ + struct i2c *i2c_base = omap24_get_base(adap); + int i; + u16 systest; + u16 orgsystest; + + /* set test mode ST_EN = 1 */ + orgsystest = readw(&i2c_base->systest); + systest = orgsystest; + /* enable testmode */ + systest |= I2C_SYSTEST_ST_EN; + writew(systest, &i2c_base->systest); + systest &= ~I2C_SYSTEST_TMODE_MASK; + systest |= 3 << I2C_SYSTEST_TMODE_SHIFT; + writew(systest, &i2c_base->systest); + + /* set SCL, SDA = 1 */ + systest |= I2C_SYSTEST_SCL_O | I2C_SYSTEST_SDA_O; + writew(systest, &i2c_base->systest); + udelay(10); + + /* toggle scl 9 clocks */ + for (i = 0; i < 9; i++) { + /* SCL = 0 */ + systest &= ~I2C_SYSTEST_SCL_O; + writew(systest, &i2c_base->systest); + udelay(10); + /* SCL = 1 */ + systest |= I2C_SYSTEST_SCL_O; + writew(systest, &i2c_base->systest); + udelay(10); + } + + /* send stop */ + systest &= ~I2C_SYSTEST_SDA_O; + writew(systest, &i2c_base->systest); + udelay(10); + systest |= I2C_SYSTEST_SCL_O | I2C_SYSTEST_SDA_O; + writew(systest, &i2c_base->systest); + udelay(10); + + /* restore original mode */ + writew(orgsystest, &i2c_base->systest); +} + static void omap24_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) { struct i2c *i2c_base = omap24_get_base(adap); int timeout = I2C_TIMEOUT; + int deblock = 1; +retry: if (readw(&i2c_base->con) & I2C_CON_EN) { writew(0, &i2c_base->con); udelay(50000); @@ -194,6 +243,14 @@ static void omap24_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) udelay(1000); flush_fifo(adap); writew(0xFFFF, &i2c_base->stat); + + /* Handle possible failed I2C state */ + if (wait_for_bb(adap)) + if (deblock == 1) { + omap24_i2c_deblock(adap); + deblock = 0; + goto retry; + } } static void flush_fifo(struct i2c_adapter *adap) diff --git a/drivers/i2c/tegra_i2c.c b/drivers/i2c/tegra_i2c.c index 594e5ddeb4..257b72f0f7 100644 --- a/drivers/i2c/tegra_i2c.c +++ b/drivers/i2c/tegra_i2c.c @@ -110,7 +110,8 @@ static void i2c_init_controller(struct i2c_bus *i2c_bus) static void send_packet_headers( struct i2c_bus *i2c_bus, struct i2c_trans_info *trans, - u32 packet_id) + u32 packet_id, + bool end_with_repeated_start) { u32 data; @@ -132,6 +133,8 @@ static void send_packet_headers( /* Enable Read if it is not a write transaction */ if (!(trans->flags & I2C_IS_WRITE)) data |= PKT_HDR3_READ_MODE_MASK; + if (end_with_repeated_start) + data |= PKT_HDR3_REPEAT_START_MASK; /* Write I2C specific header */ writel(data, &i2c_bus->control->tx_fifo); @@ -209,7 +212,8 @@ static int send_recv_packets(struct i2c_bus *i2c_bus, int_status = readl(&control->int_status); writel(int_status, &control->int_status); - send_packet_headers(i2c_bus, trans, 1); + send_packet_headers(i2c_bus, trans, 1, + trans->flags & I2C_USE_REPEATED_START); words = DIV_ROUND_UP(trans->num_bytes, 4); last_bytes = trans->num_bytes & 3; @@ -220,14 +224,16 @@ static int send_recv_packets(struct i2c_bus *i2c_bus, if (is_write) { /* deal with word alignment */ - if ((unsigned)dptr & 3) { + if ((words == 1) && last_bytes) { + local = 0; + memcpy(&local, dptr, last_bytes); + } else if ((unsigned)dptr & 3) { memcpy(&local, dptr, sizeof(u32)); - writel(local, &control->tx_fifo); - debug("pkt data sent (0x%x)\n", local); } else { - writel(*wptr, &control->tx_fifo); - debug("pkt data sent (0x%x)\n", *wptr); + local = *wptr; } + writel(local, &control->tx_fifo); + debug("pkt data sent (0x%x)\n", local); if (!wait_for_tx_fifo_empty(control)) { error = -1; goto exit; @@ -267,7 +273,7 @@ exit: } static int tegra_i2c_write_data(struct i2c_bus *bus, u32 addr, u8 *data, - u32 len) + u32 len, bool end_with_repeated_start) { int error; struct i2c_trans_info trans_info; @@ -275,6 +281,8 @@ static int tegra_i2c_write_data(struct i2c_bus *bus, u32 addr, u8 *data, trans_info.address = addr; trans_info.buf = data; trans_info.flags = I2C_IS_WRITE; + if (end_with_repeated_start) + trans_info.flags |= I2C_USE_REPEATED_START; trans_info.num_bytes = len; trans_info.is_10bit_address = 0; @@ -463,7 +471,8 @@ static void tegra_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr) } /* i2c write version without the register address */ -int i2c_write_data(struct i2c_bus *bus, uchar chip, uchar *buffer, int len) +int i2c_write_data(struct i2c_bus *bus, uchar chip, uchar *buffer, int len, + bool end_with_repeated_start) { int rc; @@ -475,7 +484,8 @@ int i2c_write_data(struct i2c_bus *bus, uchar chip, uchar *buffer, int len) debug("\n"); /* Shift 7-bit address over for lower-level i2c functions */ - rc = tegra_i2c_write_data(bus, chip << 1, buffer, len); + rc = tegra_i2c_write_data(bus, chip << 1, buffer, len, + end_with_repeated_start); if (rc) debug("i2c_write_data(): rc=%d\n", rc); @@ -516,7 +526,7 @@ static int tegra_i2c_probe(struct i2c_adapter *adap, uchar chip) if (!bus) return 1; reg = 0; - rc = i2c_write_data(bus, chip, ®, 1); + rc = i2c_write_data(bus, chip, ®, 1, false); if (rc) { debug("Error probing 0x%x.\n", chip); return 1; @@ -538,8 +548,8 @@ static int tegra_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, uint offset; int i; - debug("i2c_read: chip=0x%x, addr=0x%x, len=0x%x\n", - chip, addr, len); + debug("i2c_read: chip=0x%x, addr=0x%x, alen=0x%x len=0x%x\n", + chip, addr, alen, len); bus = tegra_i2c_get_bus(adap); if (!bus) return 1; @@ -554,7 +564,7 @@ static int tegra_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, data[alen - i - 1] = (addr + offset) >> (8 * i); } - if (i2c_write_data(bus, chip, data, alen)) { + if (i2c_write_data(bus, chip, data, alen, true)) { debug("i2c_read: error sending (0x%x)\n", addr); return 1; @@ -577,8 +587,8 @@ static int tegra_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, uint offset; int i; - debug("i2c_write: chip=0x%x, addr=0x%x, len=0x%x\n", - chip, addr, len); + debug("i2c_write: chip=0x%x, addr=0x%x, alen=0x%x len=0x%x\n", + chip, addr, alen, len); bus = tegra_i2c_get_bus(adap); if (!bus) return 1; @@ -591,7 +601,7 @@ static int tegra_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, for (i = 0; i < alen; i++) data[alen - i - 1] = (addr + offset) >> (8 * i); data[alen] = buffer[offset]; - if (i2c_write_data(bus, chip, data, alen + 1)) { + if (i2c_write_data(bus, chip, data, alen + 1, false)) { debug("i2c_write: error sending (0x%x)\n", addr); return 1; } diff --git a/drivers/input/cros_ec_keyb.c b/drivers/input/cros_ec_keyb.c index a2501e0206..47502b1763 100644 --- a/drivers/input/cros_ec_keyb.c +++ b/drivers/input/cros_ec_keyb.c @@ -93,7 +93,7 @@ static int check_for_keys(struct keyb *config, * * @return 0 if no keys available, 1 if keys are available */ -static int kbd_tstc(void) +static int kbd_tstc(struct stdio_dev *dev) { /* Just get input to do this for us */ return config.inited ? input_tstc(&config.input) : 0; @@ -104,7 +104,7 @@ static int kbd_tstc(void) * * @return ASCII key code, or 0 if no key, or -1 if error */ -static int kbd_getc(void) +static int kbd_getc(struct stdio_dev *dev) { /* Just get input to do this for us */ return config.inited ? input_getc(&config.input) : 0; @@ -214,7 +214,7 @@ static int cros_ec_keyb_decode_fdt(const void *blob, int node, * * @return 0 if ok, -1 on error */ -static int cros_ec_init_keyboard(void) +static int cros_ec_init_keyboard(struct stdio_dev *dev) { const void *blob = gd->fdt_blob; int node; diff --git a/drivers/input/i8042.c b/drivers/input/i8042.c index 35fa0bb504..ca1604c540 100644 --- a/drivers/input/i8042.c +++ b/drivers/input/i8042.c @@ -398,7 +398,7 @@ int i8042_kbd_init(void) * i8042_tstc - test if keyboard input is available * option: cursor blinking if called in a loop */ -int i8042_tstc(void) +int i8042_tstc(struct stdio_dev *dev) { unsigned char scan_code = 0; @@ -432,7 +432,7 @@ int i8042_tstc(void) * i8042_getc - wait till keyboard input is available * option: turn on/off cursor while waiting */ -int i8042_getc(void) +int i8042_getc(struct stdio_dev *dev) { int ret_chr; unsigned char scan_code; diff --git a/drivers/input/keyboard.c b/drivers/input/keyboard.c index 614592ef3c..be0f3330db 100644 --- a/drivers/input/keyboard.c +++ b/drivers/input/keyboard.c @@ -70,7 +70,7 @@ static void kbd_put_queue(char data) } /* test if a character is in the queue */ -static int kbd_testc(void) +static int kbd_testc(struct stdio_dev *dev) { #if defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555) /* no ISR is used, so received chars must be polled */ @@ -83,7 +83,7 @@ static int kbd_testc(void) } /* gets the character from the queue */ -static int kbd_getc(void) +static int kbd_getc(struct stdio_dev *dev) { char c; while(in_pointer==out_pointer) { @@ -275,8 +275,6 @@ int kbd_init (void) memset (&kbddev, 0, sizeof(kbddev)); strcpy(kbddev.name, DEVNAME); kbddev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM; - kbddev.putc = NULL ; - kbddev.puts = NULL ; kbddev.getc = kbd_getc ; kbddev.tstc = kbd_testc ; diff --git a/drivers/input/tegra-kbc.c b/drivers/input/tegra-kbc.c index f137f930a9..7e36db0a71 100644 --- a/drivers/input/tegra-kbc.c +++ b/drivers/input/tegra-kbc.c @@ -194,7 +194,7 @@ int tegra_kbc_check(struct input_config *input) * * @return 0 if no keys available, 1 if keys are available */ -static int kbd_tstc(void) +static int kbd_tstc(struct stdio_dev *dev) { /* Just get input to do this for us */ return input_tstc(&config.input); @@ -207,7 +207,7 @@ static int kbd_tstc(void) * * @return ASCII key code, or 0 if no key, or -1 if error */ -static int kbd_getc(void) +static int kbd_getc(struct stdio_dev *dev) { /* Just get input to do this for us */ return input_getc(&config.input); @@ -289,7 +289,7 @@ static void tegra_kbc_open(void) * * @return 0 if ok, -ve on error */ -static int init_tegra_keyboard(void) +static int init_tegra_keyboard(struct stdio_dev *dev) { /* check if already created */ if (config.created) diff --git a/drivers/misc/cbmem_console.c b/drivers/misc/cbmem_console.c index 80a84fdf8f..5f85ccf21e 100644 --- a/drivers/misc/cbmem_console.c +++ b/drivers/misc/cbmem_console.c @@ -31,7 +31,7 @@ struct cbmem_console { static struct cbmem_console *cbmem_console_p; -void cbmemc_putc(char data) +void cbmemc_putc(struct stdio_dev *dev, char data) { int cursor; @@ -40,12 +40,12 @@ void cbmemc_putc(char data) cbmem_console_p->buffer_body[cursor] = data; } -void cbmemc_puts(const char *str) +void cbmemc_puts(struct stdio_dev *dev, const char *str) { char c; while ((c = *str++) != 0) - cbmemc_putc(c); + cbmemc_putc(dev, c); } int cbmemc_init(void) diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index b5477b1271..a26f3cec20 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -21,7 +21,7 @@ static struct list_head mmc_devices; static int cur_dev_num = -1; -int __weak board_mmc_getwp(struct mmc *mmc) +__weak int board_mmc_getwp(struct mmc *mmc) { return -1; } @@ -42,13 +42,11 @@ int mmc_getwp(struct mmc *mmc) return wp; } -int __board_mmc_getcd(struct mmc *mmc) { +__weak int board_mmc_getcd(struct mmc *mmc) +{ return -1; } -int board_mmc_getcd(struct mmc *mmc)__attribute__((weak, - alias("__board_mmc_getcd"))); - int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { int ret; @@ -377,7 +375,7 @@ static int mmc_send_op_cond_iter(struct mmc *mmc, struct mmc_cmd *cmd, return 0; } -int mmc_send_op_cond(struct mmc *mmc) +static int mmc_send_op_cond(struct mmc *mmc) { struct mmc_cmd cmd; int err, i; @@ -399,7 +397,7 @@ int mmc_send_op_cond(struct mmc *mmc) return IN_PROGRESS; } -int mmc_complete_op_cond(struct mmc *mmc) +static int mmc_complete_op_cond(struct mmc *mmc) { struct mmc_cmd cmd; int timeout = 1000; @@ -1371,17 +1369,17 @@ int mmc_set_dsr(struct mmc *mmc, u16 val) return 0; } -/* - * CPU and board-specific MMC initializations. Aliased function - * signals caller to move on - */ -static int __def_mmc_init(bd_t *bis) +/* CPU-specific MMC initializations */ +__weak int cpu_mmc_init(bd_t *bis) { return -1; } -int cpu_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init"))); -int board_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init"))); +/* board-specific MMC initializations. */ +__weak int board_mmc_init(bd_t *bis) +{ + return -1; +} #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index 17cbb0983d..5b0c302069 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -120,7 +120,7 @@ static void omap5_pbias_config(struct mmc *mmc) } #endif -unsigned char mmc_board_init(struct mmc *mmc) +static unsigned char mmc_board_init(struct mmc *mmc) { #if defined(CONFIG_OMAP34XX) t2_t *t2_base = (t2_t *)T2_BASE; diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index eb7b1158d6..d4e574fe19 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -16,28 +16,6 @@ #include <asm/arch/cpu.h> #include <asm/arch/mmc.h> -struct sunxi_mmc_des { - u32 reserved1_1:1; - u32 dic:1; /* disable interrupt on completion */ - u32 last_des:1; /* 1-this data buffer is the last buffer */ - u32 first_des:1; /* 1-data buffer is the first buffer, - 0-data buffer contained in the next - descriptor is 1st buffer */ - u32 des_chain:1; /* 1-the 2nd address in the descriptor is the - next descriptor address */ - u32 end_of_ring:1; /* 1-last descriptor flag when using dual - data buffer in descriptor */ - u32 reserved1_2:24; - u32 card_err_sum:1; /* transfer error flag */ - u32 own:1; /* des owner:1-idma owns it, 0-host owns it */ -#define SDXC_DES_NUM_SHIFT 16 -#define SDXC_DES_BUFFER_MAX_LEN (1 << SDXC_DES_NUM_SHIFT) - u32 data_buf1_sz:16; - u32 data_buf2_sz:16; - u32 buf_addr_ptr1; - u32 buf_addr_ptr2; -}; - struct sunxi_mmc_host { unsigned mmc_no; uint32_t *mclkreg; @@ -189,6 +167,7 @@ static int mmc_core_init(struct mmc *mmc) /* Reset controller */ writel(SUNXI_MMC_GCTRL_RESET, &mmchost->reg->gctrl); + udelay(1000); return 0; } @@ -204,6 +183,9 @@ static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data) unsigned timeout_msecs = 2000; unsigned *buff = (unsigned int *)(reading ? data->dest : data->src); + /* Always read / write data through the CPU */ + setbits_le32(&mmchost->reg->gctrl, SUNXI_MMC_GCTRL_ACCESS_BY_AHB); + for (i = 0; i < (byte_cnt >> 2); i++) { while (readl(&mmchost->reg->status) & status_bit) { if (!timeout_msecs--) @@ -220,85 +202,6 @@ static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data) return 0; } -static int mmc_trans_data_by_dma(struct mmc *mmc, struct mmc_data *data) -{ - struct sunxi_mmc_host *mmchost = mmc->priv; - unsigned byte_cnt = data->blocksize * data->blocks; - unsigned char *buff; - unsigned des_idx = 0; - unsigned buff_frag_num = - (byte_cnt + SDXC_DES_BUFFER_MAX_LEN - 1) >> SDXC_DES_NUM_SHIFT; - unsigned remain; - unsigned i, rval; - ALLOC_CACHE_ALIGN_BUFFER(struct sunxi_mmc_des, pdes, buff_frag_num); - - buff = data->flags & MMC_DATA_READ ? - (unsigned char *)data->dest : (unsigned char *)data->src; - remain = byte_cnt & (SDXC_DES_BUFFER_MAX_LEN - 1); - - flush_cache((unsigned long)buff, (unsigned long)byte_cnt); - for (i = 0; i < buff_frag_num; i++, des_idx++) { - memset((void *)&pdes[des_idx], 0, sizeof(struct sunxi_mmc_des)); - pdes[des_idx].des_chain = 1; - pdes[des_idx].own = 1; - pdes[des_idx].dic = 1; - if (buff_frag_num > 1 && i != buff_frag_num - 1) - pdes[des_idx].data_buf1_sz = 0; /* 0 == max_len */ - else - pdes[des_idx].data_buf1_sz = remain; - - pdes[des_idx].buf_addr_ptr1 = - (u32) buff + i * SDXC_DES_BUFFER_MAX_LEN; - if (i == 0) - pdes[des_idx].first_des = 1; - - if (i == buff_frag_num - 1) { - pdes[des_idx].dic = 0; - pdes[des_idx].last_des = 1; - pdes[des_idx].end_of_ring = 1; - pdes[des_idx].buf_addr_ptr2 = 0; - } else { - pdes[des_idx].buf_addr_ptr2 = (u32)&pdes[des_idx + 1]; - } - } - flush_cache((unsigned long)pdes, - sizeof(struct sunxi_mmc_des) * (des_idx + 1)); - - rval = readl(&mmchost->reg->gctrl); - /* Enable DMA */ - writel(rval | SUNXI_MMC_GCTRL_DMA_RESET | SUNXI_MMC_GCTRL_DMA_ENABLE, - &mmchost->reg->gctrl); - /* Reset iDMA */ - writel(SUNXI_MMC_IDMAC_RESET, &mmchost->reg->dmac); - /* Enable iDMA */ - writel(SUNXI_MMC_IDMAC_FIXBURST | SUNXI_MMC_IDMAC_ENABLE, - &mmchost->reg->dmac); - rval = readl(&mmchost->reg->idie) & - ~(SUNXI_MMC_IDIE_TXIRQ|SUNXI_MMC_IDIE_RXIRQ); - if (data->flags & MMC_DATA_WRITE) - rval |= SUNXI_MMC_IDIE_TXIRQ; - else - rval |= SUNXI_MMC_IDIE_RXIRQ; - writel(rval, &mmchost->reg->idie); - writel((u32) pdes, &mmchost->reg->dlba); - writel((0x2 << 28) | (0x7 << 16) | (0x01 << 3), - &mmchost->reg->ftrglevel); - - return 0; -} - -static void mmc_enable_dma_accesses(struct mmc *mmc, int dma) -{ - struct sunxi_mmc_host *mmchost = mmc->priv; - - unsigned int gctrl = readl(&mmchost->reg->gctrl); - if (dma) - gctrl &= ~SUNXI_MMC_GCTRL_ACCESS_BY_AHB; - else - gctrl |= SUNXI_MMC_GCTRL_ACCESS_BY_AHB; - writel(gctrl, &mmchost->reg->gctrl); -} - static int mmc_rint_wait(struct mmc *mmc, unsigned int timeout_msecs, unsigned int done_bit, const char *what) { @@ -327,7 +230,6 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, unsigned int timeout_msecs; int error = 0; unsigned int status = 0; - unsigned int usedma = 0; unsigned int bytecnt = 0; if (mmchost->fatal_err) @@ -378,20 +280,8 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, bytecnt = data->blocksize * data->blocks; debug("trans data %d bytes\n", bytecnt); -#if defined(CONFIG_MMC_SUNXI_USE_DMA) && !defined(CONFIG_SPL_BUILD) - if (bytecnt > 64) { -#else - if (0) { -#endif - usedma = 1; - mmc_enable_dma_accesses(mmc, 1); - ret = mmc_trans_data_by_dma(mmc, data); - writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd); - } else { - mmc_enable_dma_accesses(mmc, 0); - writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd); - ret = mmc_trans_data_by_cpu(mmc, data); - } + writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd); + ret = mmc_trans_data_by_cpu(mmc, data); if (ret) { error = readl(&mmchost->reg->rint) & \ SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT; @@ -405,7 +295,7 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, goto out; if (data) { - timeout_msecs = usedma ? 120 * bytecnt : 120; + timeout_msecs = 120; debug("cacl timeout %x msec\n", timeout_msecs); error = mmc_rint_wait(mmc, timeout_msecs, data->blocks > 1 ? @@ -442,23 +332,6 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, debug("mmc resp 0x%08x\n", cmd->response[0]); } out: - if (data && usedma) { - /* IDMASTAREG - * IDST[0] : idma tx int - * IDST[1] : idma rx int - * IDST[2] : idma fatal bus error - * IDST[4] : idma descriptor invalid - * IDST[5] : idma error summary - * IDST[8] : idma normal interrupt sumary - * IDST[9] : idma abnormal interrupt sumary - */ - status = readl(&mmchost->reg->idst); - writel(status, &mmchost->reg->idst); - writel(0, &mmchost->reg->idie); - writel(0, &mmchost->reg->dmac); - writel(readl(&mmchost->reg->gctrl) & ~SUNXI_MMC_GCTRL_DMA_ENABLE, - &mmchost->reg->gctrl); - } if (error < 0) { writel(SUNXI_MMC_GCTRL_RESET, &mmchost->reg->gctrl); mmc_update_clk(mmc); diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index a389cd101c..c4b5bc1de5 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -2360,7 +2360,7 @@ unsigned long flash_init (void) #endif /* CONFIG_SYS_FLASH_QUIET_TEST */ } #ifdef CONFIG_SYS_FLASH_PROTECTION - else if ((s != NULL) && (strcmp(s, "yes") == 0)) { + else if (strcmp(s, "yes") == 0) { /* * Only the U-Boot image and it's environment * is protected, all other sectors are diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 6226cb259f..7cc6b6fc08 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_DNET) += dnet.o obj-$(CONFIG_E1000) += e1000.o obj-$(CONFIG_E1000_SPI) += e1000_spi.o obj-$(CONFIG_EEPRO100) += eepro100.o +obj-$(CONFIG_SUNXI_EMAC) += sunxi_emac.o obj-$(CONFIG_ENC28J60) += enc28j60.o obj-$(CONFIG_EP93XX) += ep93xx_eth.o obj-$(CONFIG_ETHOC) += ethoc.o @@ -51,7 +52,6 @@ obj-$(CONFIG_RTL8169) += rtl8169.o obj-$(CONFIG_SH_ETHER) += sh_eth.o obj-$(CONFIG_SMC91111) += smc91111.o obj-$(CONFIG_SMC911X) += smc911x.o -obj-$(CONFIG_SUNXI_WEMAC) += sunxi_wemac.o obj-$(CONFIG_DRIVER_TI_EMAC) += davinci_emac.o obj-$(CONFIG_TSEC_ENET) += tsec.o fsl_mdio.o obj-$(CONFIG_DRIVER_TI_CPSW) += cpsw.o diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 65c747e14b..623f7492c7 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -215,7 +215,7 @@ static void nc_send_packet(const char *buf, int len) } } -static int nc_start(void) +static int nc_start(struct stdio_dev *dev) { int retval; @@ -235,7 +235,7 @@ static int nc_start(void) return 0; } -static void nc_putc(char c) +static void nc_putc(struct stdio_dev *dev, char c) { if (output_recursion) return; @@ -246,7 +246,7 @@ static void nc_putc(char c) output_recursion = 0; } -static void nc_puts(const char *s) +static void nc_puts(struct stdio_dev *dev, const char *s) { int len; @@ -265,7 +265,7 @@ static void nc_puts(const char *s) output_recursion = 0; } -static int nc_getc(void) +static int nc_getc(struct stdio_dev *dev) { uchar c; @@ -286,7 +286,7 @@ static int nc_getc(void) return c; } -static int nc_tstc(void) +static int nc_tstc(struct stdio_dev *dev) { struct eth_device *eth; diff --git a/drivers/net/sunxi_wemac.c b/drivers/net/sunxi_emac.c index 699a381582..5a06d68af7 100644 --- a/drivers/net/sunxi_wemac.c +++ b/drivers/net/sunxi_emac.c @@ -1,5 +1,5 @@ /* - * sunxi_wemac.c -- Allwinner A10 ethernet driver + * sunxi_emac.c -- Allwinner A10 ethernet driver * * (C) Copyright 2012, Stefan Roese <sr@denx.de> * @@ -7,16 +7,16 @@ */ #include <common.h> +#include <linux/err.h> #include <malloc.h> -#include <net.h> #include <miiphy.h> -#include <linux/err.h> +#include <net.h> #include <asm/io.h> #include <asm/arch/clock.h> #include <asm/arch/gpio.h> /* EMAC register */ -struct wemac_regs { +struct emac_regs { u32 ctl; /* 0x00 */ u32 tx_mode; /* 0x04 */ u32 tx_flow; /* 0x08 */ @@ -27,7 +27,7 @@ struct wemac_regs { u32 tx_pl1; /* 0x1c */ u32 tx_sta; /* 0x20 */ u32 tx_io_data; /* 0x24 */ - u32 tx_io_data1; /* 0x28 */ + u32 tx_io_data1;/* 0x28 */ u32 tx_tsvl0; /* 0x2c */ u32 tx_tsvh0; /* 0x30 */ u32 tx_tsvl1; /* 0x34 */ @@ -141,33 +141,33 @@ struct sunxi_sramc_regs { #define EMAC_MAC_IPGT 0x15 -#define EMAC_MAC_NBTB_IPG1 0xC +#define EMAC_MAC_NBTB_IPG1 0xc #define EMAC_MAC_NBTB_IPG2 0x12 #define EMAC_MAC_CW 0x37 -#define EMAC_MAC_RM 0xF +#define EMAC_MAC_RM 0xf #define EMAC_MAC_MFL 0x0600 /* Receive status */ -#define EMAC_CRCERR (1 << 4) -#define EMAC_LENERR (3 << 5) +#define EMAC_CRCERR (0x1 << 4) +#define EMAC_LENERR (0x3 << 5) #define DMA_CPU_TRRESHOLD 2000 -struct wemac_eth_dev { +struct emac_eth_dev { u32 speed; u32 duplex; u32 phy_configured; int link_printed; }; -struct wemac_rxhdr { +struct emac_rxhdr { s16 rx_len; u16 rx_status; }; -static void wemac_inblk_32bit(void *reg, void *data, int count) +static void emac_inblk_32bit(void *reg, void *data, int count) { int cnt = (count + 3) >> 2; @@ -181,7 +181,7 @@ static void wemac_inblk_32bit(void *reg, void *data, int count) } } -static void wemac_outblk_32bit(void *reg, void *data, int count) +static void emac_outblk_32bit(void *reg, void *data, int count) { int cnt = (count + 3) >> 2; @@ -194,14 +194,12 @@ static void wemac_outblk_32bit(void *reg, void *data, int count) } } -/* - * Read a word from phyxcer - */ -static int wemac_phy_read(const char *devname, unsigned char addr, +/* Read a word from phyxcer */ +static int emac_phy_read(const char *devname, unsigned char addr, unsigned char reg, unsigned short *value) { struct eth_device *dev = eth_get_dev_by_name(devname); - struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; + struct emac_regs *regs = (struct emac_regs *)dev->iobase; /* issue the phy address and reg */ writel(addr << 8 | reg, ®s->mac_madr); @@ -221,14 +219,12 @@ static int wemac_phy_read(const char *devname, unsigned char addr, return 0; } -/* - * Write a word to phyxcer - */ -static int wemac_phy_write(const char *devname, unsigned char addr, +/* Write a word to phyxcer */ +static int emac_phy_write(const char *devname, unsigned char addr, unsigned char reg, unsigned short value) { struct eth_device *dev = eth_get_dev_by_name(devname); - struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; + struct emac_regs *regs = (struct emac_regs *)dev->iobase; /* issue the phy address and reg */ writel(addr << 8 | reg, ®s->mac_madr); @@ -250,7 +246,7 @@ static int wemac_phy_write(const char *devname, unsigned char addr, static void emac_setup(struct eth_device *dev) { - struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; + struct emac_regs *regs = (struct emac_regs *)dev->iobase; u32 reg_val; u16 phy_val; u32 duplex_flag; @@ -266,7 +262,7 @@ static void emac_setup(struct eth_device *dev) writel(EMAC_MAC_CTL0_SETUP, ®s->mac_ctl0); /* Set MAC CTL1 */ - wemac_phy_read(dev->name, 1, 0, &phy_val); + emac_phy_read(dev->name, 1, 0, &phy_val); debug("PHY SETUP, reg 0 value: %x\n", phy_val); duplex_flag = !!(phy_val & (1 << 8)); @@ -288,9 +284,9 @@ static void emac_setup(struct eth_device *dev) writel(EMAC_MAC_MFL, ®s->mac_maxf); } -static void wemac_reset(struct eth_device *dev) +static void emac_reset(struct eth_device *dev) { - struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; + struct emac_regs *regs = (struct emac_regs *)dev->iobase; debug("resetting device\n"); @@ -302,10 +298,10 @@ static void wemac_reset(struct eth_device *dev) udelay(200); } -static int sunxi_wemac_eth_init(struct eth_device *dev, bd_t *bd) +static int sunxi_emac_eth_init(struct eth_device *dev, bd_t *bd) { - struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; - struct wemac_eth_dev *priv = dev->priv; + struct emac_regs *regs = (struct emac_regs *)dev->iobase; + struct emac_eth_dev *priv = dev->priv; u16 phy_reg; /* Init EMAC */ @@ -317,10 +313,7 @@ static int sunxi_wemac_eth_init(struct eth_device *dev, bd_t *bd) /* Init MAC */ /* Soft reset MAC */ - clrbits_le32(®s->mac_ctl0, 1 << 15); - - /* Set MII clock */ - clrsetbits_le32(®s->mac_mcfg, 0xf << 2, 0xd << 2); + clrbits_le32(®s->mac_ctl0, 0x1 << 15); /* Clear RX counter */ writel(0x0, ®s->rx_fbc); @@ -336,14 +329,14 @@ static int sunxi_wemac_eth_init(struct eth_device *dev, bd_t *bd) mdelay(1); - wemac_reset(dev); + emac_reset(dev); /* PHY POWER UP */ - wemac_phy_read(dev->name, 1, 0, &phy_reg); - wemac_phy_write(dev->name, 1, 0, phy_reg & (~(1 << 11))); + emac_phy_read(dev->name, 1, 0, &phy_reg); + emac_phy_write(dev->name, 1, 0, phy_reg & (~(0x1 << 11))); mdelay(1); - wemac_phy_read(dev->name, 1, 0, &phy_reg); + emac_phy_read(dev->name, 1, 0, &phy_reg); priv->speed = miiphy_speed(dev->name, 0); priv->duplex = miiphy_duplex(dev->name, 0); @@ -357,11 +350,11 @@ static int sunxi_wemac_eth_init(struct eth_device *dev, bd_t *bd) /* Set EMAC SPEED depend on PHY */ clrsetbits_le32(®s->mac_supp, 1 << 8, - ((phy_reg & (1 << 13)) >> 13) << 8); + ((phy_reg & (0x1 << 13)) >> 13) << 8); /* Set duplex depend on phy */ clrsetbits_le32(®s->mac_ctl1, 1 << 0, - ((phy_reg & (1 << 8)) >> 8) << 0); + ((phy_reg & (0x1 << 8)) >> 8) << 0); /* Enable RX/TX */ setbits_le32(®s->ctl, 0x7); @@ -369,15 +362,15 @@ static int sunxi_wemac_eth_init(struct eth_device *dev, bd_t *bd) return 0; } -static void sunxi_wemac_eth_halt(struct eth_device *dev) +static void sunxi_emac_eth_halt(struct eth_device *dev) { /* Nothing to do here */ } -static int sunxi_wemac_eth_recv(struct eth_device *dev) +static int sunxi_emac_eth_recv(struct eth_device *dev) { - struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; - struct wemac_rxhdr rxhdr; + struct emac_regs *regs = (struct emac_regs *)dev->iobase; + struct emac_rxhdr rxhdr; u32 rxcount; u32 reg_val; int rx_len; @@ -386,8 +379,7 @@ static int sunxi_wemac_eth_recv(struct eth_device *dev) /* Check packet ready or not */ - /* - * Race warning: The first packet might arrive with + /* Race warning: The first packet might arrive with * the interrupts disabled, but the second will fix */ rxcount = readl(®s->rx_fbc); @@ -401,26 +393,25 @@ static int sunxi_wemac_eth_recv(struct eth_device *dev) reg_val = readl(®s->rx_io_data); if (reg_val != 0x0143414d) { /* Disable RX */ - clrbits_le32(®s->ctl, 1 << 2); + clrbits_le32(®s->ctl, 0x1 << 2); /* Flush RX FIFO */ - setbits_le32(®s->rx_ctl, 1 << 3); - while (readl(®s->rx_ctl) & (1 << 3)) + setbits_le32(®s->rx_ctl, 0x1 << 3); + while (readl(®s->rx_ctl) & (0x1 << 3)) ; /* Enable RX */ - setbits_le32(®s->ctl, 1 << 2); + setbits_le32(®s->ctl, 0x1 << 2); return 0; } - /* - * A packet ready now + /* A packet ready now * Get status/length */ good_packet = 1; - wemac_inblk_32bit(®s->rx_io_data, &rxhdr, sizeof(rxhdr)); + emac_inblk_32bit(®s->rx_io_data, &rxhdr, sizeof(rxhdr)); rx_len = rxhdr.rx_len; rx_status = rxhdr.rx_status; @@ -440,13 +431,13 @@ static int sunxi_wemac_eth_recv(struct eth_device *dev) printf("length error\n"); } - /* Move data from WEMAC */ + /* Move data from EMAC */ if (good_packet) { if (rx_len > DMA_CPU_TRRESHOLD) { printf("Received packet is too big (len=%d)\n", rx_len); } else { - wemac_inblk_32bit((void *)®s->rx_io_data, - NetRxPackets[0], rx_len); + emac_inblk_32bit((void *)®s->rx_io_data, + NetRxPackets[0], rx_len); /* Pass to upper layer */ NetReceive(NetRxPackets[0], rx_len); @@ -457,15 +448,15 @@ static int sunxi_wemac_eth_recv(struct eth_device *dev) return 0; } -static int sunxi_wemac_eth_send(struct eth_device *dev, void *packet, int len) +static int sunxi_emac_eth_send(struct eth_device *dev, void *packet, int len) { - struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; + struct emac_regs *regs = (struct emac_regs *)dev->iobase; /* Select channel 0 */ writel(0, ®s->tx_ins); /* Write packet */ - wemac_outblk_32bit((void *)®s->tx_io_data, packet, len); + emac_outblk_32bit((void *)®s->tx_io_data, packet, len); /* Set TX len */ writel(len, ®s->tx_pl0); @@ -476,50 +467,55 @@ static int sunxi_wemac_eth_send(struct eth_device *dev, void *packet, int len) return 0; } -int sunxi_wemac_initialize(void) +int sunxi_emac_initialize(void) { struct sunxi_ccm_reg *const ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; struct sunxi_sramc_regs *sram = (struct sunxi_sramc_regs *)SUNXI_SRAMC_BASE; + struct emac_regs *regs = + (struct emac_regs *)SUNXI_EMAC_BASE; struct eth_device *dev; - struct wemac_eth_dev *priv; + struct emac_eth_dev *priv; int pin; dev = malloc(sizeof(*dev)); if (dev == NULL) return -ENOMEM; - priv = (struct wemac_eth_dev *)malloc(sizeof(struct wemac_eth_dev)); + priv = (struct emac_eth_dev *)malloc(sizeof(struct emac_eth_dev)); if (!priv) { free(dev); return -ENOMEM; } memset(dev, 0, sizeof(*dev)); - memset(priv, 0, sizeof(struct wemac_eth_dev)); + memset(priv, 0, sizeof(struct emac_eth_dev)); /* Map SRAM to EMAC */ setbits_le32(&sram->ctrl1, 0x5 << 2); /* Configure pin mux settings for MII Ethernet */ for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(17); pin++) - sunxi_gpio_set_cfgpin(pin, 2); + sunxi_gpio_set_cfgpin(pin, SUNXI_GPA0_EMAC); /* Set up clock gating */ - setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_EMAC); + setbits_le32(&ccm->ahb_gate0, 0x1 << AHB_GATE_OFFSET_EMAC); + + /* Set MII clock */ + clrsetbits_le32(®s->mac_mcfg, 0xf << 2, 0xd << 2); - dev->iobase = SUNXI_EMAC_BASE; + dev->iobase = (int)regs; dev->priv = priv; - dev->init = sunxi_wemac_eth_init; - dev->halt = sunxi_wemac_eth_halt; - dev->send = sunxi_wemac_eth_send; - dev->recv = sunxi_wemac_eth_recv; - strcpy(dev->name, "wemac"); + dev->init = sunxi_emac_eth_init; + dev->halt = sunxi_emac_eth_halt; + dev->send = sunxi_emac_eth_send; + dev->recv = sunxi_emac_eth_recv; + strcpy(dev->name, "emac"); eth_register(dev); - miiphy_register(dev->name, wemac_phy_read, wemac_phy_write); + miiphy_register(dev->name, emac_phy_read, emac_phy_write); return 0; } diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index ae3cafbea4..91821f4c77 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile @@ -7,7 +7,6 @@ obj-$(CONFIG_I82365) += i82365.o obj-$(CONFIG_8xx) += mpc8xx_pcmcia.o -obj-y += rpx_pcmcia.o obj-$(CONFIG_IDE_TI_CARDBUS) += ti_pci1410a.o obj-y += tqm8xx_pcmcia.o obj-$(CONFIG_MARUBUN_PCCARD) += marubun_pcmcia.o diff --git a/drivers/pcmcia/mpc8xx_pcmcia.c b/drivers/pcmcia/mpc8xx_pcmcia.c index 663827780e..af774260ee 100644 --- a/drivers/pcmcia/mpc8xx_pcmcia.c +++ b/drivers/pcmcia/mpc8xx_pcmcia.c @@ -211,16 +211,6 @@ static u_int m8xx_get_graycode(u_int size) #if 0 -#if defined(CONFIG_RPXLITE) - -/* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks. - * SYPCR is write once only, therefore must the slowest memory be faster - * than the bus monitor or we will get a machine check due to the bus timeout. - */ -#undef PCMCIA_BMT_LIMIT -#define PCMCIA_BMT_LIMIT (6*8) -#endif - static u_int m8xx_get_speed(u_int ns, u_int is_io) { u_int reg, clocks, psst, psl, psht; diff --git a/drivers/pcmcia/rpx_pcmcia.c b/drivers/pcmcia/rpx_pcmcia.c deleted file mode 100644 index 5b24f0bfbe..0000000000 --- a/drivers/pcmcia/rpx_pcmcia.c +++ /dev/null @@ -1,73 +0,0 @@ -/* -------------------------------------------------------------------- */ -/* RPX Boards from Embedded Planet */ -/* -------------------------------------------------------------------- */ -#include <common.h> -#ifdef CONFIG_8xx -#include <mpc8xx.h> -#endif -#include <pcmcia.h> - -#undef CONFIG_PCMCIA - -#if defined(CONFIG_CMD_PCMCIA) -#define CONFIG_PCMCIA -#endif - -#if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD) -#define CONFIG_PCMCIA -#endif - -#if defined(CONFIG_PCMCIA) \ - && defined(CONFIG_RPXLITE) - -#define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE" - -int pcmcia_voltage_set(int slot, int vcc, int vpp) -{ - u_long reg = 0; - - switch(vcc) { - case 0: break; - case 33: reg |= BCSR1_PCVCTL4; break; - case 50: reg |= BCSR1_PCVCTL5; break; - default: return 1; - } - - switch(vpp) { - case 0: break; - case 33: - case 50: - if(vcc == vpp) - reg |= BCSR1_PCVCTL6; - else - return 1; - break; - case 120: - reg |= BCSR1_PCVCTL7; - default: return 1; - } - - /* first, turn off all power */ - *((uint *)RPX_CSR_ADDR) &= ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5 - | BCSR1_PCVCTL6 | BCSR1_PCVCTL7); - - /* enable new powersettings */ - *((uint *)RPX_CSR_ADDR) |= reg; - - return 0; -} - -int pcmcia_hardware_enable (int slot) -{ - return 0; /* No hardware to enable */ -} - -#if defined(CONFIG_CMD_PCMCIA) -static int pcmcia_hardware_disable(int slot) -{ - return 0; /* No hardware to disable */ -} -#endif - - -#endif /* CONFIG_PCMCIA && CONFIG_RPXLITE */ diff --git a/drivers/power/Makefile b/drivers/power/Makefile index 53ff97d745..dc64e4d32b 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -5,6 +5,8 @@ # SPDX-License-Identifier: GPL-2.0+ # +obj-$(CONFIG_AXP152_POWER) += axp152.o +obj-$(CONFIG_AXP209_POWER) += axp209.o obj-$(CONFIG_EXYNOS_TMU) += exynos-tmu.o obj-$(CONFIG_FTPMU010_POWER) += ftpmu010.o obj-$(CONFIG_TPS6586X_POWER) += tps6586x.o diff --git a/drivers/power/axp152.c b/drivers/power/axp152.c new file mode 100644 index 0000000000..fa4ea050a5 --- /dev/null +++ b/drivers/power/axp152.c @@ -0,0 +1,97 @@ +/* + * (C) Copyright 2012 + * Henrik Nordstrom <henrik@henriknordstrom.net> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <i2c.h> +#include <axp152.h> + +enum axp152_reg { + AXP152_CHIP_VERSION = 0x3, + AXP152_DCDC2_VOLTAGE = 0x23, + AXP152_DCDC3_VOLTAGE = 0x27, + AXP152_DCDC4_VOLTAGE = 0x2B, + AXP152_LDO2_VOLTAGE = 0x2A, + AXP152_SHUTDOWN = 0x32, +}; + +#define AXP152_POWEROFF (1 << 7) + +static int axp152_write(enum axp152_reg reg, u8 val) +{ + return i2c_write(0x30, reg, 1, &val, 1); +} + +static int axp152_read(enum axp152_reg reg, u8 *val) +{ + return i2c_read(0x30, reg, 1, val, 1); +} + +static u8 axp152_mvolt_to_target(int mvolt, int min, int max, int div) +{ + if (mvolt < min) + mvolt = min; + else if (mvolt > max) + mvolt = max; + + return (mvolt - min) / div; +} + +int axp152_set_dcdc2(int mvolt) +{ + int rc; + u8 current, target; + + target = axp152_mvolt_to_target(mvolt, 700, 2275, 25); + + /* Do we really need to be this gentle? It has built-in voltage slope */ + while ((rc = axp152_read(AXP152_DCDC2_VOLTAGE, ¤t)) == 0 && + current != target) { + if (current < target) + current++; + else + current--; + rc = axp152_write(AXP152_DCDC2_VOLTAGE, current); + if (rc) + break; + } + return rc; +} + +int axp152_set_dcdc3(int mvolt) +{ + u8 target = axp152_mvolt_to_target(mvolt, 700, 3500, 25); + + return axp152_write(AXP152_DCDC3_VOLTAGE, target); +} + +int axp152_set_dcdc4(int mvolt) +{ + u8 target = axp152_mvolt_to_target(mvolt, 700, 3500, 25); + + return axp152_write(AXP152_DCDC4_VOLTAGE, target); +} + +int axp152_set_ldo2(int mvolt) +{ + u8 target = axp152_mvolt_to_target(mvolt, 700, 3500, 100); + + return axp152_write(AXP152_LDO2_VOLTAGE, target); +} + +int axp152_init(void) +{ + u8 ver; + int rc; + + rc = axp152_read(AXP152_CHIP_VERSION, &ver); + if (rc) + return rc; + + if (ver != 0x05) + return -1; + + return 0; +} diff --git a/drivers/power/axp209.c b/drivers/power/axp209.c new file mode 100644 index 0000000000..9798e5bf7c --- /dev/null +++ b/drivers/power/axp209.c @@ -0,0 +1,167 @@ +/* + * (C) Copyright 2012 + * Henrik Nordstrom <henrik@henriknordstrom.net> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <i2c.h> +#include <axp209.h> + +enum axp209_reg { + AXP209_POWER_STATUS = 0x00, + AXP209_CHIP_VERSION = 0x03, + AXP209_DCDC2_VOLTAGE = 0x23, + AXP209_DCDC3_VOLTAGE = 0x27, + AXP209_LDO24_VOLTAGE = 0x28, + AXP209_LDO3_VOLTAGE = 0x29, + AXP209_IRQ_STATUS5 = 0x4c, + AXP209_SHUTDOWN = 0x32, +}; + +#define AXP209_POWER_STATUS_ON_BY_DC (1 << 0) + +#define AXP209_IRQ5_PEK_UP (1 << 6) +#define AXP209_IRQ5_PEK_DOWN (1 << 5) + +#define AXP209_POWEROFF (1 << 7) + +static int axp209_write(enum axp209_reg reg, u8 val) +{ + return i2c_write(0x34, reg, 1, &val, 1); +} + +static int axp209_read(enum axp209_reg reg, u8 *val) +{ + return i2c_read(0x34, reg, 1, val, 1); +} + +static u8 axp209_mvolt_to_cfg(int mvolt, int min, int max, int div) +{ + if (mvolt < min) + mvolt = min; + else if (mvolt > max) + mvolt = max; + + return (mvolt - min) / div; +} + +int axp209_set_dcdc2(int mvolt) +{ + int rc; + u8 cfg, current; + + cfg = axp209_mvolt_to_cfg(mvolt, 700, 2275, 25); + + /* Do we really need to be this gentle? It has built-in voltage slope */ + while ((rc = axp209_read(AXP209_DCDC2_VOLTAGE, ¤t)) == 0 && + current != cfg) { + if (current < cfg) + current++; + else + current--; + + rc = axp209_write(AXP209_DCDC2_VOLTAGE, current); + if (rc) + break; + } + + return rc; +} + +int axp209_set_dcdc3(int mvolt) +{ + u8 cfg = axp209_mvolt_to_cfg(mvolt, 700, 3500, 25); + + return axp209_write(AXP209_DCDC3_VOLTAGE, cfg); +} + +int axp209_set_ldo2(int mvolt) +{ + int rc; + u8 cfg, reg; + + cfg = axp209_mvolt_to_cfg(mvolt, 1800, 3300, 100); + + rc = axp209_read(AXP209_LDO24_VOLTAGE, ®); + if (rc) + return rc; + + /* LDO2 configuration is in upper 4 bits */ + reg = (reg & 0x0f) | (cfg << 4); + return axp209_write(AXP209_LDO24_VOLTAGE, reg); +} + +int axp209_set_ldo3(int mvolt) +{ + u8 cfg; + + if (mvolt == -1) + cfg = 0x80; /* determined by LDO3IN pin */ + else + cfg = axp209_mvolt_to_cfg(mvolt, 700, 2275, 25); + + return axp209_write(AXP209_LDO3_VOLTAGE, cfg); +} + +int axp209_set_ldo4(int mvolt) +{ + int rc; + static const int vindex[] = { + 1250, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000, 2500, + 2700, 2800, 3000, 3100, 3200, 3300 + }; + u8 cfg, reg; + + /* Translate mvolt to register cfg value, requested <= selected */ + for (cfg = 15; vindex[cfg] > mvolt && cfg > 0; cfg--); + + rc = axp209_read(AXP209_LDO24_VOLTAGE, ®); + if (rc) + return rc; + + /* LDO4 configuration is in lower 4 bits */ + reg = (reg & 0xf0) | (cfg << 0); + return axp209_write(AXP209_LDO24_VOLTAGE, reg); +} + +int axp209_init(void) +{ + u8 ver; + int rc; + + rc = axp209_read(AXP209_CHIP_VERSION, &ver); + if (rc) + return rc; + + /* Low 4 bits is chip version */ + ver &= 0x0f; + + if (ver != 0x1) + return -1; + + return 0; +} + +int axp209_poweron_by_dc(void) +{ + u8 v; + + if (axp209_read(AXP209_POWER_STATUS, &v)) + return 0; + + return (v & AXP209_POWER_STATUS_ON_BY_DC); +} + +int axp209_power_button(void) +{ + u8 v; + + if (axp209_read(AXP209_IRQ_STATUS5, &v)) + return 0; + + axp209_write(AXP209_IRQ_STATUS5, AXP209_IRQ5_PEK_DOWN); + + return v & AXP209_IRQ5_PEK_DOWN; +} diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c index fd61a5e545..d2eb7520d0 100644 --- a/drivers/serial/serial.c +++ b/drivers/serial/serial.c @@ -254,6 +254,48 @@ void serial_initialize(void) serial_assign(default_serial_console()->name); } +int serial_stub_start(struct stdio_dev *sdev) +{ + struct serial_device *dev = sdev->priv; + + return dev->start(); +} + +int serial_stub_stop(struct stdio_dev *sdev) +{ + struct serial_device *dev = sdev->priv; + + return dev->stop(); +} + +void serial_stub_putc(struct stdio_dev *sdev, const char ch) +{ + struct serial_device *dev = sdev->priv; + + dev->putc(ch); +} + +void serial_stub_puts(struct stdio_dev *sdev, const char *str) +{ + struct serial_device *dev = sdev->priv; + + dev->puts(str); +} + +int serial_stub_getc(struct stdio_dev *sdev) +{ + struct serial_device *dev = sdev->priv; + + return dev->getc(); +} + +int serial_stub_tstc(struct stdio_dev *sdev) +{ + struct serial_device *dev = sdev->priv; + + return dev->tstc(); +} + /** * serial_stdio_init() - Register serial ports with STDIO core * @@ -272,12 +314,12 @@ void serial_stdio_init(void) strcpy(dev.name, s->name); dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT; - dev.start = s->start; - dev.stop = s->stop; - dev.putc = s->putc; - dev.puts = s->puts; - dev.getc = s->getc; - dev.tstc = s->tstc; + dev.start = serial_stub_start; + dev.stop = serial_stub_stop; + dev.putc = serial_stub_putc; + dev.puts = serial_stub_puts; + dev.getc = serial_stub_getc; + dev.tstc = serial_stub_tstc; stdio_register(&dev); @@ -376,6 +418,7 @@ static struct serial_device *get_current(void) */ int serial_init(void) { + gd->flags |= GD_FLG_SERIAL_READY; return get_current()->start(); } diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c index ba68d46948..4413e69118 100644 --- a/drivers/serial/serial_ns16550.c +++ b/drivers/serial/serial_ns16550.c @@ -120,6 +120,8 @@ static NS16550_t serial_ports[6] = { static int calc_divisor (NS16550_t port) { + const unsigned int mode_x_div = 16; + #ifdef CONFIG_OMAP1510 /* If can't cleanly clock 115200 set div to 1 */ if ((CONFIG_SYS_NS16550_CLK == 12000000) && (gd->baudrate == 115200)) { @@ -128,21 +130,9 @@ static int calc_divisor (NS16550_t port) } port->osc_12m_sel = 0; /* clear if previsouly set */ #endif -#ifdef CONFIG_OMAP1610 - /* If can't cleanly clock 115200 set div to 1 */ - if ((CONFIG_SYS_NS16550_CLK == 48000000) && (gd->baudrate == 115200)) { - return (26); /* return 26 for base divisor */ - } -#endif -#define MODE_X_DIV 16 - /* Compute divisor value. Normally, we should simply return: - * CONFIG_SYS_NS16550_CLK) / MODE_X_DIV / gd->baudrate - * but we need to round that value by adding 0.5. - * Rounding is especially important at high baud rates. - */ - return (CONFIG_SYS_NS16550_CLK + (gd->baudrate * (MODE_X_DIV / 2))) / - (MODE_X_DIV * gd->baudrate); + return DIV_ROUND_CLOSEST(CONFIG_SYS_NS16550_CLK, + mode_x_div * gd->baudrate); } void diff --git a/drivers/serial/usbtty.c b/drivers/serial/usbtty.c index 6b912efafd..b030526b6a 100644 --- a/drivers/serial/usbtty.c +++ b/drivers/serial/usbtty.c @@ -389,7 +389,7 @@ static void str2wide (char *str, u16 * wide) * Test whether a character is in the RX buffer */ -int usbtty_tstc (void) +int usbtty_tstc(struct stdio_dev *dev) { struct usb_endpoint_instance *endpoint = &endpoint_instance[rx_endpoint]; @@ -409,7 +409,7 @@ int usbtty_tstc (void) * written into its argument c. */ -int usbtty_getc (void) +int usbtty_getc(struct stdio_dev *dev) { char c; struct usb_endpoint_instance *endpoint = @@ -429,7 +429,7 @@ int usbtty_getc (void) /* * Output a single byte to the usb client port. */ -void usbtty_putc (const char c) +void usbtty_putc(struct stdio_dev *dev, const char c) { if (!usbtty_configured ()) return; @@ -484,7 +484,7 @@ static void __usbtty_puts (const char *str, int len) } } -void usbtty_puts (const char *str) +void usbtty_puts(struct stdio_dev *dev, const char *str) { int n; int len; diff --git a/drivers/sound/sandbox.c b/drivers/sound/sandbox.c index fe5c9e9b38..5599bb948f 100644 --- a/drivers/sound/sandbox.c +++ b/drivers/sound/sandbox.c @@ -5,7 +5,7 @@ */ #include <common.h> -#include <asm/arch/sound.h> +#include <asm/sound.h> #include <asm/sdl.h> int sound_play(uint32_t msec, uint32_t frequency) diff --git a/drivers/tpm/tpm.c b/drivers/tpm/tpm.c index b657334195..bc0f9645b5 100644 --- a/drivers/tpm/tpm.c +++ b/drivers/tpm/tpm.c @@ -411,7 +411,7 @@ static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz) goto out_recv; } - if ((status == chip->vendor.req_canceled)) { + if (status == chip->vendor.req_canceled) { error("Operation Canceled\n"); rc = -ECANCELED; goto out; diff --git a/drivers/usb/host/xhci-omap.c b/drivers/usb/host/xhci-omap.c index e667810bb3..912b2bd8d5 100644 --- a/drivers/usb/host/xhci-omap.c +++ b/drivers/usb/host/xhci-omap.c @@ -98,6 +98,7 @@ static int omap_xhci_core_init(struct omap_xhci *omap) { int ret = 0; + usb_phy_power(1); omap_enable_phy(omap); ret = dwc3_core_init(omap->dwc3_reg); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index ceb1573d86..6685ed23de 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -20,9 +20,7 @@ #include <asm/cache.h> #include <asm/io.h> #include <linux/list.h> - -#define upper_32_bits(n) (u32)((n) >> 32) -#define lower_32_bits(n) (u32)(n) +#include <linux/compat.h> #define MAX_EP_CTX_NUM 31 #define XHCI_ALIGNMENT 64 @@ -1121,7 +1119,7 @@ static inline void xhci_writeq(__le64 volatile *regs, const u64 val) __u32 *ptr = (__u32 *)regs; u32 val_lo = lower_32_bits(val); /* FIXME */ - u32 val_hi = 0; + u32 val_hi = upper_32_bits(val); writel(val_lo, ptr); writel(val_hi, ptr + 1); } diff --git a/drivers/usb/phy/omap_usb_phy.c b/drivers/usb/phy/omap_usb_phy.c index af46db2edd..f78d532966 100644 --- a/drivers/usb/phy/omap_usb_phy.c +++ b/drivers/usb/phy/omap_usb_phy.c @@ -222,7 +222,22 @@ static void am437x_enable_usb2_phy2(struct omap_xhci *omap) void usb_phy_power(int on) { - return; + u32 val; + + /* USB1_CTRL */ + val = readl(USB1_CTRL); + if (on) { + /* + * these bits are re-used on AM437x to power up/down the USB + * CM and OTG PHYs, if we don't toggle them, USB will not be + * functional on newer silicon revisions + */ + val &= ~(USB1_CTRL_CM_PWRDN | USB1_CTRL_OTG_PWRDN); + } else { + val |= USB1_CTRL_CM_PWRDN | USB1_CTRL_OTG_PWRDN; + } + + writel(val, USB1_CTRL); } #endif /* CONFIG_AM437X_USB2PHY2_HOST */ diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c index b52e9edd25..9231927879 100644 --- a/drivers/video/cfb_console.c +++ b/drivers/video/cfb_console.c @@ -944,7 +944,7 @@ static void parse_putc(const char c) CURSOR_SET; } -void video_putc(const char c) +void video_putc(struct stdio_dev *dev, const char c) { #ifdef CONFIG_CFB_CONSOLE_ANSI int i; @@ -1158,12 +1158,12 @@ void video_putc(const char c) flush_cache(VIDEO_FB_ADRS, VIDEO_SIZE); } -void video_puts(const char *s) +void video_puts(struct stdio_dev *dev, const char *s) { int count = strlen(s); while (count--) - video_putc(*s++); + video_putc(dev, *s++); } /* @@ -2279,8 +2279,6 @@ int drv_video_init(void) console_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_SYSTEM; console_dev.putc = video_putc; /* 'putc' function */ console_dev.puts = video_puts; /* 'puts' function */ - console_dev.tstc = NULL; /* 'tstc' function */ - console_dev.getc = NULL; /* 'getc' function */ #if !defined(CONFIG_VGA_AS_SINGLE_DEVICE) /* Also init console device */ diff --git a/drivers/video/mpc8xx_lcd.c b/drivers/video/mpc8xx_lcd.c index fceed871a7..2bc3ceb418 100644 --- a/drivers/video/mpc8xx_lcd.c +++ b/drivers/video/mpc8xx_lcd.c @@ -34,7 +34,7 @@ #define CONFIG_LCD_INFO /* Display Logo, (C) and system info */ #endif -#if defined(CONFIG_V37) || defined(CONFIG_EDT32F10) +#if defined(CONFIG_EDT32F10) #undef CONFIG_LCD_LOGO #undef CONFIG_LCD_INFO #endif @@ -268,11 +268,6 @@ void lcd_ctrl_init (void *lcdbase) * the controller. */ -#ifdef CONFIG_RPXLITE - /* This is special for RPXlite_DW Software Development Platform **[Sam]** */ - panel_info.vl_dp = CONFIG_SYS_LOW; -#endif - lccrtmp = LCDBIT (LCCR_BNUM_BIT, (((panel_info.vl_row * panel_info.vl_col) * (1 << LCD_BPP)) / 128)); @@ -297,9 +292,6 @@ void lcd_ctrl_init (void *lcdbase) /* Initialize LCD controller bus priorities. */ -#ifdef CONFIG_RBC823 - immr->im_siu_conf.sc_sdcr = (immr->im_siu_conf.sc_sdcr & ~0x0f) | 1; /* RAID = 01, LAID = 00 */ -#else immr->im_siu_conf.sc_sdcr &= ~0x0f; /* RAID = LAID = 0 */ /* set SHFT/CLOCK division factor 4 @@ -313,21 +305,7 @@ void lcd_ctrl_init (void *lcdbase) immr->im_clkrst.car_sccr &= ~0x1F; immr->im_clkrst.car_sccr |= LCD_DF; /* was 8 */ -#endif /* CONFIG_RBC823 */ - -#if defined(CONFIG_RBC823) - /* Enable LCD on port D. - */ - immr->im_ioport.iop_pddat &= 0x0300; - immr->im_ioport.iop_pdpar |= 0x1CFF; - immr->im_ioport.iop_pddir |= 0x1CFF; - - /* Configure LCD_ON, VEE_ON, CCFL_ON on port B. - */ - immr->im_cpm.cp_pbdat &= ~0x00005001; - immr->im_cpm.cp_pbpar &= ~0x00005001; - immr->im_cpm.cp_pbdir |= 0x00005001; -#elif !defined(CONFIG_EDT32F10) +#if !defined(CONFIG_EDT32F10) /* Enable LCD on port D. */ immr->im_ioport.iop_pdpar |= 0x1FFF; @@ -432,20 +410,9 @@ void lcd_enable (void) volatile lcd823_t *lcdp = &immr->im_lcd; /* Enable the LCD panel */ -#ifndef CONFIG_RBC823 immr->im_siu_conf.sc_sdcr |= (1 << (31 - 25)); /* LAM = 1 */ -#endif lcdp->lcd_lccr |= LCCR_PON; -#ifdef CONFIG_V37 - /* Turn on display backlight */ - immr->im_cpm.cp_pbpar |= 0x00008000; - immr->im_cpm.cp_pbdir |= 0x00008000; -#elif defined(CONFIG_RBC823) - /* Turn on display backlight */ - immr->im_cpm.cp_pbdat |= 0x00004000; -#endif - #if defined(CONFIG_LWMON) { uchar c = pic_read (0x60); #if defined(CONFIG_LCD) && defined(CONFIG_LWMON) && (CONFIG_POST & CONFIG_SYS_POST_SYSMON) @@ -481,14 +448,6 @@ void lcd_enable (void) r360_i2c_lcd_write(0x40 | ((ctr>>8) & 0xF), ctr & 0xFF); } #endif /* CONFIG_R360MPI */ -#ifdef CONFIG_RBC823 - udelay(200000); /* wait 200ms */ - /* Turn VEE_ON first */ - immr->im_cpm.cp_pbdat |= 0x00000001; - udelay(200000); /* wait 200ms */ - /* Now turn on LCD_ON */ - immr->im_cpm.cp_pbdat |= 0x00001000; -#endif #ifdef CONFIG_RRVISION debug ("PC4->Output(1): enable LVDS\n"); debug ("PC5->Output(0): disable PAL clock\n"); @@ -508,41 +467,6 @@ void lcd_enable (void) #endif } -/*----------------------------------------------------------------------*/ - -#if defined (CONFIG_RBC823) -void lcd_disable (void) -{ - volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; - volatile lcd823_t *lcdp = &immr->im_lcd; - -#if defined(CONFIG_LWMON) - { uchar c = pic_read (0x60); - c &= ~0x07; /* Power off CCFL, Disable CCFL, Chip Disable LCD */ - pic_write (0x60, c); - } -#elif defined(CONFIG_R360MPI) - { - extern void r360_i2c_lcd_write (uchar data0, uchar data1); - - r360_i2c_lcd_write(0x10, 0x00); - r360_i2c_lcd_write(0x20, 0x00); - r360_i2c_lcd_write(0x30, 0x00); - r360_i2c_lcd_write(0x40, 0x00); - } -#endif /* CONFIG_LWMON */ - /* Disable the LCD panel */ - lcdp->lcd_lccr &= ~LCCR_PON; -#ifdef CONFIG_RBC823 - /* Turn off display backlight, VEE and LCD_ON */ - immr->im_cpm.cp_pbdat &= ~0x00005001; -#else - immr->im_siu_conf.sc_sdcr &= ~(1 << (31 - 25)); /* LAM = 0 */ -#endif /* CONFIG_RBC823 */ -} -#endif /* NOT_USED_SO_FAR || CONFIG_RBC823 */ - - /************************************************************************/ #endif /* CONFIG_LCD */ diff --git a/drivers/watchdog/bfin_wdt.c b/drivers/watchdog/bfin_wdt.c index 7a6756b2e5..6a8db59fdf 100644 --- a/drivers/watchdog/bfin_wdt.c +++ b/drivers/watchdog/bfin_wdt.c @@ -9,6 +9,7 @@ #include <common.h> #include <watchdog.h> #include <asm/blackfin.h> +#include <asm/clock.h> #include <asm/mach-common/bits/watchdog.h> void hw_watchdog_reset(void) |