From d1486e3352c8e6b91da8e610993ea591466cb223 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 4 Dec 2013 10:01:54 -0200 Subject: video: ipu_disp: Return a negative value on error We should return a negative error number (-EINVAL) on error. Signed-off-by: Fabio Estevam --- drivers/video/ipu_disp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/ipu_disp.c b/drivers/video/ipu_disp.c index 22ac1429ba4..cefd2dc14a2 100644 --- a/drivers/video/ipu_disp.c +++ b/drivers/video/ipu_disp.c @@ -889,7 +889,7 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk, debug("panel size = %d x %d\n", width, height); if ((v_sync_width == 0) || (h_sync_width == 0)) - return EINVAL; + return -EINVAL; adapt_panel_to_ipu_restricitions(&pixel_clk, width, height, h_start_width, h_end_width, -- cgit v1.3.1 From 732dfe090d50af53bb682d0c8971784f8de1f90f Mon Sep 17 00:00:00 2001 From: Shengzhou Liu Date: Mon, 2 Dec 2013 10:23:11 +0800 Subject: net/fman: add ft_fixup_xgec to support 3rd and 4th 10GEC As mEMAC1 and mEMAC2 are dual-role MACs, which are used as 1G or 10G MAC. So we update dynamically 'cell-index' to '2' and '3' for 10GEC3 and 10GEC4. Also change 'fsl,fman-port-1g-rx' to 'fsl,fman-port-10g-rx', ditto for Tx. Signed-off-by: Shengzhou Liu Acked-by: York Sun --- drivers/net/fm/init.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/fm/init.c b/drivers/net/fm/init.c index cd787f4eeda..74c72d3ff79 100644 --- a/drivers/net/fm/init.c +++ b/drivers/net/fm/init.c @@ -276,13 +276,64 @@ static void ft_fixup_port(void *blob, struct fm_eth_info *info, char *prop) "status", "disabled", strlen("disabled") + 1, 1); } +#ifdef CONFIG_SYS_FMAN_V3 +static int ft_fixup_xgec(void *blob, struct fm_eth_info *info) +{ + int off, i, ci; +#define FM1_10GEC3_RX_PORT_ADDR (CONFIG_SYS_CCSRBAR_PHYS + 0x488000) +#define FM1_10GEC3_TX_PORT_ADDR (CONFIG_SYS_CCSRBAR_PHYS + 0x4a8000) +#define FM1_10GEC3_MAC_ADDR (CONFIG_SYS_CCSRBAR_PHYS + 0x4e0000) + + if ((info->port == FM1_10GEC3) || (info->port == FM1_10GEC4)) { + ci = (info->port == FM1_10GEC3) ? 2 : 3; + i = (info->port == FM1_10GEC3) ? 0 : 1; + + off = fdt_node_offset_by_compat_reg(blob, "fsl,fman-port-1g-rx", + FM1_10GEC3_RX_PORT_ADDR + + i * 0x1000); + if (off > 0) { + fdt_setprop(blob, off, "cell-index", &ci, sizeof(int)); + fdt_setprop(blob, off, "compatible", + "fsl,fman-port-10g-rx", 20); + } else { + goto err; + } + + off = fdt_node_offset_by_compat_reg(blob, "fsl,fman-port-1g-tx", + FM1_10GEC3_TX_PORT_ADDR + + i * 0x1000); + if (off > 0) { + fdt_setprop(blob, off, "cell-index", &ci, sizeof(int)); + fdt_setprop(blob, off, "compatible", + "fsl,fman-port-10g-tx", 20); + } else { + goto err; + } + + off = fdt_node_offset_by_compat_reg(blob, "fsl,fman-memac", + FM1_10GEC3_MAC_ADDR + + i * 0x2000); + if (off > 0) + fdt_setprop(blob, off, "cell-index", &ci, sizeof(int)); + else + goto err; + } + return 0; +err: + printf("WARNING: Fail to find the node\n"); + return -1; +} +#endif + void fdt_fixup_fman_ethernet(void *blob) { int i; #ifdef CONFIG_SYS_FMAN_V3 - for (i = 0; i < ARRAY_SIZE(fm_info); i++) + for (i = 0; i < ARRAY_SIZE(fm_info); i++) { ft_fixup_port(blob, &fm_info[i], "fsl,fman-memac"); + ft_fixup_xgec(blob, &fm_info[i]); + } #else for (i = 0; i < ARRAY_SIZE(fm_info); i++) { if (fm_info[i].type == FM_ETH_1G_E) -- cgit v1.3.1 From 5deccafa1870c4c4eb588ebcc6b4e95c4d7a59f6 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Sat, 30 Nov 2013 16:47:01 +0200 Subject: serial: lpc32xx: send CR before LF For LPC32XX high-speed UART it is required to send a carriage return symbol along with line feed. The problem was introduced in e503f90a commit. Signed-off-by: Vladimir Zapolskiy Cc: Marek Vasut Acked-by: Marek Vasut --- drivers/serial/lpc32xx_hsuart.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/serial/lpc32xx_hsuart.c b/drivers/serial/lpc32xx_hsuart.c index 9c7c6213a58..c8926a8945a 100644 --- a/drivers/serial/lpc32xx_hsuart.c +++ b/drivers/serial/lpc32xx_hsuart.c @@ -38,6 +38,9 @@ static int lpc32xx_serial_getc(void) static void lpc32xx_serial_putc(const char c) { + if (c == '\n') + serial_putc('\r'); + writel(c, &hsuart->tx); /* Wait for character to be sent */ -- cgit v1.3.1 From 4f57a90cfa1872c0142483e426061dca4e3c90c4 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 28 Nov 2013 12:20:14 +0900 Subject: drivers/usb/gadget: select objects by obj-$(CONFIG-...) Before switching to the real Kbuild, drivers/usb/gadget/Makefile must be fixed. If none of CONFIG_USB_GADGET, CONFIG_USB_ETHER, CONFIG_USB_DEVICE is defined, both obj- and obj-y get empty. We need non-empty obj- or obj-y on each Makefile to generate built-in.o on the real Kbuild. Signed-off-by: Masahiro Yamada --- drivers/usb/gadget/Makefile | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index f52d3f45003..f13b172a667 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -5,12 +5,8 @@ # SPDX-License-Identifier: GPL-2.0+ # -# if defined(CONFIG_USB_GADGET) || defined(CONFIG_USB_ETHER) -# Everytime you forget how crufty makefiles can get things like -# this remind you... -ifneq (,$(CONFIG_USB_GADGET)$(CONFIG_USB_ETHER)) -obj-y += epautoconf.o config.o usbstring.o -endif +obj-$(CONFIG_USB_GADGET) += epautoconf.o config.o usbstring.o +obj-$(CONFIG_USB_ETHER) += epautoconf.o config.o usbstring.o # new USB gadget layer dependencies ifdef CONFIG_USB_GADGET -- cgit v1.3.1 From 392ba5256ab9bf017a9b7320ef0cee98862c908d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 28 Nov 2013 12:22:17 +0900 Subject: drivers/mtd: descend into sub directories only when it is necessary Signed-off-by: Masahiro Yamada --- Makefile | 4 ++-- drivers/mtd/nand/Makefile | 3 --- drivers/mtd/ubi/Makefile | 3 --- spl/Makefile | 2 +- 4 files changed, 3 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/Makefile b/Makefile index 468b1bc605e..b251bf64974 100644 --- a/Makefile +++ b/Makefile @@ -249,9 +249,9 @@ LIBS-y += drivers/i2c/ LIBS-y += drivers/input/ LIBS-y += drivers/mmc/ LIBS-y += drivers/mtd/ -LIBS-y += drivers/mtd/nand/ +LIBS-$(CONFIG_CMD_NAND) += drivers/mtd/nand/ LIBS-y += drivers/mtd/onenand/ -LIBS-y += drivers/mtd/ubi/ +LIBS-$(CONFIG_CMD_UBI) += drivers/mtd/ubi/ LIBS-y += drivers/mtd/spi/ LIBS-y += drivers/net/ LIBS-y += drivers/net/phy/ diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index e145cd18421..02b149cacca 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -5,8 +5,6 @@ # SPDX-License-Identifier: GPL-2.0+ # -ifdef CONFIG_CMD_NAND - ifdef CONFIG_SPL_BUILD ifdef CONFIG_SPL_NAND_DRIVERS @@ -69,4 +67,3 @@ obj-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_spl.o obj-$(CONFIG_NAND_MXC) += mxc_nand_spl.o endif # drivers -endif # nand diff --git a/drivers/mtd/ubi/Makefile b/drivers/mtd/ubi/Makefile index e1f3a241a26..56c2823477d 100644 --- a/drivers/mtd/ubi/Makefile +++ b/drivers/mtd/ubi/Makefile @@ -5,9 +5,6 @@ # SPDX-License-Identifier: GPL-2.0+ # -ifdef CONFIG_CMD_UBI obj-y += build.o vtbl.o vmt.o upd.o kapi.o eba.o io.o wl.o scan.o crc32.o - obj-y += misc.o obj-y += debug.o -endif diff --git a/spl/Makefile b/spl/Makefile index 9b862be9a5f..ec0983170a0 100644 --- a/spl/Makefile +++ b/spl/Makefile @@ -78,7 +78,7 @@ LIBS-y += fs/ LIBS-$(CONFIG_SPL_LIBGENERIC_SUPPORT) += lib/ LIBS-$(CONFIG_SPL_POWER_SUPPORT) += drivers/power/ \ drivers/power/pmic/ -LIBS-$(CONFIG_SPL_NAND_SUPPORT) += drivers/mtd/nand/ +LIBS-$(if $(CONFIG_CMD_NAND),$(CONFIG_SPL_NAND_SUPPORT)) += drivers/mtd/nand/ LIBS-$(CONFIG_SPL_ONENAND_SUPPORT) += drivers/mtd/onenand/ LIBS-$(CONFIG_SPL_DMA_SUPPORT) += drivers/dma/ LIBS-$(CONFIG_SPL_POST_MEM_SUPPORT) += post/drivers/ -- cgit v1.3.1 From 69cc97f8dbf898d732fbd04852cf1068aeb991ba Mon Sep 17 00:00:00 2001 From: pekon gupta Date: Thu, 5 Dec 2013 17:54:21 +0530 Subject: mtd: nand: omap: fix ecc-layout for HAM1 ecc-scheme As per OMAP3530 TRM referenced below [1] For large-page NAND, ROM code expects following ecc-layout for HAM1 ecc-scheme - OOB[1] (offset of 1 *byte* from start of OOB) for x8 NAND device - OOB[2] (offset of 1 *word* from start of OOB) for x16 NAND device Thus ecc-layout expected by ROM code for HAM1 ecc-scheme is: *for x8 NAND Device* +--------+---------+---------+---------+---------+---------+---------+ | xxxx | ECC[A0] | ECC[A1] | ECC[A2] | ECC[B0] | ECC[B1] | ECC[B2] | ... +--------+---------+---------+---------+---------+---------+---------+ *for x16 NAND Device* +--------+--------+---------+---------+---------+---------+---------+---------+ | xxxxx | xxxxx | ECC[A0] | ECC[A1] | ECC[A2] | ECC[B0] | ECC[B1] | ECC[B2] | +--------+--------+---------+---------+---------+---------+---------+---------+ This patch fixes ecc-layout *only* for HAM1, as required by ROM-code For other ecc-schemes like (BCH8) ecc-layout is same for x8 or x16 devices. [1] OMAP3530: http://www.ti.com/product/omap3530 TRM: http://www.ti.com/litv/pdf/spruf98x Chapter-25: Initialization Sub-topic: Memory Booting Section: 25.4.7.4 NAND Figure 25-19. ECC Locations in NAND Spare Areas Reported-by: Stefan Roese Signed-off-by: Pekon Gupta Tested-by: Stefan Roese --- drivers/mtd/nand/omap_gpmc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c index 5e7e6b33754..23a961c9d4e 100644 --- a/drivers/mtd/nand/omap_gpmc.c +++ b/drivers/mtd/nand/omap_gpmc.c @@ -798,8 +798,12 @@ static int omap_select_ecc_scheme(struct nand_chip *nand, nand->ecc.calculate = omap_calculate_ecc; /* define ecc-layout */ ecclayout->eccbytes = nand->ecc.bytes * eccsteps; - for (i = 0; i < ecclayout->eccbytes; i++) - ecclayout->eccpos[i] = i + BADBLOCK_MARKER_LENGTH; + for (i = 0; i < ecclayout->eccbytes; i++) { + if (nand->options & NAND_BUSWIDTH_16) + ecclayout->eccpos[i] = i + 2; + else + ecclayout->eccpos[i] = i + 1; + } ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH; ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes - BADBLOCK_MARKER_LENGTH; -- cgit v1.3.1 From 5d7a49b930156514ce9d418e26b5bf21673fd399 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Thu, 5 Dec 2013 07:58:06 +0100 Subject: mtd: nand: omap_gpmc: cosmetic: Fix indentation Signed-off-by: Stefan Roese Cc: Pekon Gupta Cc: Scott Wood [scottwood@freescale.com: wrap some long lines] Signed-off-by: Scott Wood --- drivers/mtd/nand/omap_gpmc.c | 88 ++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c index 23a961c9d4e..20679694f3e 100644 --- a/drivers/mtd/nand/omap_gpmc.c +++ b/drivers/mtd/nand/omap_gpmc.c @@ -283,53 +283,55 @@ static void omap_hwecc_init_bch(struct nand_chip *chip, int32_t mode) if (bch->ecc_scheme == OMAP_ECC_BCH8_CODE_HW) { wr_mode = BCH_WRAPMODE_1; - switch (bch->nibbles) { - case ECC_BCH4_NIBBLES: - unused_length = 3; - break; - case ECC_BCH8_NIBBLES: - unused_length = 2; - break; - case ECC_BCH16_NIBBLES: - unused_length = 0; - break; - } - - /* - * This is ecc_size_config for ELM mode. - * Here we are using different settings for read and write access and - * also depending on BCH strength. - */ - switch (mode) { - case NAND_ECC_WRITE: - /* write access only setup eccsize1 config */ - val = ((unused_length + bch->nibbles) << 22); - break; + switch (bch->nibbles) { + case ECC_BCH4_NIBBLES: + unused_length = 3; + break; + case ECC_BCH8_NIBBLES: + unused_length = 2; + break; + case ECC_BCH16_NIBBLES: + unused_length = 0; + break; + } - case NAND_ECC_READ: - default: /* - * by default eccsize0 selected for ecc1resultsize - * eccsize0 config. + * This is ecc_size_config for ELM mode. Here we are using + * different settings for read and write access and also + * depending on BCH strength. */ - val = (bch->nibbles << 12); - /* eccsize1 config */ - val |= (unused_length << 22); - break; - } + switch (mode) { + case NAND_ECC_WRITE: + /* write access only setup eccsize1 config */ + val = ((unused_length + bch->nibbles) << 22); + break; + + case NAND_ECC_READ: + default: + /* + * by default eccsize0 selected for ecc1resultsize + * eccsize0 config. + */ + val = (bch->nibbles << 12); + /* eccsize1 config */ + val |= (unused_length << 22); + break; + } } else { - /* - * This ecc_size_config setting is for BCH sw library. - * - * Note: we only support BCH8 currently with BCH sw library! - * Should be really easy to adobt to BCH4, however some omap3 have - * flaws with BCH4. - * - * Here we are using wrapping mode 6 both for reading and writing, with: - * size0 = 0 (no additional protected byte in spare area) - * size1 = 32 (skip 32 nibbles = 16 bytes per sector in spare area) - */ - val = (32 << 22) | (0 << 12); + /* + * This ecc_size_config setting is for BCH sw library. + * + * Note: we only support BCH8 currently with BCH sw library! + * Should be really easy to adobt to BCH4, however some omap3 + * have flaws with BCH4. + * + * Here we are using wrapping mode 6 both for reading and + * writing, with: + * size0 = 0 (no additional protected byte in spare area) + * size1 = 32 (skip 32 nibbles = 16 bytes per sector in + * spare area) + */ + val = (32 << 22) | (0 << 12); } /* ecc size configuration */ writel(val, &gpmc_cfg->ecc_size_config); -- cgit v1.3.1 From 2528460c38dfaffe7ae430244d1fa119087c1b01 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Thu, 12 Dec 2013 15:19:31 +0200 Subject: mtd: nand: omap: fix HAM1_SW ecc using default value for ecc.size Commit "mtd: nand: omap: enable BCH ECC scheme using ELM for generic platform" (d016dc42cedbf6102e100fa9ecb58462edfb14f8) changed the way software ECC is configured, both during boot, and during ecc switch, in a way that is not backwards compatible with older systems: Older version of omap_gpmc.c always assigned ecc.size = 0 when configuring for software ecc, relying on nand_scan_tail() to select a default for ecc.size (256), while the new version of omap_gpmc.c assigns ecc.size = pagesize, which is likely to not be 256. Since 1 bit hamming sw ecc is only meant to be used by legacy devices, revert to the original behavior. Cc: Igor Grinberg Cc: Tom Rini Cc: Scott Wood Cc: Pekon Gupta Signed-off-by: Nikita Kiryanov Acked-by: Pekon Gupta --- drivers/mtd/nand/omap_gpmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c index 20679694f3e..d5c4c2269c1 100644 --- a/drivers/mtd/nand/omap_gpmc.c +++ b/drivers/mtd/nand/omap_gpmc.c @@ -776,7 +776,7 @@ static int omap_select_ecc_scheme(struct nand_chip *nand, bch_priv.type = 0; nand->ecc.mode = NAND_ECC_SOFT; nand->ecc.layout = NULL; - nand->ecc.size = pagesize; + nand->ecc.size = 0; bch->ecc_scheme = OMAP_ECC_HAM1_CODE_SW; break; -- cgit v1.3.1 From 3ef1eadb4466a68a32cb56e6be98a98061c07673 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Mon, 16 Dec 2013 09:59:34 -0500 Subject: nand_util.c: Use '%zd' for length in nand_unlock debug print length is size_t so needs to be '%zd' not '%d' to avoid warnings. Cc: Scott Wood Signed-off-by: Tom Rini --- drivers/mtd/nand/nand_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c index eeaa7e8a488..b292826034f 100644 --- a/drivers/mtd/nand/nand_util.c +++ b/drivers/mtd/nand/nand_util.c @@ -315,7 +315,7 @@ int nand_unlock(struct mtd_info *mtd, loff_t start, size_t length, int page; struct nand_chip *chip = mtd->priv; - debug("nand_unlock%s: start: %08llx, length: %d!\n", + debug("nand_unlock%s: start: %08llx, length: %zd!\n", allexcept ? " (allexcept)" : "", start, length); /* select the NAND device */ -- cgit v1.3.1 From eb237a15bd793a785feb0c77c459c9f97c6fbe4c Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Mon, 16 Dec 2013 19:19:01 +0200 Subject: mtd: nand: omap: fix sw->hw->sw ecc switch When switching ecc mode, omap_select_ecc_scheme() assigns the appropriate values into the current nand chip's ecc.layout struct. This is done under the assumption that the struct exists only to store values, so it is OK to overwrite it, but there is at least one situation where this assumption is incorrect: When switching to 1 bit hamming code sw ecc, the job of assigning layout data is outsourced to nand_scan_tail(), which simply assigns into ecc.layout a pointer to an existing struct prefilled with the appropriate values. This struct doubles as both data and layout definition, and therefore shouldn't be overwritten, but on the next switch to hardware ecc, this is exactly what's going to happen. The next time the user switches to software ecc, they're going to get a messed up ecc layout. Prevent this and possible similar bugs by explicitly using the private-to-omap_gpmc.c omap_ecclayout struct when switching ecc mode. Cc: Scott Wood Cc: Pekon Gupta Signed-off-by: Nikita Kiryanov --- drivers/mtd/nand/omap_gpmc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c index d5c4c2269c1..3405ed502bf 100644 --- a/drivers/mtd/nand/omap_gpmc.c +++ b/drivers/mtd/nand/omap_gpmc.c @@ -763,7 +763,7 @@ static void __maybe_unused omap_free_bch(struct mtd_info *mtd) static int omap_select_ecc_scheme(struct nand_chip *nand, enum omap_ecc ecc_scheme, unsigned int pagesize, unsigned int oobsize) { struct nand_bch_priv *bch = nand->priv; - struct nand_ecclayout *ecclayout = nand->ecc.layout; + struct nand_ecclayout *ecclayout = &omap_ecclayout; int eccsteps = pagesize / SECTOR_BYTES; int i; @@ -897,6 +897,11 @@ static int omap_select_ecc_scheme(struct nand_chip *nand, debug("nand: error: ecc scheme not enabled or supported\n"); return -EINVAL; } + + /* nand_scan_tail() sets ham1 sw ecc; hw ecc layout is set by driver */ + if (ecc_scheme != OMAP_ECC_HAM1_CODE_SW) + nand->ecc.layout = ecclayout; + return 0; } -- cgit v1.3.1 From fcd052457434d1f86c4e6d5f90d838210ab87d8b Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Tue, 17 Dec 2013 15:18:01 +0200 Subject: mtd: nand: omap: fix ecc ops assignment when changing ecc If we change to software ecc and then back to hardware ecc, the nand ecc ops pointers are populated with incorrect function pointers. This is related to the way nand_scan_tail() handles assigning functions to ecc ops: If we are switching to software ecc/no ecc, it assigns default functions to the ecc ops pointers unconditionally, but if we are switching to hardware ecc, the default hardware ecc functions are assigned to ops pointers only if these pointers are NULL (so that drivers could set their own functions). In the case of omap_gpmc.c driver, when we switch to sw ecc, sw ecc functions are assigned to ecc ops by nand_scan_tail(), and when we later switch to hw ecc, the ecc ops pointers are not NULL, so nand_scan_tail() does not overwrite them with hw ecc functions. The result: sw ecc functions used to write hw ecc data. Clear the ecc ops pointers in omap_gpmc.c when switching ecc types, so that ops which were not assigned by the driver will get the correct default values from nand_scan_tail(). Cc: Scott Wood Cc: Pekon Gupta Signed-off-by: Nikita Kiryanov --- drivers/mtd/nand/omap_gpmc.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c index 3405ed502bf..790d5385e0b 100644 --- a/drivers/mtd/nand/omap_gpmc.c +++ b/drivers/mtd/nand/omap_gpmc.c @@ -791,6 +791,7 @@ static int omap_select_ecc_scheme(struct nand_chip *nand, bch_priv.control = NULL; bch_priv.type = 0; /* populate ecc specific fields */ + memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl)); nand->ecc.mode = NAND_ECC_HW; nand->ecc.strength = 1; nand->ecc.size = SECTOR_BYTES; @@ -829,6 +830,7 @@ static int omap_select_ecc_scheme(struct nand_chip *nand, } bch_priv.type = ECC_BCH8; /* populate ecc specific fields */ + memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl)); nand->ecc.mode = NAND_ECC_HW; nand->ecc.strength = 8; nand->ecc.size = SECTOR_BYTES; @@ -871,6 +873,7 @@ static int omap_select_ecc_scheme(struct nand_chip *nand, elm_init(); bch_priv.type = ECC_BCH8; /* populate ecc specific fields */ + memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl)); nand->ecc.mode = NAND_ECC_HW; nand->ecc.strength = 8; nand->ecc.size = SECTOR_BYTES; -- cgit v1.3.1 From 3067f81f165550cbc3199ba6764eb7558699e2b0 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Wed, 18 Dec 2013 16:04:04 +0900 Subject: net: sh-eth: add support for SH7753 SH7753 has two fast ethernet controllers and two gigabit ethernet controllers. It is similar to SH7757. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Nobuhiro Iwamatsu --- drivers/net/sh_eth.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h index 8aa71098cb3..331c07cb596 100644 --- a/drivers/net/sh_eth.h +++ b/drivers/net/sh_eth.h @@ -287,7 +287,9 @@ static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = { #if defined(CONFIG_CPU_SH7763) || defined(CONFIG_CPU_SH7734) #define SH_ETH_TYPE_GETHER #define BASE_IO_ADDR 0xfee00000 -#elif defined(CONFIG_CPU_SH7757) || defined(CONFIG_CPU_SH7752) +#elif defined(CONFIG_CPU_SH7757) || \ + defined(CONFIG_CPU_SH7752) || \ + defined(CONFIG_CPU_SH7753) #if defined(CONFIG_SH_ETHER_USE_GETHER) #define SH_ETH_TYPE_GETHER #define BASE_IO_ADDR 0xfee00000 @@ -356,7 +358,9 @@ enum DMAC_T_BIT { /* GECMR */ enum GECMR_BIT { -#if defined(CONFIG_CPU_SH7757) || defined(CONFIG_CPU_SH7752) +#if defined(CONFIG_CPU_SH7757) || \ + defined(CONFIG_CPU_SH7752) || \ + defined(CONFIG_CPU_SH7753) GECMR_1000B = 0x20, GECMR_100B = 0x01, GECMR_10B = 0x00, #else GECMR_1000B = 0x01, GECMR_100B = 0x04, GECMR_10B = 0x00, -- cgit v1.3.1 From f3bf212abc4139f12b472e97c1992ab32671b609 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Wed, 18 Dec 2013 16:04:20 +0900 Subject: serial_sh: add support for SH7753 Signed-off-by: Yoshihiro Shimoda Signed-off-by: Nobuhiro Iwamatsu --- drivers/serial/serial_sh.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/serial/serial_sh.h b/drivers/serial/serial_sh.h index 556b8681502..f5e9854d13d 100644 --- a/drivers/serial/serial_sh.h +++ b/drivers/serial/serial_sh.h @@ -143,7 +143,9 @@ struct uart_port { #elif defined(CONFIG_H8S2678) # define SCSCR_INIT(port) 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ # define H8300_SCI_DR(ch) (*(volatile char *)(P1DR + h8300_sci_pins[ch].port)) -#elif defined(CONFIG_CPU_SH7757) || defined(CONFIG_CPU_SH7752) +#elif defined(CONFIG_CPU_SH7757) || \ + defined(CONFIG_CPU_SH7752) || \ + defined(CONFIG_CPU_SH7753) # define SCSPTR0 0xfe4b0020 # define SCSPTR1 0xfe4b0020 # define SCSPTR2 0xfe4b0020 -- cgit v1.3.1 From 28303f617a01d6663a54062852f67f8150b4c87a Mon Sep 17 00:00:00 2001 From: Luka Perkov Date: Mon, 28 Oct 2013 10:26:41 +0100 Subject: sf: probe: Hex values are in lower case All other hex values in sf_probe.c are in lower case so we should fix this one too. Signed-off-by: Luka Perkov Reviewed-by: Jagannadha Sutradharudu Teki --- drivers/mtd/spi/sf_probe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index c1eb7548983..2bd86b1814c 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -67,7 +67,7 @@ static const struct spi_flash_params spi_flash_params_table[] = { {"MX25L6405D", 0xc22017, 0x0, 64 * 1024, 128, 0}, {"MX25L12805", 0xc22018, 0x0, 64 * 1024, 256, 0}, {"MX25L25635F", 0xc22019, 0x0, 64 * 1024, 512, 0}, - {"MX25L51235F", 0xc2201A, 0x0, 64 * 1024, 1024, 0}, + {"MX25L51235F", 0xc2201a, 0x0, 64 * 1024, 1024, 0}, {"MX25L12855E", 0xc22618, 0x0, 64 * 1024, 256, 0}, #endif #ifdef CONFIG_SPI_FLASH_SPANSION /* SPANSION */ -- cgit v1.3.1 From 57af475389c1355f630cdafc1f3acc42347df669 Mon Sep 17 00:00:00 2001 From: Luka Perkov Date: Mon, 28 Oct 2013 10:27:17 +0100 Subject: sf: probe: add support for MX25L2006E Add support for Macronix MX25L2006E SPI flash. Signed-off-by: Luka Perkov Reviewed-by: Jagannadha Sutradharudu Teki --- drivers/mtd/spi/sf_probe.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index 2bd86b1814c..b863a982834 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -60,6 +60,7 @@ static const struct spi_flash_params spi_flash_params_table[] = { {"GD25LQ32", 0xc86016, 0x0, 64 * 1024, 64, SECT_4K}, #endif #ifdef CONFIG_SPI_FLASH_MACRONIX /* MACRONIX */ + {"MX25L2006E", 0xc22012, 0x0, 64 * 1024, 4, 0}, {"MX25L4005", 0xc22013, 0x0, 64 * 1024, 8, 0}, {"MX25L8005", 0xc22014, 0x0, 64 * 1024, 16, 0}, {"MX25L1605D", 0xc22015, 0x0, 64 * 1024, 32, 0}, -- cgit v1.3.1 From 16f47c9c510a61ee91d6b9d02dd723522beff80f Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Wed, 18 Dec 2013 15:31:55 +0900 Subject: spi: Add support SH Quad SPI driver This patch adds a driver for Renesas SoC's Quad SPI bus. This supports with 8 bits per transfer to use with SPI flash. Signed-off-by: Kouei Abe Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Jagannadha Sutradharudu Teki --- doc/SPI/README.sh_qspi_test | 38 ++++++ drivers/spi/Makefile | 1 + drivers/spi/sh_qspi.c | 277 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 316 insertions(+) create mode 100644 doc/SPI/README.sh_qspi_test create mode 100644 drivers/spi/sh_qspi.c (limited to 'drivers') diff --git a/doc/SPI/README.sh_qspi_test b/doc/SPI/README.sh_qspi_test new file mode 100644 index 00000000000..8a33fec32fd --- /dev/null +++ b/doc/SPI/README.sh_qspi_test @@ -0,0 +1,38 @@ +------------------------------------------------- + Simple steps used to test the SH-QSPI at U-Boot +------------------------------------------------- + +#0, Currently, SH-QSPI is used by lager board (Renesas ARM SoC R8A7790) + and koelsch board (Renesas ARM SoC R8A7791). These boot from SPI ROM + basically. Thus, U-Boot start, SH-QSPI will is operating normally. + +#1, build U-Boot and load u-boot.bin + + => tftpboot 40000000 u-boot.bin + sh_eth Waiting for PHY auto negotiation to complete.. done + sh_eth: 100Base/Half + Using sh_eth device + TFTP from server 192.168.169.1; our IP address is 192.168.169.79 + Filename 'u-boot.bin'. + Load address: 0x40000000 + Loading: ############ + 2.5 MiB/s + done + Bytes transferred = 175364 (2ad04 hex) + +#2, Commands to erase/write u-boot to flash device + + Note: This method is description of the lager board. If you want to use the + other boards, please change the value according to each environment. + + => sf probe 0 + SF: Detected S25FL512S_256K with page size 512 Bytes, erase size 64 KiB, total 64 MiB + => sf erase 80000 40000 + SF: 262144 bytes @ 0x80000 Erased: OK + => sf write 40000000 80000 175364 + SF: 1528676 bytes @ 0x80000 Written: OK + => + +#3, Push reset button. + + If you're written correctly and driver works properly, U-Boot starts. diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index ed4ecd754b4..d5a7143b500 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_OMAP3_SPI) += omap3_spi.o obj-$(CONFIG_SANDBOX_SPI) += sandbox_spi.o obj-$(CONFIG_SOFT_SPI) += soft_spi.o obj-$(CONFIG_SH_SPI) += sh_spi.o +obj-$(CONFIG_SH_QSPI) += sh_qspi.o obj-$(CONFIG_FSL_ESPI) += fsl_espi.o obj-$(CONFIG_FDT_SPI) += fdt_spi.o obj-$(CONFIG_TEGRA20_SFLASH) += tegra20_sflash.o diff --git a/drivers/spi/sh_qspi.c b/drivers/spi/sh_qspi.c new file mode 100644 index 00000000000..edeb42d0388 --- /dev/null +++ b/drivers/spi/sh_qspi.c @@ -0,0 +1,277 @@ +/* + * SH QSPI (Quad SPI) driver + * + * Copyright (C) 2013 Renesas Electronics Corporation + * Copyright (C) 2013 Nobuhiro Iwamatsu + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include +#include +#include + +/* SH QSPI register bit masks _ */ +#define SPCR_MSTR 0x08 +#define SPCR_SPE 0x40 +#define SPSR_SPRFF 0x80 +#define SPSR_SPTEF 0x20 +#define SPPCR_IO3FV 0x04 +#define SPPCR_IO2FV 0x02 +#define SPPCR_IO1FV 0x01 +#define SPBDCR_RXBC0 (1 << 0) +#define SPCMD_SCKDEN (1 << 15) +#define SPCMD_SLNDEN (1 << 14) +#define SPCMD_SPNDEN (1 << 13) +#define SPCMD_SSLKP (1 << 7) +#define SPCMD_BRDV0 (1 << 2) +#define SPCMD_INIT1 SPCMD_SCKDEN | SPCMD_SLNDEN | \ + SPCMD_SPNDEN | SPCMD_SSLKP | \ + SPCMD_BRDV0 +#define SPCMD_INIT2 SPCMD_SPNDEN | SPCMD_SSLKP | \ + SPCMD_BRDV0 +#define SPBFCR_TXRST (1 << 7) +#define SPBFCR_RXRST (1 << 6) + +/* SH QSPI register set */ +struct sh_qspi_regs { + unsigned char spcr; + unsigned char sslp; + unsigned char sppcr; + unsigned char spsr; + unsigned long spdr; + unsigned char spscr; + unsigned char spssr; + unsigned char spbr; + unsigned char spdcr; + unsigned char spckd; + unsigned char sslnd; + unsigned char spnd; + unsigned char dummy0; + unsigned short spcmd0; + unsigned short spcmd1; + unsigned short spcmd2; + unsigned short spcmd3; + unsigned char spbfcr; + unsigned char dummy1; + unsigned short spbdcr; + unsigned long spbmul0; + unsigned long spbmul1; + unsigned long spbmul2; + unsigned long spbmul3; +}; + +struct sh_qspi_slave { + struct spi_slave slave; + struct sh_qspi_regs *regs; +}; + +static inline struct sh_qspi_slave *to_sh_qspi(struct spi_slave *slave) +{ + return container_of(slave, struct sh_qspi_slave, slave); +} + +static void sh_qspi_init(struct sh_qspi_slave *ss) +{ + /* QSPI initialize */ + /* Set master mode only */ + writeb(SPCR_MSTR, &ss->regs->spcr); + + /* Set SSL signal level */ + writeb(0x00, &ss->regs->sslp); + + /* Set MOSI signal value when transfer is in idle state */ + writeb(SPPCR_IO3FV|SPPCR_IO2FV, &ss->regs->sppcr); + + /* Set bit rate. See 58.3.8 Quad Serial Peripheral Interface */ + writeb(0x01, &ss->regs->spbr); + + /* Disable Dummy Data Transmission */ + writeb(0x00, &ss->regs->spdcr); + + /* Set clock delay value */ + writeb(0x00, &ss->regs->spckd); + + /* Set SSL negation delay value */ + writeb(0x00, &ss->regs->sslnd); + + /* Set next-access delay value */ + writeb(0x00, &ss->regs->spnd); + + /* Set equence command */ + writew(SPCMD_INIT2, &ss->regs->spcmd0); + + /* Reset transfer and receive Buffer */ + setbits_8(&ss->regs->spbfcr, SPBFCR_TXRST|SPBFCR_RXRST); + + /* Clear transfer and receive Buffer control bit */ + clrbits_8(&ss->regs->spbfcr, SPBFCR_TXRST|SPBFCR_RXRST); + + /* Set equence control method. Use equence0 only */ + writeb(0x00, &ss->regs->spscr); + + /* Enable SPI function */ + setbits_8(&ss->regs->spcr, SPCR_SPE); +} + +int spi_cs_is_valid(unsigned int bus, unsigned int cs) +{ + return 1; +} + +void spi_cs_activate(struct spi_slave *slave) +{ + struct sh_qspi_slave *ss = to_sh_qspi(slave); + + /* Set master mode only */ + writeb(SPCR_MSTR, &ss->regs->spcr); + + /* Set command */ + writew(SPCMD_INIT1, &ss->regs->spcmd0); + + /* Reset transfer and receive Buffer */ + setbits_8(&ss->regs->spbfcr, SPBFCR_TXRST|SPBFCR_RXRST); + + /* Clear transfer and receive Buffer control bit */ + clrbits_8(&ss->regs->spbfcr, SPBFCR_TXRST|SPBFCR_RXRST); + + /* Set equence control method. Use equence0 only */ + writeb(0x00, &ss->regs->spscr); + + /* Enable SPI function */ + setbits_8(&ss->regs->spcr, SPCR_SPE); +} + +void spi_cs_deactivate(struct spi_slave *slave) +{ + struct sh_qspi_slave *ss = to_sh_qspi(slave); + + /* Disable SPI Function */ + clrbits_8(&ss->regs->spcr, SPCR_SPE); +} + +void spi_init(void) +{ + /* nothing to do */ +} + +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + struct sh_qspi_slave *ss; + + if (!spi_cs_is_valid(bus, cs)) + return NULL; + + ss = spi_alloc_slave(struct sh_qspi_slave, bus, cs); + if (!ss) { + printf("SPI_error: Fail to allocate sh_qspi_slave\n"); + return NULL; + } + + ss->regs = (struct sh_qspi_regs *)CONFIG_SH_QSPI_BASE; + + /* Init SH QSPI */ + sh_qspi_init(ss); + + return &ss->slave; +} + +void spi_free_slave(struct spi_slave *slave) +{ + struct sh_qspi_slave *spi = to_sh_qspi(slave); + + free(spi); +} + +int spi_claim_bus(struct spi_slave *slave) +{ + return 0; +} + +void spi_release_bus(struct spi_slave *slave) +{ +} + +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, + void *din, unsigned long flags) +{ + struct sh_qspi_slave *ss = to_sh_qspi(slave); + unsigned long nbyte; + int ret = 0; + unsigned char dtdata = 0, drdata; + unsigned char *tdata = &dtdata, *rdata = &drdata; + unsigned long *spbmul0 = &ss->regs->spbmul0; + + if (dout == NULL && din == NULL) { + if (flags & SPI_XFER_END) + spi_cs_deactivate(slave); + return 0; + } + + if (bitlen % 8) { + printf("%s: bitlen is not 8bit alined %d", __func__, bitlen); + return 1; + } + + nbyte = bitlen / 8; + + if (flags & SPI_XFER_BEGIN) { + spi_cs_activate(slave); + + /* Set 1048576 byte */ + writel(0x100000, spbmul0); + } + + if (flags & SPI_XFER_END) + writel(nbyte, spbmul0); + + if (dout != NULL) + tdata = (unsigned char *)dout; + + if (din != NULL) + rdata = din; + + while (nbyte > 0) { + while (!(readb(&ss->regs->spsr) & SPSR_SPTEF)) { + if (ctrlc()) { + puts("abort\n"); + return 1; + } + udelay(10); + } + + writeb(*tdata, (unsigned char *)(&ss->regs->spdr)); + + while ((readw(&ss->regs->spbdcr) != SPBDCR_RXBC0)) { + if (ctrlc()) { + puts("abort\n"); + return 1; + } + udelay(1); + } + + while (!(readb(&ss->regs->spsr) & SPSR_SPRFF)) { + if (ctrlc()) { + puts("abort\n"); + return 1; + } + udelay(10); + } + + *rdata = readb((unsigned char *)(&ss->regs->spdr)); + + if (dout != NULL) + tdata++; + if (din != NULL) + rdata++; + + nbyte--; + } + + if (flags & SPI_XFER_END) + spi_cs_deactivate(slave); + + return ret; +} -- cgit v1.3.1 From 60acde43d71cf0701b1124998bf4ab457c6640b6 Mon Sep 17 00:00:00 2001 From: Yen Lin Date: Wed, 18 Dec 2013 11:18:46 -0700 Subject: spi: tegra: clear RDY bit prior to every transfer The RDY bit indicates that a transfer is complete. This needs to be cleared by SW before every single HW transaction, rather than only at the start of each SW transaction (those being made up of n HW transactions). It seems that earlier HW may have cleared this bit autonomously when starting a new transfer, and hence this code was not needed in practice. However, this is generally a good idea in all cases. In Tegra124, the HW behaviour appears to have changed, and SW must explicitly clear this bit. Otherwise, SW will believe that transfers have completed when they have not, and may e.g. read stale data from the RX FIFO. Signed-off-by: Yen Lin [swarren, rewrote commit description, unified duplicate RDY clearing code and moved it right before the start of the HW transaction, unconditionally exit loop after reading RX data, rather than checking if TX FIFO is empty, since it is guaranteed to be] Signed-off-by: Stephen Warren Reviewed-by: Jagannadha Sutradharudu Teki --- drivers/spi/tegra114_spi.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/tegra114_spi.c b/drivers/spi/tegra114_spi.c index 4d2af483d77..810fa4718ce 100644 --- a/drivers/spi/tegra114_spi.c +++ b/drivers/spi/tegra114_spi.c @@ -289,9 +289,6 @@ int tegra114_spi_xfer(struct spi_slave *slave, unsigned int bitlen, reg = readl(®s->fifo_status); writel(reg, ®s->fifo_status); - /* clear ready bit */ - setbits_le32(®s->xfer_status, SPI_XFER_STS_RDY); - clrsetbits_le32(®s->command1, SPI_CMD1_CS_SW_VAL, SPI_CMD1_RX_EN | SPI_CMD1_TX_EN | SPI_CMD1_LSBY_FE | (slave->cs << SPI_CMD1_CS_SEL_SHIFT)); @@ -305,7 +302,6 @@ int tegra114_spi_xfer(struct spi_slave *slave, unsigned int bitlen, /* handle data in 32-bit chunks */ while (num_bytes > 0) { int bytes; - int is_read = 0; int tm, i; tmpdout = 0; @@ -319,6 +315,9 @@ int tegra114_spi_xfer(struct spi_slave *slave, unsigned int bitlen, num_bytes -= bytes; + /* clear ready bit */ + setbits_le32(®s->xfer_status, SPI_XFER_STS_RDY); + clrsetbits_le32(®s->command1, SPI_CMD1_BIT_LEN_MASK << SPI_CMD1_BIT_LEN_SHIFT, (bytes * 8 - 1) << SPI_CMD1_BIT_LEN_SHIFT); @@ -329,20 +328,14 @@ int tegra114_spi_xfer(struct spi_slave *slave, unsigned int bitlen, * Wait for SPI transmit FIFO to empty, or to time out. * The RX FIFO status will be read and cleared last */ - for (tm = 0, is_read = 0; tm < SPI_TIMEOUT; ++tm) { + for (tm = 0; tm < SPI_TIMEOUT; ++tm) { u32 fifo_status, xfer_status; - fifo_status = readl(®s->fifo_status); - - /* We can exit when we've had both RX and TX activity */ - if (is_read && - (fifo_status & SPI_FIFO_STS_TX_FIFO_EMPTY)) - break; - xfer_status = readl(®s->xfer_status); if (!(xfer_status & SPI_XFER_STS_RDY)) continue; + fifo_status = readl(®s->fifo_status); if (fifo_status & SPI_FIFO_STS_ERR) { debug("%s: got a fifo error: ", __func__); if (fifo_status & SPI_FIFO_STS_TX_FIFO_OVF) @@ -367,7 +360,6 @@ int tegra114_spi_xfer(struct spi_slave *slave, unsigned int bitlen, if (!(fifo_status & SPI_FIFO_STS_RX_FIFO_EMPTY)) { tmpdin = readl(®s->rx_fifo); - is_read = 1; /* swap bytes read in */ if (din != NULL) { @@ -377,6 +369,9 @@ int tegra114_spi_xfer(struct spi_slave *slave, unsigned int bitlen, } din += bytes; } + + /* We can exit when we've had both RX and TX */ + break; } } -- cgit v1.3.1 From 4fb127898e46f0adf9fcca3cfae0987975ef34ec Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Mon, 9 Dec 2013 16:20:13 +0100 Subject: dfu: Export allocated dfu buffer size The method for exporting size of allocated buffer is provided. It is afterwards used by USB's dfu function code. Signed-off-by: Lukasz Majewski --- drivers/dfu/dfu.c | 5 +++++ include/dfu.h | 1 + 2 files changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c index 1eb92e54176..07011e99a85 100644 --- a/drivers/dfu/dfu.c +++ b/drivers/dfu/dfu.c @@ -74,6 +74,11 @@ unsigned char *dfu_free_buf(void) return dfu_buf; } +unsigned long dfu_get_buf_size(void) +{ + return dfu_buf_size; +} + unsigned char *dfu_get_buf(void) { char *s; diff --git a/include/dfu.h b/include/dfu.h index cc140449271..9a50721104c 100644 --- a/include/dfu.h +++ b/include/dfu.h @@ -131,6 +131,7 @@ bool dfu_reset(void); int dfu_init_env_entities(char *interface, int dev); unsigned char *dfu_get_buf(void); unsigned char *dfu_free_buf(void); +unsigned long dfu_get_buf_size(void); int dfu_read(struct dfu_entity *de, void *buf, int size, int blk_seq_num); int dfu_write(struct dfu_entity *de, void *buf, int size, int blk_seq_num); -- cgit v1.3.1 From 33fac4a6a23b595a2a3cdfa76eddde98d48947b4 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Mon, 9 Dec 2013 16:20:14 +0100 Subject: usb: dfu: f_dfu: Provide infrastructure to adjust DFU's Poll Timeout value It is necessary to deter the host from sending subsequent DFU_GETSTATUS request in the case of e.g. writing the buffer to medium. Here the timeout is increased when we fill up the whole buffer. This delay allows eMMC memory to perform its internal operations. Otherwise we end up with HOST's error regarding GET_STATUS receive timeout. Signed-off-by: Lukasz Majewski --- drivers/usb/gadget/f_dfu.c | 39 ++++++++++++++++++++++++++++++++++++--- drivers/usb/gadget/f_dfu.h | 2 ++ include/dfu.h | 3 +++ 3 files changed, 41 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c index 37d04a19285..b4b4aa4f5b2 100644 --- a/drivers/usb/gadget/f_dfu.c +++ b/drivers/usb/gadget/f_dfu.c @@ -40,6 +40,7 @@ struct f_dfu { /* Send/received block number is handy for data integrity check */ int blk_seq_num; + unsigned int poll_timeout; }; typedef int (*dfu_state_fn) (struct f_dfu *, @@ -128,6 +129,33 @@ static struct usb_gadget_strings *dfu_strings[] = { NULL, }; +static void dfu_set_poll_timeout(struct dfu_status *dstat, unsigned int ms) +{ + /* + * The bwPollTimeout DFU_GETSTATUS request payload provides information + * about minimum time, in milliseconds, that the host should wait before + * sending a subsequent DFU_GETSTATUS request + * + * This permits the device to vary the delay depending on its need to + * erase or program the memory + * + */ + + unsigned char *p = (unsigned char *)&ms; + + if (!ms || (ms & ~DFU_POLL_TIMEOUT_MASK)) { + dstat->bwPollTimeout[0] = 0; + dstat->bwPollTimeout[1] = 0; + dstat->bwPollTimeout[2] = 0; + + return; + } + + dstat->bwPollTimeout[0] = *p++; + dstat->bwPollTimeout[1] = *p++; + dstat->bwPollTimeout[2] = *p; +} + /*-------------------------------------------------------------------------*/ static void dnload_request_complete(struct usb_ep *ep, struct usb_request *req) @@ -157,11 +185,15 @@ static void handle_getstatus(struct usb_request *req) break; } + dfu_set_poll_timeout(dstat, 0); + + if (f_dfu->poll_timeout) + if (!(f_dfu->blk_seq_num % + (dfu_get_buf_size() / DFU_USB_BUFSIZ))) + dfu_set_poll_timeout(dstat, f_dfu->poll_timeout); + /* send status response */ dstat->bStatus = f_dfu->dfu_status; - dstat->bwPollTimeout[0] = 0; - dstat->bwPollTimeout[1] = 0; - dstat->bwPollTimeout[2] = 0; dstat->bState = f_dfu->dfu_state; dstat->iString = 0; } @@ -725,6 +757,7 @@ static int dfu_bind_config(struct usb_configuration *c) f_dfu->usb_function.disable = dfu_disable; f_dfu->usb_function.strings = dfu_generic_strings, f_dfu->usb_function.setup = dfu_handle, + f_dfu->poll_timeout = DFU_DEFAULT_POLL_TIMEOUT; status = usb_add_function(c, &f_dfu->usb_function); if (status) diff --git a/drivers/usb/gadget/f_dfu.h b/drivers/usb/gadget/f_dfu.h index cc2c45567b6..0c29954add7 100644 --- a/drivers/usb/gadget/f_dfu.h +++ b/drivers/usb/gadget/f_dfu.h @@ -82,4 +82,6 @@ struct dfu_function_descriptor { __le16 wTransferSize; __le16 bcdDFUVersion; } __packed; + +#define DFU_POLL_TIMEOUT_MASK (0xFFFFFFUL) #endif /* __F_DFU_H_ */ diff --git a/include/dfu.h b/include/dfu.h index 9a50721104c..f973426aa90 100644 --- a/include/dfu.h +++ b/include/dfu.h @@ -77,6 +77,9 @@ static inline unsigned int get_mmc_blk_size(int dev) #ifndef CONFIG_SYS_DFU_MAX_FILE_SIZE #define CONFIG_SYS_DFU_MAX_FILE_SIZE CONFIG_SYS_DFU_DATA_BUF_SIZE #endif +#ifndef DFU_DEFAULT_POLL_TIMEOUT +#define DFU_DEFAULT_POLL_TIMEOUT 0 +#endif struct dfu_entity { char name[DFU_NAME_SIZE]; -- cgit v1.3.1 From 77b95042889c958c0da5a96a093aeb5a605ea3b4 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Mon, 9 Dec 2013 16:20:15 +0100 Subject: usb: f_dfu: cosmetic: Code cleanup Code cleanup for dfu_bind_config function Signed-off-by: Lukasz Majewski --- drivers/usb/gadget/f_dfu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c index b4b4aa4f5b2..a045864d730 100644 --- a/drivers/usb/gadget/f_dfu.c +++ b/drivers/usb/gadget/f_dfu.c @@ -755,8 +755,8 @@ static int dfu_bind_config(struct usb_configuration *c) f_dfu->usb_function.unbind = dfu_unbind; f_dfu->usb_function.set_alt = dfu_set_alt; f_dfu->usb_function.disable = dfu_disable; - f_dfu->usb_function.strings = dfu_generic_strings, - f_dfu->usb_function.setup = dfu_handle, + f_dfu->usb_function.strings = dfu_generic_strings; + f_dfu->usb_function.setup = dfu_handle; f_dfu->poll_timeout = DFU_DEFAULT_POLL_TIMEOUT; status = usb_add_function(c, &f_dfu->usb_function); -- cgit v1.3.1 From 8fb83547b93cd30a803eca1fec005b3d2b86a21f Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 13 Dec 2013 23:36:33 +0100 Subject: usb: ehci-pci: Clarify and cleanup the EHCI controller detection The detection function of the EHCI PCI controller was really cryptic, add a beefy comment and clean the portion of the code up a bit. No change in the logic of the code. Signed-off-by: Marek Vasut Cc: Simon Glass --- drivers/usb/host/ehci-pci.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 7a1ffe5e28b..991b19998b7 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -54,9 +54,31 @@ static pci_dev_t ehci_find_class(int index) bdf += PCI_BDF(0, 0, 1)) { pci_read_config_dword(bdf, PCI_CLASS_REVISION, &class); - if ((class >> 8 == PCI_CLASS_SERIAL_USB_EHCI) - && !index--) - return bdf; + class >>= 8; + /* + * Here be dragons! In case we have multiple + * PCI EHCI controllers, this function will + * be called multiple times as well. This + * function will scan the PCI busses, always + * starting from bus 0, device 0, function 0, + * until it finds an USB controller. The USB + * stack gives us an 'index' of a controller + * that is currently being registered, which + * is a number, starting from 0 and growing + * in ascending order as controllers are added. + * To avoid probing the same controller in tne + * subsequent runs of this function, we will + * skip 'index - 1' detected controllers and + * report the index'th controller. + */ + if (class != PCI_CLASS_SERIAL_USB_EHCI) + continue; + if (index) { + index--; + continue; + } + /* Return index'th controller. */ + return bdf; } } } -- cgit v1.3.1 From 1e1be6d478c7c2cddf97e2623dd5c4c10bc23020 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 14 Dec 2013 02:03:11 +0100 Subject: usb: ehci: Do not de-init uninited controllers In case the controller is not initialized, we shall not de-initialize it. As the control structure will not be filled, we will produce a null ptr dereference if the controller is not inited. Signed-off-by: Marek Vasut Cc: Simon Glass --- drivers/usb/host/ehci-hcd.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 8bd1eb8a998..3ef204d6abc 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -201,6 +201,9 @@ static int ehci_shutdown(struct ehci_ctrl *ctrl) int i, ret = 0; uint32_t cmd, reg; + if (!ctrl || !ctrl->hcor) + return -EINVAL; + cmd = ehci_readl(&ctrl->hcor->or_usbcmd); cmd &= ~(CMD_PSE | CMD_ASE); ehci_writel(&ctrl->hcor->or_usbcmd, cmd); -- cgit v1.3.1 From eb63218b9b95a59baa8b241f3a88e4415dabf833 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 14 Dec 2013 02:04:52 +0100 Subject: usb: ehci: Fix register access Fix the register access in EHCI HCD. We need to use address of the register as an ehci_writel() argument. Signed-off-by: Marek Vasut Cc: Simon Glass --- drivers/usb/host/ehci-hcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 3ef204d6abc..17187caed48 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -948,7 +948,7 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) #endif /* Set the high address word (aka segment) for 64-bit controller */ if (ehci_readl(&ehcic[index].hccr->cr_hccparams) & 1) - ehci_writel(ehcic[index].hcor->or_ctrldssegment, 0); + ehci_writel(&ehcic[index].hcor->or_ctrldssegment, 0); qh_list = &ehcic[index].qh_list; -- cgit v1.3.1 From ac5cce38de8f97a120b8c98f34be0d5eec50a6fb Mon Sep 17 00:00:00 2001 From: "Poddar, Sourav" Date: Thu, 14 Nov 2013 21:01:15 +0530 Subject: driver: mtd: sf_ops: claim bus while doing memcpy claim spi bus while doing memory copy, this will set up the spi controller device control register before doing a memory read. Signed-off-by: Sourav Poddar Tested-by: Yebio Mesfin Reviewed-by: Jagannadha Sutradharudu Teki --- drivers/mtd/spi/sf_ops.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c index 108665f4415..e316a692a8d 100644 --- a/drivers/mtd/spi/sf_ops.c +++ b/drivers/mtd/spi/sf_ops.c @@ -273,9 +273,15 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset, /* Handle memory-mapped SPI */ if (flash->memory_map) { + ret = spi_claim_bus(flash->spi); + if (ret) { + debug("SF: unable to claim SPI bus\n"); + return ret; + } spi_xfer(flash->spi, 0, NULL, NULL, SPI_XFER_MMAP); memcpy(data, flash->memory_map + offset, len); spi_xfer(flash->spi, 0, NULL, NULL, SPI_XFER_MMAP_END); + spi_release_bus(flash->spi); return 0; } -- cgit v1.3.1 From 9b56942f7d2f67e620662cfeb4269a9a938d55da Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 26 Dec 2013 01:01:24 +0100 Subject: mtd: onenand: Fix unaligned access Fix unaligned access in OneNAND core. The problem is that the ffchars[] array is an array of "unsigned char", but in onenand_write_ops_nolock() can be passed to the memcpy_16() function. The memcpy_16() function will treat the buffer as an array of "unsigned short", thus triggering unaligned access if the compiler decided ffchars[] to be not aligned. I managed to trigger the problem with regular ELDK 5.4 GCC compiler. Signed-off-by: Marek Vasut Cc: Albert Aribaud Cc: Scott Wood Cc: Tom Rini --- drivers/mtd/onenand/onenand_base.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 979e4af7c5f..e33e8d38e7a 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -91,7 +91,13 @@ static struct nand_ecclayout onenand_oob_32 = { .oobfree = { {2, 3}, {14, 2}, {18, 3}, {30, 2} } }; -static const unsigned char ffchars[] = { +/* + * Warning! This array is used with the memcpy_16() function, thus + * it must be aligned to 2 bytes. GCC can make this array unaligned + * as the array is made of unsigned char, which memcpy16() doesn't + * like and will cause unaligned access. + */ +static const unsigned char __aligned(2) ffchars[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 16 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -- cgit v1.3.1 From 456ccfdf0d5eefc153b143bd13731a59e2d71585 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Fri, 20 Dec 2013 11:19:33 -0500 Subject: TI:omap3: Drop omap3_zoom2 The omap3_zoom2 board has not been updated for a correct CONFIG_SYS_HZ and Tom Rix's email has long been bouncing. Signed-off-by: Tom Rini --- board/logicpd/zoom2/Makefile | 11 -- board/logicpd/zoom2/config.mk | 17 --- board/logicpd/zoom2/debug_board.c | 44 ------- board/logicpd/zoom2/led.c | 116 ------------------ board/logicpd/zoom2/zoom2.c | 183 ---------------------------- board/logicpd/zoom2/zoom2.h | 142 ---------------------- board/logicpd/zoom2/zoom2_serial.c | 130 -------------------- board/logicpd/zoom2/zoom2_serial.h | 59 --------- boards.cfg | 1 - drivers/serial/ns16550.c | 5 +- include/configs/omap3_zoom2.h | 237 ------------------------------------- 11 files changed, 2 insertions(+), 943 deletions(-) delete mode 100644 board/logicpd/zoom2/Makefile delete mode 100644 board/logicpd/zoom2/config.mk delete mode 100644 board/logicpd/zoom2/debug_board.c delete mode 100644 board/logicpd/zoom2/led.c delete mode 100644 board/logicpd/zoom2/zoom2.c delete mode 100644 board/logicpd/zoom2/zoom2.h delete mode 100644 board/logicpd/zoom2/zoom2_serial.c delete mode 100644 board/logicpd/zoom2/zoom2_serial.h delete mode 100644 include/configs/omap3_zoom2.h (limited to 'drivers') diff --git a/board/logicpd/zoom2/Makefile b/board/logicpd/zoom2/Makefile deleted file mode 100644 index 8ec5f256133..00000000000 --- a/board/logicpd/zoom2/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# (C) Copyright 2000, 2001, 2002 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-y := zoom2.o -obj-y += debug_board.o -obj-y += zoom2_serial.o -obj-$(CONFIG_STATUS_LED) += led.o diff --git a/board/logicpd/zoom2/config.mk b/board/logicpd/zoom2/config.mk deleted file mode 100644 index 1c382f71893..00000000000 --- a/board/logicpd/zoom2/config.mk +++ /dev/null @@ -1,17 +0,0 @@ -# -# (C) Copyright 2009 -# Texas Instruments, -# -# Zoom II uses OMAP3 (ARM-CortexA8) CPU -# see http://www.ti.com/ for more information on Texas Instruments -# -# SPDX-License-Identifier: GPL-2.0+ -# -# Physical Address: -# 0x80000000 (bank0) -# 0xA0000000 (bank1) -# Linux-Kernel is expected to be at 0x80008000, entry 0x80008000 -# (mem base + reserved) - -# For use with external or internal boots. -CONFIG_SYS_TEXT_BASE = 0x80008000 diff --git a/board/logicpd/zoom2/debug_board.c b/board/logicpd/zoom2/debug_board.c deleted file mode 100644 index 071f41074ba..00000000000 --- a/board/logicpd/zoom2/debug_board.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2009 Wind River Systems, Inc. - * Tom Rix - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include -#include -#include -#include -#include - -#define DEBUG_BOARD_CONNECTED 1 -#define DEBUG_BOARD_NOT_CONNECTED 0 - -static int debug_board_connected = DEBUG_BOARD_CONNECTED; - -static void zoom2_debug_board_detect (void) -{ - int val = 0; - - if (!gpio_request(158, "")) { - /* - * GPIO to query for debug board - * 158 db board query - */ - gpio_direction_input(158); - val = gpio_get_value(158); - } - - if (!val) - debug_board_connected = DEBUG_BOARD_NOT_CONNECTED; -} - -int zoom2_debug_board_connected (void) -{ - static int first_time = 1; - - if (first_time) { - zoom2_debug_board_detect (); - first_time = 0; - } - return debug_board_connected; -} diff --git a/board/logicpd/zoom2/led.c b/board/logicpd/zoom2/led.c deleted file mode 100644 index 5d37ac15f2f..00000000000 --- a/board/logicpd/zoom2/led.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2009 Wind River Systems, Inc. - * Tom Rix - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include -#include -#include -#include -#include -#include - -static unsigned int saved_state[2] = {STATUS_LED_OFF, STATUS_LED_OFF}; - -/* - * GPIO LEDs - * 173 red - * 154 blue - * 61 blue2 - */ -#define ZOOM2_LED_RED 173 -#define ZOOM2_LED_BLUE 154 -#define ZOOM2_LED_BLUE2 61 - -void red_led_off(void) -{ - /* red */ - if (!gpio_request(ZOOM2_LED_RED, "")) { - gpio_direction_output(ZOOM2_LED_RED, 0); - gpio_set_value(ZOOM2_LED_RED, 0); - } - saved_state[STATUS_LED_RED] = STATUS_LED_OFF; -} - -void blue_led_off(void) -{ - /* blue */ - if (!gpio_request(ZOOM2_LED_BLUE, "")) { - gpio_direction_output(ZOOM2_LED_BLUE, 0); - gpio_set_value(ZOOM2_LED_BLUE, 0); - } - - /* blue 2 */ - if (!gpio_request(ZOOM2_LED_BLUE2, "")) { - gpio_direction_output(ZOOM2_LED_BLUE2, 0); - gpio_set_value(ZOOM2_LED_BLUE2, 0); - } - saved_state[STATUS_LED_BLUE] = STATUS_LED_OFF; -} - -void red_led_on(void) -{ - blue_led_off(); - - /* red */ - if (!gpio_request(ZOOM2_LED_RED, "")) { - gpio_direction_output(ZOOM2_LED_RED, 0); - gpio_set_value(ZOOM2_LED_RED, 1); - } - saved_state[STATUS_LED_RED] = STATUS_LED_ON; -} - -void blue_led_on(void) -{ - red_led_off(); - - /* blue */ - if (!gpio_request(ZOOM2_LED_BLUE, "")) { - gpio_direction_output(ZOOM2_LED_BLUE, 0); - gpio_set_value(ZOOM2_LED_BLUE, 1); - } - - /* blue 2 */ - if (!gpio_request(ZOOM2_LED_BLUE2, "")) { - gpio_direction_output(ZOOM2_LED_BLUE2, 0); - gpio_set_value(ZOOM2_LED_BLUE2, 1); - } - - saved_state[STATUS_LED_BLUE] = STATUS_LED_ON; -} - -void __led_init (led_id_t mask, int state) -{ - __led_set (mask, state); -} - -void __led_toggle (led_id_t mask) -{ - if (STATUS_LED_BLUE == mask) { - if (STATUS_LED_ON == saved_state[STATUS_LED_BLUE]) - blue_led_off(); - else - blue_led_on(); - } else if (STATUS_LED_RED == mask) { - if (STATUS_LED_ON == saved_state[STATUS_LED_RED]) - red_led_off(); - else - red_led_on(); - } -} - -void __led_set (led_id_t mask, int state) -{ - if (STATUS_LED_BLUE == mask) { - if (STATUS_LED_ON == state) - blue_led_on(); - else - blue_led_off(); - } else if (STATUS_LED_RED == mask) { - if (STATUS_LED_ON == state) - red_led_on(); - else - red_led_off(); - } -} diff --git a/board/logicpd/zoom2/zoom2.c b/board/logicpd/zoom2/zoom2.c deleted file mode 100644 index e14de04695a..00000000000 --- a/board/logicpd/zoom2/zoom2.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2009 Wind River Systems, Inc. - * Tom Rix - * - * Derived from Zoom1 code by - * Nishanth Menon - * Sunil Kumar - * Shashi Ranjan - * Richard Woodruff - * Syed Mohammed Khasim - * - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include -#include -#ifdef CONFIG_STATUS_LED -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include "zoom2.h" -#include "zoom2_serial.h" - -DECLARE_GLOBAL_DATA_PTR; - -/* - * This the the zoom2, board specific, gpmc configuration for the - * quad uart on the debug board. The more general gpmc configurations - * are setup at the cpu level in arch/arm/cpu/armv7/omap3/mem.c - * - * The details of the setting of the serial gpmc setup are not available. - * The values were provided by another party. - */ -static u32 gpmc_serial_TL16CP754C[GPMC_MAX_REG] = { - 0x00011000, - 0x001F1F01, - 0x00080803, - 0x1D091D09, - 0x041D1F1F, - 0x1D0904C4, 0 -}; - -/* Used to track the revision of the board */ -static zoom2_revision revision = ZOOM2_REVISION_UNKNOWN; - -/* - * Routine: zoom2_get_revision - * Description: Return the revision of the Zoom2 this code is running on. - */ -zoom2_revision zoom2_get_revision(void) -{ - return revision; -} - -/* - * Routine: zoom2_identify - * Description: Detect which version of Zoom2 we are running on. - */ -void zoom2_identify(void) -{ - /* - * To check for production board vs beta board, - * check if gpio 94 is clear. - * - * No way yet to check for alpha board identity. - * Alpha boards were produced in very limited quantities - * and they are not commonly used. They are mentioned here - * only for completeness. - */ - if (!gpio_request(94, "")) { - unsigned int val; - - gpio_direction_input(94); - val = gpio_get_value(94); - - if (val) - revision = ZOOM2_REVISION_BETA; - else - revision = ZOOM2_REVISION_PRODUCTION; - } - - printf("Board revision "); - switch (revision) { - case ZOOM2_REVISION_PRODUCTION: - printf("Production\n"); - break; - case ZOOM2_REVISION_BETA: - printf("Beta\n"); - break; - default: - printf("Unknown\n"); - break; - } -} - -/* - * Routine: board_init - * Description: Early hardware init. - */ -int board_init (void) -{ - u32 *gpmc_config; - - gpmc_init (); /* in SRAM or SDRAM, finish GPMC */ - - /* Configure console support on zoom2 */ - gpmc_config = gpmc_serial_TL16CP754C; - enable_gpmc_cs_config(gpmc_config, &gpmc_cfg->cs[3], - SERIAL_TL16CP754C_BASE, GPMC_SIZE_16M); - - /* board id for Linux */ - gd->bd->bi_arch_number = MACH_TYPE_OMAP_ZOOM2; - /* boot param addr */ - gd->bd->bi_boot_params = (OMAP34XX_SDRC_CS0 + 0x100); - -#if defined(CONFIG_STATUS_LED) && defined(STATUS_LED_BOOT) - status_led_set (STATUS_LED_BOOT, STATUS_LED_ON); -#endif - return 0; -} - -/* - * Routine: misc_init_r - * Description: Configure zoom board specific configurations - */ -int misc_init_r(void) -{ - zoom2_identify(); - twl4030_power_init(); - twl4030_led_init(TWL4030_LED_LEDEN_LEDAON | TWL4030_LED_LEDEN_LEDBON); - dieid_num_r(); - - /* - * Board Reset - * The board is reset by holding the the large button - * on the top right side of the main board for - * eight seconds. - * - * There are reported problems of some beta boards - * continously resetting. For those boards, disable resetting. - */ - if (ZOOM2_REVISION_PRODUCTION <= zoom2_get_revision()) - twl4030_power_reset_init(); - - return 0; -} - -/* - * Routine: set_muxconf_regs - * Description: Setting up the configuration Mux registers specific to the - * hardware. Many pins need to be moved from protect to primary - * mode. - */ -void set_muxconf_regs (void) -{ - /* platform specific muxes */ - MUX_ZOOM2 (); -} - -#ifdef CONFIG_GENERIC_MMC -int board_mmc_init(bd_t *bis) -{ - return omap_mmc_init(0, 0, 0, -1, -1); -} -#endif - -#ifdef CONFIG_CMD_NET -int board_eth_init(bd_t *bis) -{ - int rc = 0; -#ifdef CONFIG_LAN91C96 - rc = lan91c96_initialize(0, CONFIG_LAN91C96_BASE); -#endif - return rc; -} -#endif diff --git a/board/logicpd/zoom2/zoom2.h b/board/logicpd/zoom2/zoom2.h deleted file mode 100644 index 850c790a08d..00000000000 --- a/board/logicpd/zoom2/zoom2.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2009 Wind River Systems, Inc. - * Tom Rix - * - * Derived from: board/omap3/zoom1/zoom1.h - * Nishanth Menon - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#ifndef _BOARD_ZOOM2_H_ -#define _BOARD_ZOOM2_H_ - -const omap3_sysinfo sysinfo = { - DDR_STACKED, - "OMAP3 Zoom2 ", - "NAND", -}; - -typedef enum { - ZOOM2_REVISION_UNKNOWN = 0, - ZOOM2_REVISION_ALPHA, - ZOOM2_REVISION_BETA, - ZOOM2_REVISION_PRODUCTION -} zoom2_revision; - -zoom2_revision zoom2_get_revision(void); - -/* - * IEN - Input Enable - * IDIS - Input Disable - * PTD - Pull type Down - * PTU - Pull type Up - * DIS - Pull type selection is inactive - * EN - Pull type selection is active - * M0 - Mode 0 - * The commented string gives the final mux configuration for that pin - */ -#define MUX_ZOOM2() \ - /* SDRC*/\ - MUX_VAL(CP(SDRC_D0), (IEN | PTD | DIS | M0)) /* SDRC_D0 */\ - MUX_VAL(CP(SDRC_D1), (IEN | PTD | DIS | M0)) /* SDRC_D1 */\ - MUX_VAL(CP(SDRC_D2), (IEN | PTD | DIS | M0)) /* SDRC_D2 */\ - MUX_VAL(CP(SDRC_D3), (IEN | PTD | DIS | M0)) /* SDRC_D3 */\ - MUX_VAL(CP(SDRC_D4), (IEN | PTD | DIS | M0)) /* SDRC_D4 */\ - MUX_VAL(CP(SDRC_D5), (IEN | PTD | DIS | M0)) /* SDRC_D5 */\ - MUX_VAL(CP(SDRC_D6), (IEN | PTD | DIS | M0)) /* SDRC_D6 */\ - MUX_VAL(CP(SDRC_D7), (IEN | PTD | DIS | M0)) /* SDRC_D7 */\ - MUX_VAL(CP(SDRC_D8), (IEN | PTD | DIS | M0)) /* SDRC_D8 */\ - MUX_VAL(CP(SDRC_D9), (IEN | PTD | DIS | M0)) /* SDRC_D9 */\ - MUX_VAL(CP(SDRC_D10), (IEN | PTD | DIS | M0)) /* SDRC_D10 */\ - MUX_VAL(CP(SDRC_D11), (IEN | PTD | DIS | M0)) /* SDRC_D11 */\ - MUX_VAL(CP(SDRC_D12), (IEN | PTD | DIS | M0)) /* SDRC_D12 */\ - MUX_VAL(CP(SDRC_D13), (IEN | PTD | DIS | M0)) /* SDRC_D13 */\ - MUX_VAL(CP(SDRC_D14), (IEN | PTD | DIS | M0)) /* SDRC_D14 */\ - MUX_VAL(CP(SDRC_D15), (IEN | PTD | DIS | M0)) /* SDRC_D15 */\ - MUX_VAL(CP(SDRC_D16), (IEN | PTD | DIS | M0)) /* SDRC_D16 */\ - MUX_VAL(CP(SDRC_D17), (IEN | PTD | DIS | M0)) /* SDRC_D17 */\ - MUX_VAL(CP(SDRC_D18), (IEN | PTD | DIS | M0)) /* SDRC_D18 */\ - MUX_VAL(CP(SDRC_D19), (IEN | PTD | DIS | M0)) /* SDRC_D19 */\ - MUX_VAL(CP(SDRC_D20), (IEN | PTD | DIS | M0)) /* SDRC_D20 */\ - MUX_VAL(CP(SDRC_D21), (IEN | PTD | DIS | M0)) /* SDRC_D21 */\ - MUX_VAL(CP(SDRC_D22), (IEN | PTD | DIS | M0)) /* SDRC_D22 */\ - MUX_VAL(CP(SDRC_D23), (IEN | PTD | DIS | M0)) /* SDRC_D23 */\ - MUX_VAL(CP(SDRC_D24), (IEN | PTD | DIS | M0)) /* SDRC_D24 */\ - MUX_VAL(CP(SDRC_D25), (IEN | PTD | DIS | M0)) /* SDRC_D25 */\ - MUX_VAL(CP(SDRC_D26), (IEN | PTD | DIS | M0)) /* SDRC_D26 */\ - MUX_VAL(CP(SDRC_D27), (IEN | PTD | DIS | M0)) /* SDRC_D27 */\ - MUX_VAL(CP(SDRC_D28), (IEN | PTD | DIS | M0)) /* SDRC_D28 */\ - MUX_VAL(CP(SDRC_D29), (IEN | PTD | DIS | M0)) /* SDRC_D29 */\ - MUX_VAL(CP(SDRC_D30), (IEN | PTD | DIS | M0)) /* SDRC_D30 */\ - MUX_VAL(CP(SDRC_D31), (IEN | PTD | DIS | M0)) /* SDRC_D31 */\ - MUX_VAL(CP(SDRC_CLK), (IEN | PTD | DIS | M0)) /* SDRC_CLK */\ - MUX_VAL(CP(SDRC_DQS0), (IEN | PTD | DIS | M0)) /* SDRC_DQS0 */\ - MUX_VAL(CP(SDRC_DQS1), (IEN | PTD | DIS | M0)) /* SDRC_DQS1 */\ - MUX_VAL(CP(SDRC_DQS2), (IEN | PTD | DIS | M0)) /* SDRC_DQS2 */\ - MUX_VAL(CP(SDRC_DQS3), (IEN | PTD | DIS | M0)) /* SDRC_DQS3 */\ -/* GPMC */\ - MUX_VAL(CP(GPMC_A1), (IDIS | PTD | DIS | M0)) /* GPMC_A1 */\ - MUX_VAL(CP(GPMC_A2), (IDIS | PTD | DIS | M0)) /* GPMC_A2 */\ - MUX_VAL(CP(GPMC_A3), (IDIS | PTD | DIS | M0)) /* GPMC_A3 */\ - MUX_VAL(CP(GPMC_A4), (IDIS | PTD | DIS | M0)) /* GPMC_A4 */\ - MUX_VAL(CP(GPMC_A5), (IDIS | PTD | DIS | M0)) /* GPMC_A5 */\ - MUX_VAL(CP(GPMC_A6), (IDIS | PTD | DIS | M0)) /* GPMC_A6 */\ - MUX_VAL(CP(GPMC_A7), (IDIS | PTD | DIS | M0)) /* GPMC_A7 */\ - MUX_VAL(CP(GPMC_A8), (IDIS | PTD | DIS | M0)) /* GPMC_A8 */\ - MUX_VAL(CP(GPMC_A9), (IDIS | PTD | DIS | M0)) /* GPMC_A9 */\ - MUX_VAL(CP(GPMC_A10), (IDIS | PTD | DIS | M0)) /* GPMC_A10 */\ - MUX_VAL(CP(GPMC_D0), (IEN | PTD | DIS | M0)) /* GPMC_D0 */\ - MUX_VAL(CP(GPMC_D1), (IEN | PTD | DIS | M0)) /* GPMC_D1 */\ - MUX_VAL(CP(GPMC_D2), (IEN | PTD | DIS | M0)) /* GPMC_D2 */\ - MUX_VAL(CP(GPMC_D3), (IEN | PTD | DIS | M0)) /* GPMC_D3 */\ - MUX_VAL(CP(GPMC_D4), (IEN | PTD | DIS | M0)) /* GPMC_D4 */\ - MUX_VAL(CP(GPMC_D5), (IEN | PTD | DIS | M0)) /* GPMC_D5 */\ - MUX_VAL(CP(GPMC_D6), (IEN | PTD | DIS | M0)) /* GPMC_D6 */\ - MUX_VAL(CP(GPMC_D7), (IEN | PTD | DIS | M0)) /* GPMC_D7 */\ - MUX_VAL(CP(GPMC_D8), (IEN | PTD | DIS | M0)) /* GPMC_D8 */\ - MUX_VAL(CP(GPMC_D9), (IEN | PTD | DIS | M0)) /* GPMC_D9 */\ - MUX_VAL(CP(GPMC_D10), (IEN | PTD | DIS | M0)) /* GPMC_D10 */\ - MUX_VAL(CP(GPMC_D11), (IEN | PTD | DIS | M0)) /* GPMC_D11 */\ - MUX_VAL(CP(GPMC_D12), (IEN | PTD | DIS | M0)) /* GPMC_D12 */\ - MUX_VAL(CP(GPMC_D13), (IEN | PTD | DIS | M0)) /* GPMC_D13 */\ - MUX_VAL(CP(GPMC_D14), (IEN | PTD | DIS | M0)) /* GPMC_D14 */\ - MUX_VAL(CP(GPMC_D15), (IEN | PTD | DIS | M0)) /* GPMC_D15 */\ - MUX_VAL(CP(GPMC_NCS0), (IDIS | PTU | EN | M0)) /* GPMC_nCS0 */\ - MUX_VAL(CP(GPMC_NCS1), (IDIS | PTU | EN | M7)) /* GPMC_nCS1 */\ - MUX_VAL(CP(GPMC_NCS2), (IDIS | PTU | EN | M7)) /* GPMC_nCS2 */\ - MUX_VAL(CP(GPMC_NCS3), (IDIS | PTU | EN | M7)) /* GPMC_nCS3 */\ - MUX_VAL(CP(GPMC_NCS4), (IDIS | PTU | EN | M7)) /* GPMC_nCS4 */\ - MUX_VAL(CP(GPMC_NCS5), (IDIS | PTD | DIS | M7)) /* GPMC_nCS5 */\ - MUX_VAL(CP(GPMC_NCS6), (IEN | PTD | DIS | M7)) /* GPMC_nCS6 */\ - MUX_VAL(CP(GPMC_NCS7), (IEN | PTU | EN | M7)) /* GPMC_nCS7 */\ - MUX_VAL(CP(GPMC_CLK), (IDIS | PTD | DIS | M0)) /* GPMC_CLK */\ - MUX_VAL(CP(GPMC_NADV_ALE), (IDIS | PTD | DIS | M0)) /* GPMC_nADV_ALE */\ - MUX_VAL(CP(GPMC_NOE), (IDIS | PTD | DIS | M0)) /* GPMC_nOE */\ - MUX_VAL(CP(GPMC_NWE), (IDIS | PTD | DIS | M0)) /* GPMC_nWE */\ - MUX_VAL(CP(GPMC_NWP), (IDIS | PTU | DIS | M0)) /* GPMC_nWP */\ - MUX_VAL(CP(GPMC_NBE0_CLE), (IDIS | PTD | DIS | M0)) /* GPMC_nBE0_CLE */\ - MUX_VAL(CP(GPMC_NBE1), (IEN | PTD | DIS | M0)) /* GPMC_nBE1 */\ - MUX_VAL(CP(GPMC_WAIT0), (IEN | PTD | EN | M0)) /* GPMC_WAIT0 */\ - MUX_VAL(CP(GPMC_WAIT1), (IEN | PTU | EN | M0)) /* GPMC_WAIT1 */\ - MUX_VAL(CP(GPMC_WAIT2), (IEN | PTU | EN | M0)) /* GPMC_WAIT2 */\ - MUX_VAL(CP(GPMC_WAIT3), (IEN | PTU | EN | M0)) /* GPMC_WAIT3 */\ -/* IDCC modem Power On */\ - MUX_VAL(CP(CAM_D11), (IEN | PTU | EN | M4)) /* GPIO_110 */\ - MUX_VAL(CP(CAM_D4), (IEN | PTU | EN | M4)) /* GPIO_103 */\ -/* GPMC CS7 has LAN9211 device */\ - MUX_VAL(CP(GPMC_NCS7), (IDIS | PTU | EN | M0)) /* GPMC_nCS7 */\ - MUX_VAL(CP(MCBSP1_DX), (IEN | PTD | DIS | M4)) /* LAN9221 */\ - MUX_VAL(CP(MCSPI1_CS2), (IEN | PTD | EN | M0)) /* MCSPI1_CS2 */\ -/* GPMC CS3 has Serial TL16CP754C device */\ - MUX_VAL(CP(GPMC_NCS3), (IDIS | PTU | EN | M0)) /* GPMC_nCS3 */\ -/* Toggle Reset pin of TL16CP754C device */\ - MUX_VAL(CP(MCBSP4_CLKX), (IEN | PTU | EN | M4)) /* GPIO_152 */\ - udelay(10);\ - MUX_VAL(CP(MCBSP4_CLKX), (IEN | PTD | EN | M4)) /* GPIO_152 */\ - MUX_VAL(CP(SDRC_CKE1), (IDIS | PTU | EN | M0)) /* SDRC_CKE1 */\ -/* LEDS */\ - MUX_VAL(CP(MCSPI1_SOMI), (IEN | PTD | EN | M4)) /* GPIO_173 red */\ - MUX_VAL(CP(MCBSP4_DX), (IEN | PTD | EN | M4)) /* GPIO_154 blue */\ - MUX_VAL(CP(GPMC_NBE1), (IEN | PTD | EN | M4)) /* GPIO_61 blue2 */ - -#endif /* _BOARD_ZOOM2_H_ */ diff --git a/board/logicpd/zoom2/zoom2_serial.c b/board/logicpd/zoom2/zoom2_serial.c deleted file mode 100644 index 29592761161..00000000000 --- a/board/logicpd/zoom2/zoom2_serial.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2009 Wind River Systems, Inc. - * Tom Rix - * - * SPDX-License-Identifier: GPL-2.0+ - * - * This file was adapted from arch/powerpc/cpu/mpc5xxx/serial.c - */ - -#include -#include -#include -#include -#include "zoom2_serial.h" - -int quad_init_dev (unsigned long base) -{ - /* - * The Quad UART is on the debug board. - * Check if the debug board is attached before using the UART - */ - if (zoom2_debug_board_connected ()) { - NS16550_t com_port = (NS16550_t) base; - int baud_divisor = CONFIG_SYS_NS16550_CLK / 16 / - CONFIG_BAUDRATE; - - /* - * Zoom2 has a board specific initialization of its UART. - * This generic initialization has been copied from - * drivers/serial/ns16550.c. The macros have been expanded. - * - * Do the following instead of - * - * NS16550_init (com_port, clock_divisor); - */ - com_port->ier = 0x00; - - /* - * On Zoom2 board Set pre-scalar to 1 - * CLKSEL is GND => MCR[7] is 1 => preslr is 4 - * So change the prescl to 1 - */ - com_port->lcr = 0xBF; - com_port->fcr |= 0x10; - com_port->mcr &= 0x7F; - - /* This is generic ns16550.c setup */ - com_port->lcr = UART_LCR_BKSE | UART_LCR_8N1; - com_port->dll = 0; - com_port->dlm = 0; - com_port->lcr = UART_LCR_8N1; - com_port->mcr = UART_MCR_DTR | UART_MCR_RTS; - com_port->fcr = UART_FCR_FIFO_EN | UART_FCR_RXSR | - UART_FCR_TXSR; - com_port->lcr = UART_LCR_BKSE | UART_LCR_8N1; - com_port->dll = baud_divisor & 0xff; - com_port->dlm = (baud_divisor >> 8) & 0xff; - com_port->lcr = UART_LCR_8N1; - } - /* - * We have to lie here, otherwise the board init code will hang - * on the check - */ - return 0; -} - -void quad_putc_dev (unsigned long base, const char c) -{ - if (zoom2_debug_board_connected ()) { - - if (c == '\n') - quad_putc_dev (base, '\r'); - - NS16550_putc ((NS16550_t) base, c); - } else { - usbtty_putc(c); - } -} - -void quad_puts_dev (unsigned long base, const char *s) -{ - if (zoom2_debug_board_connected ()) { - while ((s != NULL) && (*s != '\0')) - quad_putc_dev (base, *s++); - } else { - usbtty_puts(s); - } -} - -int quad_getc_dev (unsigned long base) -{ - if (zoom2_debug_board_connected ()) - return NS16550_getc ((NS16550_t) base); - - return usbtty_getc(); -} - -int quad_tstc_dev (unsigned long base) -{ - if (zoom2_debug_board_connected ()) - return NS16550_tstc ((NS16550_t) base); - - return usbtty_tstc(); -} - -void quad_setbrg_dev (unsigned long base) -{ - if (zoom2_debug_board_connected ()) { - - int clock_divisor = CONFIG_SYS_NS16550_CLK / 16 / - CONFIG_BAUDRATE; - - NS16550_reinit ((NS16550_t) base, clock_divisor); - } -} - -QUAD_INIT (0) -QUAD_INIT (1) -QUAD_INIT (2) -QUAD_INIT (3) - -struct serial_device *default_serial_console(void) -{ - switch (ZOOM2_DEFAULT_SERIAL_DEVICE) { - case 0: return &zoom2_serial_device0; - case 1: return &zoom2_serial_device1; - case 2: return &zoom2_serial_device2; - case 3: return &zoom2_serial_device3; - } -} diff --git a/board/logicpd/zoom2/zoom2_serial.h b/board/logicpd/zoom2/zoom2_serial.h deleted file mode 100644 index 82244521ac5..00000000000 --- a/board/logicpd/zoom2/zoom2_serial.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2009 Wind River Systems, Inc. - * Tom Rix - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef ZOOM2_SERIAL_H -#define ZOOM2_SERIAL_H - -#include - -extern int zoom2_debug_board_connected (void); - -#define SERIAL_TL16CP754C_BASE 0x10000000 /* Zoom2 Serial chip address */ - -#define QUAD_BASE_0 SERIAL_TL16CP754C_BASE -#define QUAD_BASE_1 (SERIAL_TL16CP754C_BASE + 0x100) -#define QUAD_BASE_2 (SERIAL_TL16CP754C_BASE + 0x200) -#define QUAD_BASE_3 (SERIAL_TL16CP754C_BASE + 0x300) - -#define QUAD_INIT(n) \ -int quad_init_##n(void) \ -{ \ - return quad_init_dev(QUAD_BASE_##n); \ -} \ -void quad_setbrg_##n(void) \ -{ \ - quad_setbrg_dev(QUAD_BASE_##n); \ -} \ -void quad_putc_##n(const char c) \ -{ \ - quad_putc_dev(QUAD_BASE_##n, c); \ -} \ -void quad_puts_##n(const char *s) \ -{ \ - quad_puts_dev(QUAD_BASE_##n, s); \ -} \ -int quad_getc_##n(void) \ -{ \ - return quad_getc_dev(QUAD_BASE_##n); \ -} \ -int quad_tstc_##n(void) \ -{ \ - return quad_tstc_dev(QUAD_BASE_##n); \ -} \ -struct serial_device zoom2_serial_device##n = \ -{ \ - .name = __stringify(n), \ - .start = quad_init_##n, \ - .stop = NULL, \ - .setbrg = quad_setbrg_##n, \ - .getc = quad_getc_##n, \ - .tstc = quad_tstc_##n, \ - .putc = quad_putc_##n, \ - .puts = quad_puts_##n, \ -}; - -#endif /* ZOOM2_SERIAL_H */ diff --git a/boards.cfg b/boards.cfg index 9949bb53672..a49fa660891 100644 --- a/boards.cfg +++ b/boards.cfg @@ -326,7 +326,6 @@ Active arm armv7 omap3 isee igep00x0 Active arm armv7 omap3 logicpd am3517evm am3517_evm - Vaibhav Hiremath Active arm armv7 omap3 logicpd omap3som omap3_logic - Peter Barada Active arm armv7 omap3 logicpd zoom1 omap3_zoom1 - Nishanth Menon -Active arm armv7 omap3 logicpd zoom2 omap3_zoom2 - Tom Rix Active arm armv7 omap3 matrix_vision mvblx omap3_mvblx - Michael Jones Active arm armv7 omap3 nokia rx51 nokia_rx51 - Pali Rohár Active arm armv7 omap3 technexion tao3530 omap3_ha tao3530:SYS_BOARD_OMAP3_HA Stefan Roese diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c index 181c81815ac..fbc37b27e8e 100644 --- a/drivers/serial/ns16550.c +++ b/drivers/serial/ns16550.c @@ -56,9 +56,8 @@ void NS16550_init(NS16550_t com_port, int baud_divisor) ; serial_out(CONFIG_SYS_NS16550_IER, &com_port->ier); -#if (defined(CONFIG_OMAP) && !defined(CONFIG_OMAP3_ZOOM2)) || \ - defined(CONFIG_AM33XX) || defined(CONFIG_TI81XX) || \ - defined(CONFIG_AM43XX) +#if defined(CONFIG_OMAP) || defined(CONFIG_AM33XX) || \ + 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); diff --git a/include/configs/omap3_zoom2.h b/include/configs/omap3_zoom2.h deleted file mode 100644 index f7497408158..00000000000 --- a/include/configs/omap3_zoom2.h +++ /dev/null @@ -1,237 +0,0 @@ -/* - * (C) Copyright 2006-2009 - * Texas Instruments. - * Richard Woodruff - * Syed Mohammed Khasim - * Nishanth Menon - * Tom Rix - * - * Configuration settings for the TI OMAP3430 Zoom II board. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __CONFIG_H -#define __CONFIG_H - -/* - * High Level Configuration Options - */ -#define CONFIG_OMAP 1 /* in a TI OMAP core */ -#define CONFIG_OMAP34XX 1 /* which is a 34XX */ -#define CONFIG_OMAP3_ZOOM2 1 /* working with Zoom II */ -#define CONFIG_OMAP_GPIO -#define CONFIG_OMAP_COMMON - -#define CONFIG_SDRC /* The chip has SDRC controller */ - -#include /* get chip and board defs */ -#include - -/* - * Display CPU and Board information - */ -#define CONFIG_DISPLAY_CPUINFO 1 -#define CONFIG_DISPLAY_BOARDINFO 1 - -/* Clock Defines */ -#define V_OSCK 26000000 /* Clock output from T2 */ -#define V_SCLK (V_OSCK >> 1) - -#define CONFIG_MISC_INIT_R - -#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */ -#define CONFIG_SETUP_MEMORY_TAGS 1 -#define CONFIG_INITRD_TAG 1 -#define CONFIG_REVISION_TAG 1 - -#define CONFIG_OF_LIBFDT 1 - -/* - * Size of malloc() pool - */ -#define CONFIG_ENV_SIZE (128 << 10) /* 128 KiB */ - /* Sector */ -#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (128 << 10)) -/* - * Hardware drivers - */ - -/* - * NS16550 Configuration - * Zoom2 uses the TL16CP754C on the debug board - */ -/* - * 0 - 1 : first USB with respect to the left edge of the debug board - * 2 - 3 : second USB with respect to the left edge of the debug board - */ -#define ZOOM2_DEFAULT_SERIAL_DEVICE 0 - -#define V_NS16550_CLK (1843200) /* 1.8432 Mhz */ - -#define CONFIG_SYS_NS16550 -#define CONFIG_SYS_NS16550_REG_SIZE (-2) -#define CONFIG_SYS_NS16550_CLK V_NS16550_CLK -#define CONFIG_BAUDRATE 115200 -#define CONFIG_SYS_BAUDRATE_TABLE {115200} - -/* allow to overwrite serial and ethaddr */ -#define CONFIG_ENV_OVERWRITE - -#define CONFIG_GENERIC_MMC 1 -#define CONFIG_MMC 1 -#define CONFIG_OMAP_HSMMC 1 -#define CONFIG_DOS_PARTITION 1 - -/* Status LED */ -#define CONFIG_STATUS_LED 1 /* Status LED enabled */ -#define CONFIG_BOARD_SPECIFIC_LED 1 -#define STATUS_LED_BLUE 0 -#define STATUS_LED_RED 1 -/* Blue */ -#define STATUS_LED_BIT STATUS_LED_BLUE -#define STATUS_LED_STATE STATUS_LED_ON -#define STATUS_LED_PERIOD (CONFIG_SYS_HZ / 2) -/* Red */ -#define STATUS_LED_BIT1 STATUS_LED_RED -#define STATUS_LED_STATE1 STATUS_LED_OFF -#define STATUS_LED_PERIOD1 (CONFIG_SYS_HZ / 2) -/* Optional value */ -#define STATUS_LED_BOOT STATUS_LED_BIT - -/* GPIO banks */ -#ifdef CONFIG_STATUS_LED -#define CONFIG_OMAP3_GPIO_2 /* ZOOM2_LED_BLUE2 */ -#define CONFIG_OMAP3_GPIO_6 /* ZOOM2_LED_RED */ -#endif -#define CONFIG_OMAP3_GPIO_3 /* board revision */ -#define CONFIG_OMAP3_GPIO_5 /* debug board detection, ZOOM2_LED_BLUE */ - -/* USB */ -#define CONFIG_MUSB_UDC 1 -#define CONFIG_USB_OMAP3 1 -#define CONFIG_TWL4030_USB 1 - -/* USB device configuration */ -#define CONFIG_USB_DEVICE 1 -#define CONFIG_USB_TTY 1 -/* Change these to suit your needs */ -#define CONFIG_USBD_VENDORID 0x0451 -#define CONFIG_USBD_PRODUCTID 0x5678 -#define CONFIG_USBD_MANUFACTURER "Texas Instruments" -#define CONFIG_USBD_PRODUCT_NAME "Zoom2" - -/* commands to include */ -#include - -#define CONFIG_CMD_FAT /* FAT support */ -#define CONFIG_CMD_I2C /* I2C serial bus support */ -#define CONFIG_CMD_MMC /* MMC support */ -#define CONFIG_CMD_NAND /* NAND support */ -#define CONFIG_CMD_NAND_LOCK_UNLOCK /* Enable lock/unlock support */ - -#undef CONFIG_CMD_FLASH /* flinfo, erase, protect */ -#undef CONFIG_CMD_FPGA /* FPGA configuration Support */ -#undef CONFIG_CMD_IMI /* iminfo */ -#undef CONFIG_CMD_IMLS /* List all found images */ -#undef CONFIG_CMD_NET /* bootp, tftpboot, rarpboot */ -#undef CONFIG_CMD_NFS /* NFS support */ - -#define CONFIG_SYS_NO_FLASH -#define CONFIG_SYS_I2C -#define CONFIG_SYS_OMAP24_I2C_SPEED 100000 -#define CONFIG_SYS_OMAP24_I2C_SLAVE 1 -#define CONFIG_SYS_I2C_OMAP34XX - -/* - * TWL4030 - */ -#define CONFIG_TWL4030_POWER 1 -#define CONFIG_TWL4030_LED 1 - -/* - * Board NAND Info. - */ -#define CONFIG_NAND_OMAP_GPMC -#define CONFIG_SYS_NAND_ADDR NAND_BASE /* physical address */ - /* to access nand */ -#define CONFIG_SYS_NAND_BASE NAND_BASE /* physical address */ - /* to access nand at */ - /* CS0 */ -#define GPMC_NAND_ECC_LP_x16_LAYOUT 1 -#define CONFIG_SYS_MAX_NAND_DEVICE 1 - -/* Environment information */ -#define CONFIG_BOOTDELAY 10 - -#define CONFIG_EXTRA_ENV_SETTINGS \ - "usbtty=cdc_acm\0" \ - -#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 -#define CONFIG_SYS_INIT_RAM_ADDR 0x4020f800 -#define CONFIG_SYS_INIT_RAM_SIZE 0x800 -#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INIT_RAM_ADDR + \ - CONFIG_SYS_INIT_RAM_SIZE - \ - GENERATED_GBL_DATA_SIZE) -/* - * Miscellaneous configurable options - */ - -#define CONFIG_SYS_PROMPT "OMAP3 Zoom2 # " -#define CONFIG_SYS_LONGHELP -#define CONFIG_SYS_CBSIZE 512 -#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ - sizeof(CONFIG_SYS_PROMPT) + 16) -#define CONFIG_SYS_MAXARGS 16 -#define CONFIG_SYS_BARGSIZE (CONFIG_SYS_CBSIZE) -/* Memtest from start of memory to 31MB */ -#define CONFIG_SYS_MEMTEST_START (OMAP34XX_SDRC_CS0) -#define CONFIG_SYS_MEMTEST_END (OMAP34XX_SDRC_CS0 + 0x01F00000) -/* The default load address is the start of memory */ -#define CONFIG_SYS_LOAD_ADDR (OMAP34XX_SDRC_CS0) -/* everything, incl board info, in Hz */ -#undef CONFIG_SYS_CLKS_IN_HZ -/* - * 2430 has 12 GP timers, they can be driven by the SysClk (12/13/19.2) or by - * 32KHz clk, or from external sig. This rate is divided by a local divisor. - */ -#define CONFIG_SYS_TIMERBASE (OMAP34XX_GPT2) -#define CONFIG_SYS_PTV 7 /* 2^(PTV+1) */ -#define CONFIG_SYS_HZ ((V_SCLK) / (2 << CONFIG_SYS_PTV)) - -/*----------------------------------------------------------------------- - * Physical Memory Map - */ -#define CONFIG_NR_DRAM_BANKS 2 /* CS1 may or may not be populated */ -#define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0 -#define PHYS_SDRAM_2 OMAP34XX_SDRC_CS1 - -/*----------------------------------------------------------------------- - * FLASH and environment organization - */ - -/* **** PISMO SUPPORT *** */ - -/* Configure the PISMO */ -#define PISMO1_NAND_SIZE GPMC_SIZE_128M -#define PISMO1_ONEN_SIZE GPMC_SIZE_128M - -#define CONFIG_SYS_MONITOR_LEN (256 << 10) /* Reserve 2 sectors */ - -#if defined(CONFIG_CMD_NAND) -#define CONFIG_SYS_FLASH_BASE PISMO1_NAND_BASE -#endif - -/* Monitor at start of flash */ -#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE - -#define CONFIG_ENV_IS_IN_NAND 1 -#define SMNAND_ENV_OFFSET 0x0c0000 /* environment starts here */ - -#define CONFIG_SYS_ENV_SECT_SIZE (128 << 10) /* 128 KiB */ -#define CONFIG_ENV_OFFSET SMNAND_ENV_OFFSET -#define CONFIG_ENV_ADDR SMNAND_ENV_OFFSET - -#define CONFIG_SYS_CACHELINE_SIZE 64 - -#endif /* __CONFIG_H */ -- cgit v1.3.1 From fd26b5490bef8e8a37e33a9b3c4960d7a8734067 Mon Sep 17 00:00:00 2001 From: Chin Liang See Date: Wed, 18 Dec 2013 11:16:01 -0600 Subject: mmc/dwmmc: Using calloc instead malloc To enhance the SDMMC DesignWare driver to use calloc instead of malloc. This will avoid the incident that uninitialized members of mmc structure are later used for NULL comparison. Signed-off-by: Chin Liang See Cc: Rajeshwari Shinde Cc: Jaehoon Chung Cc: Mischa Jonker Cc: Alexey Brodkin Cc: Andy Fleming Cc: Pantelis Antoniou Acked-by: Pantelis Antoniou --- drivers/mmc/dw_mmc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) mode change 100644 => 100755 drivers/mmc/dw_mmc.c (limited to 'drivers') diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c old mode 100644 new mode 100755 index 19d9b0b899c..82abe19eaba --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -336,9 +336,9 @@ int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk) struct mmc *mmc; int err = 0; - mmc = malloc(sizeof(struct mmc)); + mmc = calloc(sizeof(struct mmc), 1); if (!mmc) { - printf("mmc malloc fail!\n"); + printf("mmc calloc fail!\n"); return -1; } -- cgit v1.3.1 From f4d8de48f5a2aa1885daa0d425b8c0568a2ccb69 Mon Sep 17 00:00:00 2001 From: Henrik Nordström Date: Sun, 10 Nov 2013 10:26:56 -0700 Subject: sandbox: block driver using host file/device as backing store MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Provide a way to use any host file or device as a block device in U-Boot. This can be used to provide filesystem access within U-Boot to an ext2 image file on the host, for example. The support is plumbed into the filesystem and partition interfaces. We don't want to print a message in the driver every time we find a missing device. Pass the information back to the caller where a message can be printed if desired. Signed-off-by: Henrik Nordström Signed-off-by: Simon Glass - Removed change to part.c get_device_and_partition() Signed-off-by: Simon Glass Reviewed-by: Simon Glass --- common/cmd_sandbox.c | 64 +++++++++++++++++++++++ disk/part.c | 6 +++ drivers/block/Makefile | 1 + drivers/block/sandbox.c | 124 +++++++++++++++++++++++++++++++++++++++++++++ include/config_fallbacks.h | 3 +- include/configs/sandbox.h | 3 ++ include/part.h | 5 ++ include/sandboxblockdev.h | 18 +++++++ 8 files changed, 223 insertions(+), 1 deletion(-) create mode 100644 drivers/block/sandbox.c create mode 100644 include/sandboxblockdev.h (limited to 'drivers') diff --git a/common/cmd_sandbox.c b/common/cmd_sandbox.c index 8d59364b636..00982b164dd 100644 --- a/common/cmd_sandbox.c +++ b/common/cmd_sandbox.c @@ -6,6 +6,9 @@ #include #include +#include +#include +#include static int do_sandbox_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) @@ -25,10 +28,69 @@ static int do_sandbox_save(cmd_tbl_t *cmdtp, int flag, int argc, return do_save(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX); } +static int do_sandbox_bind(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + if (argc < 2 || argc > 3) + return CMD_RET_USAGE; + char *ep; + char *dev_str = argv[1]; + char *file = argc >= 3 ? argv[2] : NULL; + int dev = simple_strtoul(dev_str, &ep, 16); + if (*ep) { + printf("** Bad device specification %s **\n", dev_str); + return CMD_RET_USAGE; + } + return host_dev_bind(dev, file); +} + +static int do_sandbox_info(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + if (argc < 1 || argc > 2) + return CMD_RET_USAGE; + int min_dev = 0; + int max_dev = CONFIG_HOST_MAX_DEVICES - 1; + if (argc >= 2) { + char *ep; + char *dev_str = argv[1]; + int dev = simple_strtoul(dev_str, &ep, 16); + if (*ep) { + printf("** Bad device specification %s **\n", dev_str); + return CMD_RET_USAGE; + } + min_dev = dev; + max_dev = dev; + } + int dev; + printf("%3s %12s %s\n", "dev", "blocks", "path"); + for (dev = min_dev; dev <= max_dev; dev++) { + block_dev_desc_t *blk_dev; + int ret; + + printf("%3d ", dev); + ret = host_get_dev_err(dev, &blk_dev); + if (ret) { + if (ret == -ENOENT) + puts("Not bound to a backing file\n"); + else if (ret == -ENODEV) + puts("Invalid host device number\n"); + + continue; + } + struct host_block_dev *host_dev = blk_dev->priv; + printf("%12lu %s\n", (unsigned long)blk_dev->lba, + host_dev->filename); + } + return 0; +} + static cmd_tbl_t cmd_sandbox_sub[] = { U_BOOT_CMD_MKENT(load, 7, 0, do_sandbox_load, "", ""), U_BOOT_CMD_MKENT(ls, 3, 0, do_sandbox_ls, "", ""), U_BOOT_CMD_MKENT(save, 6, 0, do_sandbox_save, "", ""), + U_BOOT_CMD_MKENT(bind, 3, 0, do_sandbox_bind, "", ""), + U_BOOT_CMD_MKENT(info, 3, 0, do_sandbox_info, "", ""), }; static int do_sandbox(cmd_tbl_t *cmdtp, int flag, int argc, @@ -57,4 +119,6 @@ U_BOOT_CMD( "sb ls host - list files on host\n" "sb save host [] - " "save a file to host\n" + "sb bind [] - bind \"host\" device to file\n" + "sb info [] - show device binding & info" ); diff --git a/disk/part.c b/disk/part.c index d2e34cfcfa9..6941033d8d7 100644 --- a/disk/part.c +++ b/disk/part.c @@ -42,6 +42,9 @@ static const struct block_drvr block_drvr[] = { #endif #if defined(CONFIG_SYSTEMACE) { .name = "ace", .get_dev = systemace_get_dev, }, +#endif +#if defined(CONFIG_SANDBOX) + { .name = "host", .get_dev = host_get_dev, }, #endif { }, }; @@ -286,6 +289,9 @@ static void print_part_header (const char *type, block_dev_desc_t * dev_desc) case IF_TYPE_MMC: puts ("MMC"); break; + case IF_TYPE_HOST: + puts("HOST"); + break; default: puts ("UNKNOWN"); break; diff --git a/drivers/block/Makefile b/drivers/block/Makefile index 4e94378388c..8697da4262b 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -18,5 +18,6 @@ obj-$(CONFIG_SATA_DWC) += sata_dwc.o obj-$(CONFIG_SATA_SIL3114) += sata_sil3114.o obj-$(CONFIG_SATA_SIL) += sata_sil.o obj-$(CONFIG_IDE_SIL680) += sil680.o +obj-$(CONFIG_SANDBOX) += sandbox.o obj-$(CONFIG_SCSI_SYM53C8XX) += sym53c8xx.o obj-$(CONFIG_SYSTEMACE) += systemace.o diff --git a/drivers/block/sandbox.c b/drivers/block/sandbox.c new file mode 100644 index 00000000000..73f4c4a9e98 --- /dev/null +++ b/drivers/block/sandbox.c @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2013 Henrik Nordstrom + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include + +static struct host_block_dev host_devices[CONFIG_HOST_MAX_DEVICES]; + +static struct host_block_dev *find_host_device(int dev) +{ + if (dev >= 0 && dev < CONFIG_HOST_MAX_DEVICES) + return &host_devices[dev]; + + return NULL; +} + +static unsigned long host_block_read(int dev, unsigned long start, + lbaint_t blkcnt, void *buffer) +{ + struct host_block_dev *host_dev = find_host_device(dev); + + if (!host_dev) + return -1; + if (os_lseek(host_dev->fd, + start * host_dev->blk_dev.blksz, + OS_SEEK_SET) == -1) { + printf("ERROR: Invalid position\n"); + return -1; + } + ssize_t len = os_read(host_dev->fd, buffer, + blkcnt * host_dev->blk_dev.blksz); + if (len >= 0) + return len / host_dev->blk_dev.blksz; + return -1; +} + +static unsigned long host_block_write(int dev, unsigned long start, + lbaint_t blkcnt, const void *buffer) +{ + struct host_block_dev *host_dev = find_host_device(dev); + if (os_lseek(host_dev->fd, + start * host_dev->blk_dev.blksz, + OS_SEEK_SET) == -1) { + printf("ERROR: Invalid position\n"); + return -1; + } + ssize_t len = os_write(host_dev->fd, buffer, blkcnt * + host_dev->blk_dev.blksz); + if (len >= 0) + return len / host_dev->blk_dev.blksz; + return -1; +} + +int host_dev_bind(int dev, char *filename) +{ + struct host_block_dev *host_dev = find_host_device(dev); + + if (!host_dev) + return -1; + if (host_dev->blk_dev.priv) { + os_close(host_dev->fd); + host_dev->blk_dev.priv = NULL; + } + if (host_dev->filename) + free(host_dev->filename); + if (filename && *filename) { + host_dev->filename = strdup(filename); + } else { + host_dev->filename = NULL; + return 0; + } + + host_dev->fd = os_open(host_dev->filename, OS_O_RDWR); + if (host_dev->fd == -1) { + printf("Failed to access host backing file '%s'\n", + host_dev->filename); + return 1; + } + + block_dev_desc_t *blk_dev = &host_dev->blk_dev; + blk_dev->if_type = IF_TYPE_HOST; + blk_dev->priv = host_dev; + blk_dev->blksz = 512; + blk_dev->lba = os_lseek(host_dev->fd, 0, OS_SEEK_END) / blk_dev->blksz; + blk_dev->block_read = host_block_read; + blk_dev->block_write = host_block_write; + blk_dev->dev = dev; + blk_dev->part_type = PART_TYPE_UNKNOWN; + init_part(blk_dev); + + return 0; +} + +int host_get_dev_err(int dev, block_dev_desc_t **blk_devp) +{ + struct host_block_dev *host_dev = find_host_device(dev); + + if (!host_dev) + return -ENODEV; + + if (!host_dev->blk_dev.priv) + return -ENOENT; + + *blk_devp = &host_dev->blk_dev; + return 0; +} + +block_dev_desc_t *host_get_dev(int dev) +{ + block_dev_desc_t *blk_dev; + + if (host_get_dev_err(dev, &blk_dev)) + return NULL; + + return blk_dev; +} diff --git a/include/config_fallbacks.h b/include/config_fallbacks.h index 3633b09aa91..d8339b26cca 100644 --- a/include/config_fallbacks.h +++ b/include/config_fallbacks.h @@ -50,7 +50,8 @@ defined(CONFIG_CMD_PART) || \ defined(CONFIG_CMD_GPT) || \ defined(CONFIG_MMC) || \ - defined(CONFIG_SYSTEMACE) + defined(CONFIG_SYSTEMACE) || \ + defined(CONFIG_SANDBOX) #define HAVE_BLOCK_DEVICE #endif diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index 7e78a231d7a..98bdd70ffa9 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -39,6 +39,9 @@ #define CONFIG_CMD_FAT #define CONFIG_CMD_EXT4 #define CONFIG_CMD_EXT4_WRITE +#define CONFIG_CMD_PART +#define CONFIG_DOS_PARTITION +#define CONFIG_HOST_MAX_DEVICES 4 #define CONFIG_SYS_VSNPRINTF diff --git a/include/part.h b/include/part.h index ce840bd841b..4beb6db89b1 100644 --- a/include/part.h +++ b/include/part.h @@ -58,6 +58,8 @@ typedef struct block_dev_desc { #define IF_TYPE_MMC 6 #define IF_TYPE_SD 7 #define IF_TYPE_SATA 8 +#define IF_TYPE_HOST 9 +#define IF_TYPE_MAX 10 /* Max number of IF_TYPE_* supported */ /* Part types */ #define PART_TYPE_UNKNOWN 0x00 @@ -102,6 +104,8 @@ block_dev_desc_t* usb_stor_get_dev(int dev); block_dev_desc_t* mmc_get_dev(int dev); block_dev_desc_t* systemace_get_dev(int dev); block_dev_desc_t* mg_disk_get_dev(int dev); +block_dev_desc_t *host_get_dev(int dev); +int host_get_dev_err(int dev, block_dev_desc_t **blk_devp); /* disk/part.c */ int get_partition_info (block_dev_desc_t * dev_desc, int part, disk_partition_t *info); @@ -123,6 +127,7 @@ static inline block_dev_desc_t* usb_stor_get_dev(int dev) { return NULL; } static inline block_dev_desc_t* mmc_get_dev(int dev) { return NULL; } static inline block_dev_desc_t* systemace_get_dev(int dev) { return NULL; } static inline block_dev_desc_t* mg_disk_get_dev(int dev) { return NULL; } +static inline block_dev_desc_t *host_get_dev(int dev) { return NULL; } static inline int get_partition_info (block_dev_desc_t * dev_desc, int part, disk_partition_t *info) { return -1; } diff --git a/include/sandboxblockdev.h b/include/sandboxblockdev.h new file mode 100644 index 00000000000..627787aa326 --- /dev/null +++ b/include/sandboxblockdev.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2013, Henrik Nordstrom + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __SANDBOX_BLOCK_DEV__ +#define __SANDBOX_BLOCK_DEV__ + +struct host_block_dev { + block_dev_desc_t blk_dev; + char *filename; + int fd; +}; + +int host_dev_bind(int dev, char *filename); + +#endif -- cgit v1.3.1 From ed3f5a30a7bc4254e516caad7f01baf4596359b7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 10 Nov 2013 10:27:05 -0700 Subject: sandbox: tpm: Add TPM emulation Add a simple TPM emulator for sandbox. It only supports a small subset of TPM operations. However, these are enough to perform common tasks. Note this is an initial commit to get this working, but it could use cleaning up (for example constants instead of open-coded values). Signed-off-by: Simon Glass Signed-off-by: Simon Glass Reviewed-by: Simon Glass --- drivers/tpm/Makefile | 1 + drivers/tpm/tpm_tis_sandbox.c | 262 ++++++++++++++++++++++++++++++++++++++++++ include/configs/sandbox.h | 2 + 3 files changed, 265 insertions(+) create mode 100644 drivers/tpm/tpm_tis_sandbox.c (limited to 'drivers') diff --git a/drivers/tpm/Makefile b/drivers/tpm/Makefile index 2f2353f809b..150570ee7e4 100644 --- a/drivers/tpm/Makefile +++ b/drivers/tpm/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_TPM_ATMEL_TWI) += tpm_atmel_twi.o obj-$(CONFIG_TPM_TIS_I2C) += tpm.o obj-$(CONFIG_TPM_TIS_I2C) += tpm_tis_i2c.o obj-$(CONFIG_TPM_TIS_LPC) += tpm_tis_lpc.o +obj-$(CONFIG_TPM_TIS_SANDBOX) += tpm_tis_sandbox.o diff --git a/drivers/tpm/tpm_tis_sandbox.c b/drivers/tpm/tpm_tis_sandbox.c new file mode 100644 index 00000000000..80cf734f1c2 --- /dev/null +++ b/drivers/tpm/tpm_tis_sandbox.c @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2013 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +/* TPM NVRAM location indices. */ +#define FIRMWARE_NV_INDEX 0x1007 +#define KERNEL_NV_INDEX 0x1008 + +#define NV_DATA_PUBLIC_PERMISSIONS_OFFSET 60 + +/* Kernel TPM space - KERNEL_NV_INDEX, locked with physical presence */ +#define ROLLBACK_SPACE_KERNEL_VERSION 2 +#define ROLLBACK_SPACE_KERNEL_UID 0x4752574C /* 'GRWL' */ + +struct rollback_space_kernel { + /* Struct version, for backwards compatibility */ + uint8_t struct_version; + /* Unique ID to detect space redefinition */ + uint32_t uid; + /* Kernel versions */ + uint32_t kernel_versions; + /* Reserved for future expansion */ + uint8_t reserved[3]; + /* Checksum (v2 and later only) */ + uint8_t crc8; +} __packed rollback_space_kernel; + +/* + * These numbers derive from adding the sizes of command fields as shown in + * the TPM commands manual. + */ +#define TPM_REQUEST_HEADER_LENGTH 10 +#define TPM_RESPONSE_HEADER_LENGTH 10 + +/* These are the different non-volatile spaces that we emulate */ +enum { + NV_GLOBAL_LOCK, + NV_SEQ_FIRMWARE, + NV_SEQ_KERNEL, + NV_SEQ_COUNT, +}; + +/* Size of each non-volatile space */ +#define NV_DATA_SIZE 0x20 + +/* + * Information about our TPM emulation. This is preserved in the sandbox + * state file if enabled. + */ +static struct tpm_state { + uint8_t nvdata[NV_SEQ_COUNT][NV_DATA_SIZE]; +} state; + +/** + * sandbox_tpm_read_state() - read the sandbox EC state from the state file + * + * If data is available, then blob and node will provide access to it. If + * not this function sets up an empty TPM. + * + * @blob: Pointer to device tree blob, or NULL if no data to read + * @node: Node offset to read from + */ +static int sandbox_tpm_read_state(const void *blob, int node) +{ + const char *prop; + int len; + int i; + + if (!blob) + return 0; + + for (i = 0; i < NV_SEQ_COUNT; i++) { + char prop_name[20]; + + sprintf(prop_name, "nvdata%d", i); + prop = fdt_getprop(blob, node, prop_name, &len); + if (prop && len == NV_DATA_SIZE) + memcpy(state.nvdata[i], prop, NV_DATA_SIZE); + } + + return 0; +} + +/** + * cros_ec_write_state() - Write out our state to the state file + * + * The caller will ensure that there is a node ready for the state. The node + * may already contain the old state, in which case it is overridden. + * + * @blob: Device tree blob holding state + * @node: Node to write our state into + */ +static int sandbox_tpm_write_state(void *blob, int node) +{ + int i; + + /* + * We are guaranteed enough space to write basic properties. + * We could use fdt_add_subnode() to put each set of data in its + * own node - perhaps useful if we add access informaiton to each. + */ + for (i = 0; i < NV_SEQ_COUNT; i++) { + char prop_name[20]; + + sprintf(prop_name, "nvdata%d", i); + fdt_setprop(blob, node, prop_name, state.nvdata[i], + NV_DATA_SIZE); + } + + return 0; +} + +SANDBOX_STATE_IO(sandbox_tpm, "google,sandbox-tpm", sandbox_tpm_read_state, + sandbox_tpm_write_state); + +static int index_to_seq(uint32_t index) +{ + switch (index) { + case FIRMWARE_NV_INDEX: + return NV_SEQ_FIRMWARE; + case KERNEL_NV_INDEX: + return NV_SEQ_KERNEL; + case 0: + return NV_GLOBAL_LOCK; + } + + printf("Invalid nv index %#x\n", index); + return -1; +} + +int tis_sendrecv(const u8 *sendbuf, size_t send_size, + u8 *recvbuf, size_t *recv_len) +{ + struct tpm_state *tpm = &state; + uint32_t code, index, length, type; + uint8_t *data; + int seq; + + code = get_unaligned_be32(sendbuf + sizeof(uint16_t) + + sizeof(uint32_t)); + printf("tpm: %zd bytes, recv_len %zd, cmd = %x\n", send_size, + *recv_len, code); + print_buffer(0, sendbuf, 1, send_size, 0); + switch (code) { + case 0x65: /* get flags */ + type = get_unaligned_be32(sendbuf + 14); + switch (type) { + case 4: + index = get_unaligned_be32(sendbuf + 18); + printf("Get flags index %#02x\n", index); + *recv_len = 22; + memset(recvbuf, '\0', *recv_len); + put_unaligned_be32(22, recvbuf + + TPM_RESPONSE_HEADER_LENGTH); + data = recvbuf + TPM_RESPONSE_HEADER_LENGTH + + sizeof(uint32_t); + switch (index) { + case FIRMWARE_NV_INDEX: + break; + case KERNEL_NV_INDEX: + /* TPM_NV_PER_PPWRITE */ + put_unaligned_be32(1, data + + NV_DATA_PUBLIC_PERMISSIONS_OFFSET); + break; + } + break; + case 0x11: /* TPM_CAP_NV_INDEX */ + index = get_unaligned_be32(sendbuf + 18); + printf("Get cap nv index %#02x\n", index); + put_unaligned_be32(22, recvbuf + + TPM_RESPONSE_HEADER_LENGTH); + break; + default: + printf(" ** Unknown 0x65 command type %#02x\n", + type); + return -1; + } + break; + case 0xcd: /* nvwrite */ + index = get_unaligned_be32(sendbuf + 10); + length = get_unaligned_be32(sendbuf + 18); + seq = index_to_seq(index); + if (seq < 0) + return -1; + printf("tpm: nvwrite index=%#02x, len=%#02x\n", index, length); + memcpy(&tpm->nvdata[seq], + recvbuf + TPM_RESPONSE_HEADER_LENGTH + sizeof(uint32_t), + length); + *recv_len = 12; + memset(recvbuf, '\0', *recv_len); + break; + case 0xcf: /* nvread */ + index = get_unaligned_be32(sendbuf + 10); + length = get_unaligned_be32(sendbuf + 18); + seq = index_to_seq(index); + if (seq < 0) + return -1; + printf("tpm: nvread index=%#02x, len=%#02x\n", index, length); + *recv_len = TPM_RESPONSE_HEADER_LENGTH + sizeof(uint32_t) + + length; + memset(recvbuf, '\0', *recv_len); + put_unaligned_be32(length, recvbuf + + TPM_RESPONSE_HEADER_LENGTH); + if (seq == NV_SEQ_KERNEL) { + struct rollback_space_kernel rsk; + + data = recvbuf + TPM_RESPONSE_HEADER_LENGTH + + sizeof(uint32_t); + rsk.struct_version = 2; + rsk.uid = ROLLBACK_SPACE_KERNEL_UID; + rsk.kernel_versions = 0; + rsk.crc8 = crc8((unsigned char *)&rsk, + offsetof(struct rollback_space_kernel, + crc8)); + memcpy(data, &rsk, sizeof(rsk)); + } else { + memcpy(recvbuf + TPM_RESPONSE_HEADER_LENGTH + + sizeof(uint32_t), &tpm->nvdata[seq], length); + } + break; + case 0x14: /* tpm extend */ + case 0x15: /* pcr read */ + case 0x5d: /* force clear */ + case 0x6f: /* physical enable */ + case 0x72: /* physical set deactivated */ + case 0x99: /* startup */ + case 0x4000000a: /* assert physical presence */ + *recv_len = 12; + memset(recvbuf, '\0', *recv_len); + break; + default: + printf("Unknown tpm command %02x\n", code); + return -1; + } + + return 0; +} + +int tis_open(void) +{ + printf("%s\n", __func__); + return 0; +} + +int tis_close(void) +{ + printf("%s\n", __func__); + return 0; +} + +int tis_init(void) +{ + printf("%s\n", __func__); + return 0; +} diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index 98bdd70ffa9..a6d55822b82 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -129,4 +129,6 @@ #define CONFIG_LZO #define CONFIG_LZMA +#define CONFIG_TPM_TIS_SANDBOX + #endif -- cgit v1.3.1 From 2c30af8f1861f09f217097460bfbea5ea691f8b8 Mon Sep 17 00:00:00 2001 From: Che-Liang Chiou Date: Sun, 10 Nov 2013 10:27:08 -0700 Subject: sandbox: tpm: Fix nvwrite command The original codes misused recvbuf in source buffer instead of sendbuf, and read from incorrect offset 14 instead of 22. Signed-off-by: Che-Liang Chiou Signed-off-by: Simon Glass Reviewed-by: Simon Glass Tested-by: Che-Liang Chiou --- drivers/tpm/tpm_tis_sandbox.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/tpm/tpm_tis_sandbox.c b/drivers/tpm/tpm_tis_sandbox.c index 80cf734f1c2..ed4b0391278 100644 --- a/drivers/tpm/tpm_tis_sandbox.c +++ b/drivers/tpm/tpm_tis_sandbox.c @@ -190,9 +190,7 @@ int tis_sendrecv(const u8 *sendbuf, size_t send_size, if (seq < 0) return -1; printf("tpm: nvwrite index=%#02x, len=%#02x\n", index, length); - memcpy(&tpm->nvdata[seq], - recvbuf + TPM_RESPONSE_HEADER_LENGTH + sizeof(uint32_t), - length); + memcpy(&tpm->nvdata[seq], sendbuf + 22, length); *recv_len = 12; memset(recvbuf, '\0', *recv_len); break; -- cgit v1.3.1 From 2a7a210e2cb724f4a941786e58878baf6edce846 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Thu, 26 Dec 2013 15:29:07 +0400 Subject: mmc/dwmmc: use bounce buffer for data exchange between CPU and MMC controller Bounce buffer implementation takes care of proper data buffer alignemt and correct flush/invalidation of data cache at once so we no longer depend on input data variety and make sure CPU and MMC controller deal with expected data in case of enabled data cache. Bounce buffer requires to add its definition (CONFIG_BOUNCE_BUFFER) in board configuration, otherwise corresponding library won't be compiled and linker will fail to build resulting executable. Difference since v1 - fixed compile-time warning with type casting to "void *": Slight edit to remove UTF8 characters in the commit message. Acked-by: Jaehoon Chung Tested-by: Jaehoon Chung Acked-by: Pantelis Antoniou ==== passing argument 2 of 'bounce_buffer_start' discards 'const' qualifier from pointer target type ==== Signed-off-by: Alexey Brodkin Cc: Mischa Jonker Cc: Alim Akhtar Cc: Rajeshwari Shinde Cc: Jaehoon Chung Cc: Amar Cc: Kyungmin Park Cc: Minkyu Kang Cc: Simon Glass Cc: Pantelis Antoniou Cc: Andy Fleming --- drivers/mmc/dw_mmc.c | 32 ++++++++++++++++++++++---------- include/configs/arndale.h | 1 + include/configs/exynos5250-dt.h | 1 + 3 files changed, 24 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 82abe19eaba..4cec5aaa604 100755 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -6,6 +6,7 @@ * SPDX-License-Identifier: GPL-2.0+ */ +#include #include #include #include @@ -41,11 +42,13 @@ static void dwmci_set_idma_desc(struct dwmci_idmac *idmac, } static void dwmci_prepare_data(struct dwmci_host *host, - struct mmc_data *data, struct dwmci_idmac *cur_idmac) + struct mmc_data *data, + struct dwmci_idmac *cur_idmac, + void *bounce_buffer) { unsigned long ctrl; unsigned int i = 0, flags, cnt, blk_cnt; - ulong data_start, data_end, start_addr; + ulong data_start, data_end; blk_cnt = data->blocks; @@ -55,11 +58,6 @@ static void dwmci_prepare_data(struct dwmci_host *host, data_start = (ulong)cur_idmac; dwmci_writel(host, DWMCI_DBADDR, (unsigned int)cur_idmac); - if (data->flags == MMC_DATA_READ) - start_addr = (unsigned int)data->dest; - else - start_addr = (unsigned int)data->src; - do { flags = DWMCI_IDMAC_OWN | DWMCI_IDMAC_CH ; flags |= (i == 0) ? DWMCI_IDMAC_FS : 0; @@ -70,7 +68,7 @@ static void dwmci_prepare_data(struct dwmci_host *host, cnt = data->blocksize * 8; dwmci_set_idma_desc(cur_idmac, flags, cnt, - start_addr + (i * PAGE_SIZE)); + (u32)bounce_buffer + (i * PAGE_SIZE)); if (blk_cnt <= 8) break; @@ -117,6 +115,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, u32 retry = 10000; u32 mask, ctrl; ulong start = get_timer(0); + struct bounce_buffer bbstate; while (dwmci_readl(host, DWMCI_STATUS) & DWMCI_BUSY) { if (get_timer(start) > timeout) { @@ -127,8 +126,19 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_ALL); - if (data) - dwmci_prepare_data(host, data, cur_idmac); + if (data) { + if (data->flags == MMC_DATA_READ) { + bounce_buffer_start(&bbstate, (void*)data->dest, + data->blocksize * + data->blocks, GEN_BB_WRITE); + } else { + bounce_buffer_start(&bbstate, (void*)data->src, + data->blocksize * + data->blocks, GEN_BB_READ); + } + dwmci_prepare_data(host, data, cur_idmac, + bbstate.bounce_buffer); + } dwmci_writel(host, DWMCI_CMDARG, cmd->cmdarg); @@ -204,6 +214,8 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, ctrl = dwmci_readl(host, DWMCI_CTRL); ctrl &= ~(DWMCI_DMA_EN); dwmci_writel(host, DWMCI_CTRL, ctrl); + + bounce_buffer_stop(&bbstate); } udelay(100); diff --git a/include/configs/arndale.h b/include/configs/arndale.h index a3cb56b8bf2..3d29caf4c5e 100644 --- a/include/configs/arndale.h +++ b/include/configs/arndale.h @@ -85,6 +85,7 @@ #define CONFIG_DWMMC #define CONFIG_EXYNOS_DWMMC #define CONFIG_SUPPORT_EMMC_BOOT +#define CONFIG_BOUNCE_BUFFER #define CONFIG_BOARD_EARLY_INIT_F diff --git a/include/configs/exynos5250-dt.h b/include/configs/exynos5250-dt.h index 8fb904cddf4..b39bafca3e0 100644 --- a/include/configs/exynos5250-dt.h +++ b/include/configs/exynos5250-dt.h @@ -102,6 +102,7 @@ #define CONFIG_DWMMC #define CONFIG_EXYNOS_DWMMC #define CONFIG_SUPPORT_EMMC_BOOT +#define CONFIG_BOUNCE_BUFFER #define CONFIG_BOARD_EARLY_INIT_F -- cgit v1.3.1 From 30e6d979fa9da56a5badcb981cdddd58638d3375 Mon Sep 17 00:00:00 2001 From: Darwin Rambo Date: Thu, 19 Dec 2013 15:13:25 -0800 Subject: mmc: Minor cleanup of sdhci.c Fixup prints to show where the print is done from, and a few minor formatting/grammar issues. Signed-off-by: Darwin Rambo Acked-by: Pantelis Antoniou --- drivers/mmc/sdhci.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 46ae9cb52d9..1e86b92beec 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -24,7 +24,8 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask) sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET); while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) { if (timeout == 0) { - printf("Reset 0x%x never completed.\n", (int)mask); + printf("%s: Reset 0x%x never completed.\n", + __func__, (int)mask); return; } timeout--; @@ -79,7 +80,8 @@ static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data, do { stat = sdhci_readl(host, SDHCI_INT_STATUS); if (stat & SDHCI_INT_ERROR) { - printf("Error detected in status(0x%X)!\n", stat); + printf("%s: Error detected in status(0x%X)!\n", + __func__, stat); return -1; } if (stat & rdy) { @@ -102,7 +104,7 @@ static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data, if (timeout-- > 0) udelay(10); else { - printf("Transfer data timeout\n"); + printf("%s: Transfer data timeout\n", __func__); return -1; } } while (!(stat & SDHCI_INT_DATA_END)); @@ -147,7 +149,7 @@ int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) { if (time >= cmd_timeout) { - printf("MMC: %d busy ", mmc_dev); + printf("%s: MMC: %d busy ", __func__, mmc_dev); if (2 * cmd_timeout <= CONFIG_SDHCI_CMD_MAX_TIMEOUT) { cmd_timeout += cmd_timeout; printf("timeout increasing to: %u ms.\n", @@ -179,7 +181,7 @@ int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, if (data) flags |= SDHCI_CMD_DATA; - /*Set Transfer mode regarding to data flag*/ + /* Set Transfer mode regarding to data flag */ if (data != 0) { sdhci_writeb(host, 0xe, SDHCI_TIMEOUT_CONTROL); mode = SDHCI_TRNS_BLK_CNT_EN; @@ -230,7 +232,7 @@ int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, if (host->quirks & SDHCI_QUIRK_BROKEN_R1B) return 0; else { - printf("Timeout for status update!\n"); + printf("%s: Timeout for status update!\n", __func__); return TIMEOUT; } } @@ -307,7 +309,8 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL)) & SDHCI_CLOCK_INT_STABLE)) { if (timeout == 0) { - printf("Internal clock never stabilised.\n"); + printf("%s: Internal clock never stabilised.\n", + __func__); return -1; } timeout--; @@ -397,7 +400,8 @@ int sdhci_init(struct mmc *mmc) if ((host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) && !aligned_buffer) { aligned_buffer = memalign(8, 512*1024); if (!aligned_buffer) { - printf("Aligned buffer alloc failed!!!"); + printf("%s: Aligned buffer alloc failed!!!\n", + __func__); return -1; } } @@ -418,8 +422,8 @@ int sdhci_init(struct mmc *mmc) } /* Enable only interrupts served by the SD controller */ - sdhci_writel(host, SDHCI_INT_DATA_MASK | SDHCI_INT_CMD_MASK - , SDHCI_INT_ENABLE); + sdhci_writel(host, SDHCI_INT_DATA_MASK | SDHCI_INT_CMD_MASK, + SDHCI_INT_ENABLE); /* Mask all sdhci interrupt sources */ sdhci_writel(host, 0x0, SDHCI_SIGNAL_ENABLE); @@ -433,7 +437,7 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) mmc = malloc(sizeof(struct mmc)); if (!mmc) { - printf("mmc malloc fail!\n"); + printf("%s: mmc malloc fail!\n", __func__); return -1; } @@ -450,7 +454,8 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) caps = sdhci_readl(host, SDHCI_CAPABILITIES); #ifdef CONFIG_MMC_SDMA if (!(caps & SDHCI_CAN_DO_SDMA)) { - printf("Your controller don't support sdma!!\n"); + printf("%s: Your controller doesn't support SDMA!!\n", + __func__); return -1; } #endif @@ -467,7 +472,8 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) mmc->f_max *= 1000000; } if (mmc->f_max == 0) { - printf("Hardware doesn't specify base clock frequency\n"); + printf("%s: Hardware doesn't specify base clock frequency\n", + __func__); return -1; } if (min_clk) -- cgit v1.3.1 From ab71188ce87ebb66192a5bdbbb9d58052bd32d93 Mon Sep 17 00:00:00 2001 From: Markus Niebel Date: Mon, 16 Dec 2013 13:40:46 +0100 Subject: mmc: add setdsr support The eMMC and the SD-Card specifications describe the optional SET_DSR command. During measurements at our lab we found that some cards implementing this feature having really strong driver strengts per default. This can lead to voltage peaks above the specification of the host on signal edges for data sent from a card to the host. Since availability of a given card type may be shorter than the time a certain hardware will be produced it is useful to have support for this command (Alternative would be changing termination resistors and adapting the driver strength of the host to the used card.) Following proposal for an implementation: - new field that reflects CSD field DSR_IMP in struct mmc - new field for design specific DSR value in struct mmc - board code can set DSR value in mmc struct just after registering an controller - mmc_startup sends the the stored DSR value before selecting a card, if DSR_IMP is set Additionally the mmc command is extended to make is possible to play around with different DSR values. The concept was tested on a i.MX53 based platform using a Micron eMMC card where the default DSR is 0x0400 (12mA) but in our design 0x0100 (0x0100) were enough. To use this feature for instance on a mx53loco one have to add a call to mmc_set_dsr() in board_mmc_init() after calling fsl_esdhc_initialize() for the eMMC. Signed-off-by: Markus Niebel Acked-by: Pantelis Antoniou --- common/cmd_mmc.c | 23 +++++++++++++++++++++++ drivers/mmc/mmc.c | 18 ++++++++++++++++++ include/mmc.h | 3 +++ 3 files changed, 44 insertions(+) (limited to 'drivers') diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c index 67a94a74688..da5fef9db9d 100644 --- a/common/cmd_mmc.c +++ b/common/cmd_mmc.c @@ -340,6 +340,28 @@ static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } #endif /* CONFIG_SUPPORT_EMMC_BOOT */ } + + else if (argc == 3 && strcmp(argv[1], "setdsr") == 0) { + struct mmc *mmc = find_mmc_device(curr_device); + u32 val = simple_strtoul(argv[2], NULL, 16); + int ret; + + if (!mmc) { + printf("no mmc device at slot %x\n", curr_device); + return 1; + } + ret = mmc_set_dsr(mmc, val); + printf("set dsr %s\n", (!ret) ? "OK, force rescan" : "ERROR"); + if (!ret) { + mmc->has_init = 0; + if (mmc_init(mmc)) + return 1; + else + return 0; + } + return ret; + } + state = MMC_INVALID; if (argc == 5 && strcmp(argv[1], "read") == 0) state = MMC_READ; @@ -423,5 +445,6 @@ U_BOOT_CMD( "mmc bootpart \n" " - change sizes of boot and RPMB partitions of specified device\n" #endif + "mmc setdsr - set DSR register value\n" ); #endif /* !CONFIG_GENERIC_MMC */ diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index e1461a98dd9..c6a1c23fbf1 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -877,6 +877,7 @@ static int mmc_startup(struct mmc *mmc) mmc->tran_speed = freq * mult; + mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1); mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf); if (IS_SD(mmc)) @@ -907,6 +908,14 @@ static int mmc_startup(struct mmc *mmc) if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN) mmc->write_bl_len = MMC_MAX_BLOCK_LEN; + if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) { + cmd.cmdidx = MMC_CMD_SET_DSR; + cmd.cmdarg = (mmc->dsr & 0xffff) << 16; + cmd.resp_type = MMC_RSP_NONE; + if (mmc_send_cmd(mmc, &cmd, NULL)) + printf("MMC: SET_DSR failed\n"); + } + /* Select the card, and put it into Transfer Mode */ if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */ cmd.cmdidx = MMC_CMD_SELECT_CARD; @@ -1163,6 +1172,9 @@ static int mmc_send_if_cond(struct mmc *mmc) int mmc_register(struct mmc *mmc) { + /* Setup dsr related values */ + mmc->dsr_imp = 0; + mmc->dsr = 0xffffffff; /* Setup the universal parts of the block interface just once */ mmc->block_dev.if_type = IF_TYPE_MMC; mmc->block_dev.dev = cur_dev_num++; @@ -1280,6 +1292,12 @@ int mmc_init(struct mmc *mmc) return err; } +int mmc_set_dsr(struct mmc *mmc, u16 val) +{ + mmc->dsr = val; + return 0; +} + /* * CPU and board-specific MMC initializations. Aliased function * signals caller to move on diff --git a/include/mmc.h b/include/mmc.h index 8f51c939d66..e1060b9ff27 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -262,6 +262,8 @@ struct mmc { uint card_caps; uint host_caps; uint ocr; + uint dsr; + uint dsr_imp; uint scr[2]; uint csd[4]; uint cid[4]; @@ -304,6 +306,7 @@ int board_mmc_getcd(struct mmc *mmc); int mmc_switch_part(int dev_num, unsigned int part_num); int mmc_getcd(struct mmc *mmc); int mmc_getwp(struct mmc *mmc); +int mmc_set_dsr(struct mmc *mmc, u16 val); /* Function to change the size of boot partition and rpmb partitions */ int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize, unsigned long rpmbsize); -- cgit v1.3.1 From c5c1af21764d9423b45c1d03e835c4547a8bc5cb Mon Sep 17 00:00:00 2001 From: Chin Liang See Date: Mon, 30 Dec 2013 18:26:14 -0600 Subject: socfpga/dwmmc: Adding DesignWare MMC driver support for SOCFPGA To add the DesignWare MMC driver support for Altera SOCFPGA. It required information such as clocks and bus width from platform specific files (SOCFPGA handoff files) Signed-off-by: Chin Liang See Cc: Rajeshwari Shinde Cc: Jaehoon Chung Cc: Pantelis Antoniou Cc: Wolfgang Denk Acked-by: Pantelis Antoniou --- arch/arm/include/asm/arch-socfpga/dwmmc.h | 12 ++++ arch/arm/include/asm/arch-socfpga/system_manager.h | 65 +++++++++++++++++++++ doc/README.socfpga | 53 +++++++++++++++++ drivers/mmc/Makefile | 1 + drivers/mmc/socfpga_dw_mmc.c | 68 ++++++++++++++++++++++ 5 files changed, 199 insertions(+) create mode 100644 arch/arm/include/asm/arch-socfpga/dwmmc.h create mode 100644 doc/README.socfpga create mode 100644 drivers/mmc/socfpga_dw_mmc.c (limited to 'drivers') diff --git a/arch/arm/include/asm/arch-socfpga/dwmmc.h b/arch/arm/include/asm/arch-socfpga/dwmmc.h new file mode 100644 index 00000000000..945eb646ce8 --- /dev/null +++ b/arch/arm/include/asm/arch-socfpga/dwmmc.h @@ -0,0 +1,12 @@ +/* + * (C) Copyright 2013 Altera Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _SOCFPGA_DWMMC_H_ +#define _SOCFPGA_DWMMC_H_ + +extern int socfpga_dwmmc_init(u32 regbase, int bus_width, int index); + +#endif /* _SOCFPGA_SDMMC_H_ */ diff --git a/arch/arm/include/asm/arch-socfpga/system_manager.h b/arch/arm/include/asm/arch-socfpga/system_manager.h index d965d25effc..838d21053ef 100644 --- a/arch/arm/include/asm/arch-socfpga/system_manager.h +++ b/arch/arm/include/asm/arch-socfpga/system_manager.h @@ -19,4 +19,69 @@ extern unsigned long sys_mgr_init_table[CONFIG_HPS_PINMUX_NUM]; #define CONFIG_SYSMGR_PINMUXGRP_OFFSET (0x400) +#define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel) \ + ((((drvsel) << 0) & 0x7) | (((smplsel) << 3) & 0x38)) + +struct socfpga_system_manager { + u32 siliconid1; + u32 siliconid2; + u32 _pad_0x8_0xf[2]; + u32 wddbg; + u32 bootinfo; + u32 hpsinfo; + u32 parityinj; + u32 fpgaintfgrp_gbl; + u32 fpgaintfgrp_indiv; + u32 fpgaintfgrp_module; + u32 _pad_0x2c_0x2f; + u32 scanmgrgrp_ctrl; + u32 _pad_0x34_0x3f[3]; + u32 frzctrl_vioctrl; + u32 _pad_0x44_0x4f[3]; + u32 frzctrl_hioctrl; + u32 frzctrl_src; + u32 frzctrl_hwctrl; + u32 _pad_0x5c_0x5f; + u32 emacgrp_ctrl; + u32 emacgrp_l3master; + u32 _pad_0x68_0x6f[2]; + u32 dmagrp_ctrl; + u32 dmagrp_persecurity; + u32 _pad_0x78_0x7f[2]; + u32 iswgrp_handoff[8]; + u32 _pad_0xa0_0xbf[8]; + u32 romcodegrp_ctrl; + u32 romcodegrp_cpu1startaddr; + u32 romcodegrp_initswstate; + u32 romcodegrp_initswlastld; + u32 romcodegrp_bootromswstate; + u32 __pad_0xd4_0xdf[3]; + u32 romcodegrp_warmramgrp_enable; + u32 romcodegrp_warmramgrp_datastart; + u32 romcodegrp_warmramgrp_length; + u32 romcodegrp_warmramgrp_execution; + u32 romcodegrp_warmramgrp_crc; + u32 __pad_0xf4_0xff[3]; + u32 romhwgrp_ctrl; + u32 _pad_0x104_0x107; + u32 sdmmcgrp_ctrl; + u32 sdmmcgrp_l3master; + u32 nandgrp_bootstrap; + u32 nandgrp_l3master; + u32 usbgrp_l3master; + u32 _pad_0x11c_0x13f[9]; + u32 eccgrp_l2; + u32 eccgrp_ocram; + u32 eccgrp_usb0; + u32 eccgrp_usb1; + u32 eccgrp_emac0; + u32 eccgrp_emac1; + u32 eccgrp_dma; + u32 eccgrp_can0; + u32 eccgrp_can1; + u32 eccgrp_nand; + u32 eccgrp_qspi; + u32 eccgrp_sdmmc; +}; + #endif /* _SYSTEM_MANAGER_H_ */ diff --git a/doc/README.socfpga b/doc/README.socfpga new file mode 100644 index 00000000000..cfcbbfe3798 --- /dev/null +++ b/doc/README.socfpga @@ -0,0 +1,53 @@ + +-------------------------------------------- +SOCFPGA Documentation for U-Boot and SPL +-------------------------------------------- + +This README is about U-Boot and SPL support for Altera's ARM Cortex-A9MPCore +based SOCFPGA. To know more about the hardware itself, please refer to +www.altera.com. + + +-------------------------------------------- +socfpga_dw_mmc +-------------------------------------------- +Here are macro and detailed configuration required to enable DesignWare SDMMC +controller support within SOCFPGA + +#define CONFIG_MMC +-> To enable the SD MMC framework support + +#define CONFIG_SDMMC_BASE (SOCFPGA_SDMMC_ADDRESS) +-> The base address of CSR register for DesignWare SDMMC controller + +#define CONFIG_GENERIC_MMC +-> Enable the generic MMC driver + +#define CONFIG_SYS_MMC_MAX_BLK_COUNT 256 +-> Using smaller max blk cnt to avoid flooding the limited stack in OCRAM + +#define CONFIG_DWMMC +-> Enable the common DesignWare SDMMC controller framework + +#define CONFIG_SOCFPGA_DWMMC +-> Enable the SOCFPGA specific driver for DesignWare SDMMC controller + +#define CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH 1024 +-> The FIFO depth for SOCFPGA DesignWare SDMMC controller + +#define CONFIG_SOCFPGA_DWMMC_DRVSEL 3 +-> Phase-shifted clock of sdmmc_clk for controller to drive command and data to +the card to meet hold time requirements. SD clock is running at 50MHz and +drvsel is set to shift 135 degrees (3 * 45 degrees). With that, the hold time +is 135 / 360 * 20ns = 7.5ns. + +#define CONFIG_SOCFPGA_DWMMC_SMPSEL 0 +-> Phase-shifted clock of sdmmc_clk used to sample the command and data from +the card + +#define CONFIG_SOCFPGA_DWMMC_BUS_WIDTH 4 +-> Bus width of data line which either 1, 4 or 8 and based on board routing. + +#define CONFIG_SOCFPGA_DWMMC_BUS_HZ 50000000 +-> The clock rate to controller. Do note the controller have a wrapper which +divide the clock from PLL by 4. diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 1ed26cab34f..e793ed994e4 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_TEGRA_MMC) += tegra_mmc.o obj-$(CONFIG_DWMMC) += dw_mmc.o obj-$(CONFIG_EXYNOS_DWMMC) += exynos_dw_mmc.o obj-$(CONFIG_ZYNQ_SDHCI) += zynq_sdhci.o +obj-$(CONFIG_SOCFPGA_DWMMC) += socfpga_dw_mmc.o ifdef CONFIG_SPL_BUILD obj-$(CONFIG_SPL_MMC_BOOT) += fsl_esdhc_spl.o else diff --git a/drivers/mmc/socfpga_dw_mmc.c b/drivers/mmc/socfpga_dw_mmc.c new file mode 100644 index 00000000000..bc53a5da272 --- /dev/null +++ b/drivers/mmc/socfpga_dw_mmc.c @@ -0,0 +1,68 @@ +/* + * (C) Copyright 2013 Altera Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include + +static const struct socfpga_clock_manager *clock_manager_base = + (void *)SOCFPGA_CLKMGR_ADDRESS; +static const struct socfpga_system_manager *system_manager_base = + (void *)SOCFPGA_SYSMGR_ADDRESS; + +static char *SOCFPGA_NAME = "SOCFPGA DWMMC"; + +static void socfpga_dwmci_clksel(struct dwmci_host *host) +{ + unsigned int drvsel; + unsigned int smplsel; + + /* Disable SDMMC clock. */ + clrbits_le32(&clock_manager_base->per_pll_en, + CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK); + + /* Configures drv_sel and smpl_sel */ + drvsel = CONFIG_SOCFPGA_DWMMC_DRVSEL; + smplsel = CONFIG_SOCFPGA_DWMMC_SMPSEL; + + debug("%s: drvsel %d smplsel %d\n", __func__, drvsel, smplsel); + writel(SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel), + &system_manager_base->sdmmcgrp_ctrl); + + debug("%s: SYSMGR_SDMMCGRP_CTRL_REG = 0x%x\n", __func__, + readl(&system_manager_base->sdmmcgrp_ctrl)); + + /* Enable SDMMC clock */ + setbits_le32(&clock_manager_base->per_pll_en, + CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK); +} + +int socfpga_dwmmc_init(u32 regbase, int bus_width, int index) +{ + struct dwmci_host *host = NULL; + host = calloc(sizeof(struct dwmci_host), 1); + if (!host) { + printf("dwmci_host calloc fail!\n"); + return -1; + } + + host->name = SOCFPGA_NAME; + host->ioaddr = (void *)regbase; + host->buswidth = bus_width; + host->clksel = socfpga_dwmci_clksel; + host->dev_index = index; + /* fixed clock divide by 4 which due to the SDMMC wrapper */ + host->bus_hz = CONFIG_SOCFPGA_DWMMC_BUS_HZ; + host->fifoth_val = MSIZE(0x2) | + RX_WMARK(CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH / 2 - 1) | + TX_WMARK(CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH / 2); + + return add_dwmci(host, host->bus_hz, 400000); +} + -- cgit v1.3.1 From 22e75d6d60516f45347c399f2d4efa35c30c773b Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Wed, 8 Jan 2014 10:16:25 +0900 Subject: spi: sh_qspi: Add header file that defines the address of registers Signed-off-by: Nobuhiro Iwamatsu Reviewed-by: Jagannadha Sutradharudu Teki Signed-off-by: Nobuhiro Iwamatsu --- drivers/spi/sh_qspi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/sh_qspi.c b/drivers/spi/sh_qspi.c index edeb42d0388..77ede6bba3a 100644 --- a/drivers/spi/sh_qspi.c +++ b/drivers/spi/sh_qspi.c @@ -10,6 +10,7 @@ #include #include #include +#include #include /* SH QSPI register bit masks _ */ @@ -170,7 +171,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, return NULL; } - ss->regs = (struct sh_qspi_regs *)CONFIG_SH_QSPI_BASE; + ss->regs = (struct sh_qspi_regs *)SH_QSPI_BASE; /* Init SH QSPI */ sh_qspi_init(ss); -- cgit v1.3.1