From 282a82e8a10ce6ef132d7a809101fdaed951001c Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Wed, 6 Aug 2014 18:14:35 +0800 Subject: mmc: set correct block size value in bfin sdh driver Wait data transfer till the data end bit other than the data block end bit is set. Acked-by: Pantelis Antoniou Signed-off-by: Sonic Zhang --- drivers/mmc/bfin_sdh.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/bfin_sdh.c b/drivers/mmc/bfin_sdh.c index bcd6a3e52f..9bdfbbca01 100644 --- a/drivers/mmc/bfin_sdh.c +++ b/drivers/mmc/bfin_sdh.c @@ -138,9 +138,9 @@ static int sdh_setup_data(struct mmc *mmc, struct mmc_data *data) if (data->flags & MMC_DATA_WRITE) return UNUSABLE_ERR; #ifndef RSI_BLKSZ - data_ctl |= ((ffs(data_size) - 1) << 4); + data_ctl |= ((ffs(data->blocksize) - 1) << 4); #else - bfin_write_SDH_BLK_SIZE(data_size); + bfin_write_SDH_BLK_SIZE(data->blocksize); #endif data_ctl |= DTX_DIR; bfin_write_SDH_DATA_CTL(data_ctl); @@ -189,7 +189,8 @@ static int bfin_sdh_request(struct mmc *mmc, struct mmc_cmd *cmd, do { udelay(1); status = bfin_read_SDH_STATUS(); - } while (!(status & (DAT_BLK_END | DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL | RX_OVERRUN))); + } while (!(status & (DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL | + RX_OVERRUN))); if (status & DAT_TIME_OUT) { bfin_write_SDH_STATUS_CLR(DAT_TIMEOUT_STAT); -- cgit v1.2.1 From 021a80559f4293368558cc10dbbc75b26ecab059 Mon Sep 17 00:00:00 2001 From: Hannes Petermaier Date: Fri, 8 Aug 2014 09:47:22 +0200 Subject: mmc: fix ERASE_GRP_DEF handling if we set manually this bit on the eMMC card using mmc_switch(...), we also have to set it within our (before read) internal structure 'ext_csd'. Otherwise following checks on this will fail. Acked-by: Pantelis Antoniou Signed-off-by: Hannes Petermaier --- drivers/mmc/mmc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index a26f3cec20..52a8e36312 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -1010,6 +1010,8 @@ static int mmc_startup(struct mmc *mmc) if (err) return err; + else + ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1; /* Read out group size from ext_csd */ mmc->erase_grp_size = -- cgit v1.2.1 From 6dc93e7087ccac1acb6910ac8838d9e90c602fe4 Mon Sep 17 00:00:00 2001 From: Peter Bigot Date: Tue, 2 Sep 2014 18:31:23 -0500 Subject: mmc: restore capacity when switching to partition 0 The capacity and lba for an MMC device with part_num 0 reflects the whole device. When mmc_switch_part() successfully switches to a partition, the capacity is changed to that partition. As partition 0 does not physically exist, attempts to switch back to the whole device will indicate an error, but the capacity setting for the whole device must still be restored to match the partition. Signed-off-by: Peter A. Bigot Tested-by: Tom Rini Acked-by: Pantelis Antoniou --- drivers/mmc/mmc.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 52a8e36312..e4a28d4b4a 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -594,10 +594,15 @@ int mmc_switch_part(int dev_num, unsigned int part_num) ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF, (mmc->part_config & ~PART_ACCESS_MASK) | (part_num & PART_ACCESS_MASK)); - if (ret) - return ret; - return mmc_set_capacity(mmc, part_num); + /* + * Set the capacity if the switch succeeded or was intended + * to return to representing the raw device. + */ + if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0))) + ret = mmc_set_capacity(mmc, part_num); + + return ret; } int mmc_getcd(struct mmc *mmc) -- cgit v1.2.1 From bcd06989b860c691f5afbd1c03d1b0d9e9970cdc Mon Sep 17 00:00:00 2001 From: Mario Schuknecht Date: Mon, 25 Aug 2014 14:12:26 +0200 Subject: mvebu_mmc: Driver addition In function mvebu_mmc_write notice command timeout. It is possible that a command is done, but a timeout occurred. Enable timeout in set bus function. Set window registers. Without that I could not use the driver on a Kirkwood 88F6282 SoC. Set high capacity and 52MHz driver feature. Signed-off-by: Mario Schuknecht Reviewed-by: Stefan Roese Acked-by: Pantelis Antoniou --- drivers/mmc/mvebu_mmc.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/mvebu_mmc.c b/drivers/mmc/mvebu_mmc.c index 97591983d2..d34e74357f 100644 --- a/drivers/mmc/mvebu_mmc.c +++ b/drivers/mmc/mvebu_mmc.c @@ -17,8 +17,12 @@ #include #include +DECLARE_GLOBAL_DATA_PTR; + #define DRIVER_NAME "MVEBU_MMC" +#define MVEBU_TARGET_DRAM 0 + static void mvebu_mmc_write(u32 offs, u32 val) { writel(val, CONFIG_SYS_MMC_BASE + (offs)); @@ -164,6 +168,9 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, return TIMEOUT; } } + if (mvebu_mmc_read(SDIO_ERR_INTR_STATUS) & + (SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT)) + return TIMEOUT; /* Handling response */ if (cmd->resp_type & MMC_RSP_136) { @@ -271,6 +278,7 @@ static void mvebu_mmc_set_bus(unsigned int bus) /* default to maximum timeout */ ctrl_reg |= SDIO_HOST_CTRL_TMOUT(SDIO_HOST_CTRL_TMOUT_MAX); + ctrl_reg |= SDIO_HOST_CTRL_TMOUT_EN; ctrl_reg |= SDIO_HOST_CTRL_PUSH_PULL_EN; @@ -296,6 +304,55 @@ static void mvebu_mmc_set_ios(struct mmc *mmc) mvebu_mmc_set_clk(mmc->clock); } +/* + * Set window register. + */ +static void mvebu_window_setup(void) +{ + int i; + + for (i = 0; i < 4; i++) { + mvebu_mmc_write(WINDOW_CTRL(i), 0); + mvebu_mmc_write(WINDOW_BASE(i), 0); + } + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + u32 size, base, attrib; + + /* Enable DRAM bank */ + switch (i) { + case 0: + attrib = KWCPU_ATTR_DRAM_CS0; + break; + case 1: + attrib = KWCPU_ATTR_DRAM_CS1; + break; + case 2: + attrib = KWCPU_ATTR_DRAM_CS2; + break; + case 3: + attrib = KWCPU_ATTR_DRAM_CS3; + break; + default: + /* invalide bank, disable access */ + attrib = 0; + break; + } + + size = gd->bd->bi_dram[i].size; + base = gd->bd->bi_dram[i].start; + if (size && attrib) { + mvebu_mmc_write(WINDOW_CTRL(i), + MVCPU_WIN_CTRL_DATA(size, + MVEBU_TARGET_DRAM, + attrib, + MVCPU_WIN_ENABLE)); + } else { + mvebu_mmc_write(WINDOW_CTRL(i), MVCPU_WIN_DISABLE); + } + mvebu_mmc_write(WINDOW_BASE(i), base); + } +} + static int mvebu_mmc_initialize(struct mmc *mmc) { debug("%s: mvebu_mmc_initialize", DRIVER_NAME); @@ -322,6 +379,8 @@ static int mvebu_mmc_initialize(struct mmc *mmc) mvebu_mmc_write(SDIO_NOR_INTR_EN, 0); mvebu_mmc_write(SDIO_ERR_INTR_EN, 0); + mvebu_window_setup(); + /* SW reset */ mvebu_mmc_write(SDIO_SW_RESET, SDIO_SW_RESET_NOW); @@ -342,7 +401,8 @@ static struct mmc_config mvebu_mmc_cfg = { .f_min = MVEBU_MMC_BASE_FAST_CLOCK / MVEBU_MMC_BASE_DIV_MAX, .f_max = MVEBU_MMC_CLOCKRATE_MAX, .voltages = MMC_VDD_32_33 | MMC_VDD_33_34, - .host_caps = MMC_MODE_4BIT | MMC_MODE_HS, + .host_caps = MMC_MODE_4BIT | MMC_MODE_HS | MMC_MODE_HC | + MMC_MODE_HS_52MHz, .part_type = PART_TYPE_DOS, .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT, }; -- cgit v1.2.1 From 786a27b7ec9efd1ebf50008050e3cff9ce458198 Mon Sep 17 00:00:00 2001 From: Mario Schuknecht Date: Tue, 30 Sep 2014 17:04:42 +0200 Subject: mmc: Fix mmc bus width After setting the bus width, the extended CSD register is read. Some selected fields are compared with previously read extended CSD register fields. In this comparison the EXT_CSD_ERASE_GROUP_DEF field is compared. But this field is previously written under certain circumstances. And then the comparison fails. Only compare read-only fields. Therefore compare field EXT_CSD_HC_WP_GRP_SIZE instead of field EXT_CSD_ERASE_GROUP_DEF. Signed-off-by: Mario Schuknecht Acked-by: Pantelis Antoniou --- drivers/mmc/mmc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index e4a28d4b4a..44a4feb96e 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -1134,10 +1134,11 @@ static int mmc_startup(struct mmc *mmc) mmc_set_bus_width(mmc, widths[idx]); err = mmc_send_ext_csd(mmc, test_csd); + /* Only compare read only fields */ if (!err && ext_csd[EXT_CSD_PARTITIONING_SUPPORT] \ == test_csd[EXT_CSD_PARTITIONING_SUPPORT] - && ext_csd[EXT_CSD_ERASE_GROUP_DEF] \ - == test_csd[EXT_CSD_ERASE_GROUP_DEF] \ + && ext_csd[EXT_CSD_HC_WP_GRP_SIZE] \ + == test_csd[EXT_CSD_HC_WP_GRP_SIZE] \ && ext_csd[EXT_CSD_REV] \ == test_csd[EXT_CSD_REV] && ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] \ -- cgit v1.2.1 From b966db0d7259293e2c9c216c7a5dce30dacacfd9 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 5 Sep 2014 12:49:48 +0200 Subject: dw_mmc: cleanups dw_mmc driver was responding to errors with debug(). Change that to prinf so that any errors are immediately obvious. Also adjust english in comments. Signed-off-by: Pavel Machek Acked-by: Pantelis Antoniou --- drivers/mmc/dw_mmc.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 0df30bc045..4c16e7f602 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -177,14 +177,16 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, } } - if (i == retry) + if (i == retry) { + printf("dwmci_send_cmd: timeout..\n"); return TIMEOUT; + } if (mask & DWMCI_INTMSK_RTO) { - debug("Response Timeout..\n"); + printf("dwmci_send_cmd: Response Timeout..\n"); return TIMEOUT; } else if (mask & DWMCI_INTMSK_RE) { - debug("Response Error..\n"); + printf("dwmci_send_cmd: Response Error..\n"); return -1; } @@ -204,7 +206,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, do { mask = dwmci_readl(host, DWMCI_RINTSTS); if (mask & (DWMCI_DATA_ERR | DWMCI_DATA_TOUT)) { - debug("DATA ERROR!\n"); + printf("dwmci_send_cmd: DATA ERROR!\n"); return -1; } } while (!(mask & DWMCI_INTMSK_DTO)); @@ -232,16 +234,16 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq) if ((freq == host->clock) || (freq == 0)) return 0; /* - * If host->get_mmc_clk didn't define, + * If host->get_mmc_clk isn't defined, * then assume that host->bus_hz is source clock value. - * host->bus_hz should be set from user. + * host->bus_hz should be set by user. */ if (host->get_mmc_clk) sclk = host->get_mmc_clk(host); else if (host->bus_hz) sclk = host->bus_hz; else { - printf("Didn't get source clock value..\n"); + printf("dwmci_setup_bus: Didn't get source clock value..\n"); return -EINVAL; } @@ -260,7 +262,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq) do { status = dwmci_readl(host, DWMCI_CMD); if (timeout-- < 0) { - printf("TIMEOUT error!!\n"); + printf("dwmci_setup_bus: timeout!\n"); return -ETIMEDOUT; } } while (status & DWMCI_CMD_START); @@ -275,7 +277,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq) do { status = dwmci_readl(host, DWMCI_CMD); if (timeout-- < 0) { - printf("TIMEOUT error!!\n"); + printf("dwmci_setup_bus: timeout!\n"); return -ETIMEDOUT; } } while (status & DWMCI_CMD_START); @@ -290,7 +292,7 @@ static void dwmci_set_ios(struct mmc *mmc) struct dwmci_host *host = (struct dwmci_host *)mmc->priv; u32 ctype, regs; - debug("Buswidth = %d, clock: %d\n",mmc->bus_width, mmc->clock); + debug("Buswidth = %d, clock: %d\n", mmc->bus_width, mmc->clock); dwmci_setup_bus(host, mmc->clock); switch (mmc->bus_width) { @@ -329,7 +331,7 @@ static int dwmci_init(struct mmc *mmc) dwmci_writel(host, DWMCI_PWREN, 1); if (!dwmci_wait_reset(host, DWMCI_RESET_ALL)) { - debug("%s[%d] Fail-reset!!\n",__func__,__LINE__); + printf("%s[%d] Fail-reset!!\n", __func__, __LINE__); return -1; } -- cgit v1.2.1 From 91693055995733e268874ae75568ae316233e116 Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Thu, 4 Sep 2014 12:23:09 +0300 Subject: cfi_flash: don't hide write/erase errors Partially revert commit 0d01f66d235118 (CFI: cfi_flash write fix for AMD legacy). flash_full_status_check() used to skip status register parsing when flash_status_check() returns OK. This is wrong since flash_status_check() must return OK for other status bits to be valid. Cc: Ed Swarthout Signed-off-by: Baruch Siach Signed-off-by: Stefan Roese --- drivers/mtd/cfi_flash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index c4b5bc1de5..9b3175d87f 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -593,7 +593,7 @@ static int flash_full_status_check (flash_info_t * info, flash_sect_t sector, case CFI_CMDSET_INTEL_PROG_REGIONS: case CFI_CMDSET_INTEL_EXTENDED: case CFI_CMDSET_INTEL_STANDARD: - if ((retcode != ERR_OK) + if ((retcode == ERR_OK) && !flash_isequal (info, sector, 0, FLASH_STATUS_DONE)) { retcode = ERR_INVAL; printf ("Flash %s error at address %lx\n", prompt, -- cgit v1.2.1 From 4e2c4ad3604ba6f5053090749d64ed3ce5914805 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 20 Sep 2014 16:51:22 +0200 Subject: usb: ehci: Properly set hub devnum and portnr with usb-1 hubs in the chain For full / low speed devices we need to get the devnum and portnr of the tt, so of the first upstream usb-2 hub, not of the parent device (which may be a usb-1 hub). Signed-off-by: Hans de Goede --- drivers/usb/host/ehci-hcd.c | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index eaf59134cb..41af302e03 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -273,6 +273,29 @@ static inline u8 ehci_encode_speed(enum usb_device_speed speed) return QH_FULL_SPEED; } +static void ehci_update_endpt2_dev_n_port(struct usb_device *dev, + struct QH *qh) +{ + struct usb_device *ttdev; + + if (dev->speed != USB_SPEED_LOW && dev->speed != USB_SPEED_FULL) + return; + + /* + * For full / low speed devices we need to get the devnum and portnr of + * the tt, so of the first upstream usb-2 hub, there may be usb-1 hubs + * in the tree before that one! + */ + ttdev = dev; + while (ttdev->parent && ttdev->parent->speed != USB_SPEED_HIGH) + ttdev = ttdev->parent; + if (!ttdev->parent) + return; + + qh->qh_endpt2 |= cpu_to_hc32(QH_ENDPT2_PORTNUM(ttdev->portnr) | + QH_ENDPT2_HUBADDR(ttdev->parent->devnum)); +} + static int ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, int length, struct devrequest *req) @@ -390,10 +413,9 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, QH_ENDPT1_ENDPT(usb_pipeendpoint(pipe)) | QH_ENDPT1_I(0) | QH_ENDPT1_DEVADDR(usb_pipedevice(pipe)); qh->qh_endpt1 = cpu_to_hc32(endpt); - endpt = QH_ENDPT2_MULT(1) | QH_ENDPT2_PORTNUM(dev->portnr) | - QH_ENDPT2_HUBADDR(dev->parent->devnum) | - QH_ENDPT2_UFCMASK(0) | QH_ENDPT2_UFSMASK(0); + endpt = QH_ENDPT2_MULT(1) | QH_ENDPT2_UFCMASK(0) | QH_ENDPT2_UFSMASK(0); qh->qh_endpt2 = cpu_to_hc32(endpt); + ehci_update_endpt2_dev_n_port(dev, qh); qh->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE); qh->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE); @@ -1201,12 +1223,10 @@ create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize, (1 << 0)); /* S-mask: microframe 0 */ if (dev->speed == USB_SPEED_LOW || dev->speed == USB_SPEED_FULL) { - debug("TT: port: %d, hub address: %d\n", - dev->portnr, dev->parent->devnum); - qh->qh_endpt2 |= cpu_to_hc32((dev->portnr << 23) | - (dev->parent->devnum << 16) | - (0x1c << 8)); /* C-mask: microframes 2-4 */ + /* C-mask: microframes 2-4 */ + qh->qh_endpt2 |= cpu_to_hc32((0x1c << 8)); } + ehci_update_endpt2_dev_n_port(dev, qh); td->qt_next = cpu_to_hc32(QT_NEXT_TERMINATE); td->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE); -- cgit v1.2.1 From ea7b30c58973d59396c71d5880a652639d479a68 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 20 Sep 2014 16:51:23 +0200 Subject: usb: ehci: Add missing cache flush to destroy_int_queue Signed-off-by: Hans de Goede --- drivers/usb/host/ehci-hcd.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 41af302e03..1a0ddc3d51 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1342,6 +1342,8 @@ destroy_int_queue(struct usb_device *dev, struct int_queue *queue) if (NEXT_QH(cur) == queue->first) { debug("found candidate. removing from chain\n"); cur->qh_link = queue->last->qh_link; + flush_dcache_range((uint32_t)cur, + ALIGN_END_ADDR(struct QH, cur, 1)); result = 0; break; } -- cgit v1.2.1 From 415548d88446134549917aae026f53dbbee36fd2 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 20 Sep 2014 16:51:24 +0200 Subject: usb: ehci: poll_int_queue check real qtd, not the overlay When we first start an int queue, the qh's overlay area is all zeros. This gets filled by the hc with the actual qtd values as soon as it advances the queue, but we may call poll_int_queue before then, in which case we would think the transfer has completed as the hc has not yet copied the qt_token to the overlay, so the active flag is not set. This fixes this by checking the actual qtd token, rather then the overlay. This also fixes a (theoretical) race where we see the completion in the overlay and free and re-use the qtd before the hc has completed writing back the overlay to the actual qtd. Signed-off-by: Hans de Goede --- drivers/usb/host/ehci-hcd.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 1a0ddc3d51..635a3b4511 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1297,6 +1297,7 @@ fail1: void *poll_int_queue(struct usb_device *dev, struct int_queue *queue) { struct QH *cur = queue->current; + struct qTD *cur_td; /* depleted queue */ if (cur == NULL) { @@ -1304,20 +1305,21 @@ void *poll_int_queue(struct usb_device *dev, struct int_queue *queue) return NULL; } /* still active */ - invalidate_dcache_range((uint32_t)cur, - ALIGN_END_ADDR(struct QH, cur, 1)); - if (cur->qh_overlay.qt_token & cpu_to_hc32(0x80)) { - debug("Exit poll_int_queue with no completed intr transfer. " - "token is %x\n", cur->qh_overlay.qt_token); + cur_td = &queue->tds[queue->current - queue->first]; + invalidate_dcache_range((uint32_t)cur_td, + ALIGN_END_ADDR(struct qTD, cur_td, 1)); + if (QT_TOKEN_GET_STATUS(hc32_to_cpu(cur_td->qt_token)) & + QT_TOKEN_STATUS_ACTIVE) { + debug("Exit poll_int_queue with no completed intr transfer. token is %x\n", + hc32_to_cpu(cur_td->qt_token)); return NULL; } if (!(cur->qh_link & QH_LINK_TERMINATE)) queue->current++; else queue->current = NULL; - debug("Exit poll_int_queue with completed intr transfer. " - "token is %x at %p (first at %p)\n", cur->qh_overlay.qt_token, - &cur->qh_overlay.qt_token, queue->first); + debug("Exit poll_int_queue with completed intr transfer. token is %x at %p (first at %p)\n", + hc32_to_cpu(cur_td->qt_token), cur, queue->first); return cur->buffer; } -- cgit v1.2.1 From 36b73109c49c1359a5fcc790c00717cb27468c12 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 20 Sep 2014 16:51:25 +0200 Subject: usb: ehci: Make periodic_schedules a per controller variable Periodic schedules tracks how many int_queue-s are active, and decides whether or not to en/disable the periodic schedule based on this. This is clearly a per controller thing. Signed-off-by: Hans de Goede --- drivers/usb/host/ehci-hcd.c | 9 ++++----- drivers/usb/host/ehci.h | 1 + 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 635a3b4511..6323c50837 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -996,6 +996,7 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) * Set up periodic list * Step 1: Parent QH for all periodic transfers. */ + ehcic[index].periodic_schedules = 0; periodic = &ehcic[index].periodic_queue; memset(periodic, 0, sizeof(*periodic)); periodic->qh_link = cpu_to_hc32(QH_LINK_TERMINATE); @@ -1154,8 +1155,6 @@ disable_periodic(struct ehci_ctrl *ctrl) return 0; } -static int periodic_schedules; - struct int_queue * create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize, int elementsize, void *buffer) @@ -1278,7 +1277,7 @@ create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize, debug("FATAL: periodic should never fail, but did"); goto fail3; } - periodic_schedules++; + ctrl->periodic_schedules++; debug("Exit create_int_queue\n"); return result; @@ -1335,7 +1334,7 @@ destroy_int_queue(struct usb_device *dev, struct int_queue *queue) debug("FATAL: periodic should never fail, but did"); goto out; } - periodic_schedules--; + ctrl->periodic_schedules--; struct QH *cur = &ctrl->periodic_queue; timeout = get_timer(0) + 500; /* abort after 500ms */ @@ -1357,7 +1356,7 @@ destroy_int_queue(struct usb_device *dev, struct int_queue *queue) } } - if (periodic_schedules > 0) { + if (ctrl->periodic_schedules > 0) { result = enable_periodic(ctrl); if (result < 0) debug("FATAL: periodic should never fail, but did"); diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 093eb4b832..433e703da8 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -246,6 +246,7 @@ struct ehci_ctrl { struct QH qh_list __aligned(USB_DMA_MINALIGN); struct QH periodic_queue __aligned(USB_DMA_MINALIGN); uint32_t *periodic_list; + int periodic_schedules; int ntds; }; -- cgit v1.2.1 From 32d019265d1f0c334f2f86407abf295d46bd2f4d Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 20 Sep 2014 16:54:37 +0200 Subject: stdio: Add force parameter to stdio_deregister In some cases we really want to move forward with a deregister, add a force parameter to allow this, and replace the dev with a nulldev in this case. Signed-off-by: Hans de Goede --- drivers/serial/serial-uclass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c index 1ac943f692..fd010cac42 100644 --- a/drivers/serial/serial-uclass.c +++ b/drivers/serial/serial-uclass.c @@ -198,7 +198,7 @@ static int serial_pre_remove(struct udevice *dev) #ifdef CONFIG_SYS_STDIO_DEREGISTER struct serial_dev_priv *upriv = dev->uclass_priv; - if (stdio_deregister_dev(upriv->sdev)) + if (stdio_deregister_dev(upriv->sdev), 0) return -EPERM; #endif -- cgit v1.2.1 From b9c99d32466b90aa2269eca99545f045a23266ab Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Thu, 11 Sep 2014 15:26:10 +0200 Subject: usb: dfu: thor: gadget: Remove dead code This code is not used anymore in the current DFU implementation and can be safely removed. Signed-off-by: Lukasz Majewski --- drivers/usb/gadget/f_dfu.c | 8 -------- drivers/usb/gadget/f_thor.c | 10 ---------- 2 files changed, 18 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c index 3e4f02932b..d040606e6f 100644 --- a/drivers/usb/gadget/f_dfu.c +++ b/drivers/usb/gadget/f_dfu.c @@ -81,14 +81,6 @@ static struct usb_descriptor_header *dfu_runtime_descs[] = { NULL, }; -static const struct usb_qualifier_descriptor dev_qualifier = { - .bLength = sizeof dev_qualifier, - .bDescriptorType = USB_DT_DEVICE_QUALIFIER, - .bcdUSB = __constant_cpu_to_le16(0x0200), - .bDeviceClass = USB_CLASS_VENDOR_SPEC, - .bNumConfigurations = 1, -}; - static const char dfu_name[] = "Device Firmware Upgrade"; /* diff --git a/drivers/usb/gadget/f_thor.c b/drivers/usb/gadget/f_thor.c index c85b0fbd3c..78519fa41f 100644 --- a/drivers/usb/gadget/f_thor.c +++ b/drivers/usb/gadget/f_thor.c @@ -458,16 +458,6 @@ static struct usb_endpoint_descriptor hs_int_desc = { .bInterval = 0x9, }; -static struct usb_qualifier_descriptor dev_qualifier = { - .bLength = sizeof(dev_qualifier), - .bDescriptorType = USB_DT_DEVICE_QUALIFIER, - - .bcdUSB = __constant_cpu_to_le16(0x0200), - .bDeviceClass = USB_CLASS_VENDOR_SPEC, - - .bNumConfigurations = 2, -}; - /* * This attribute vendor descriptor is necessary for correct operation with * Windows version of THOR download program -- cgit v1.2.1 From 9f3b8ed14cef1e277f1362f121e16975bba2026f Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Wed, 10 Sep 2014 08:55:00 +0200 Subject: usb: dfu: add fullspeed support for DFU DFU now can use also fullspeed. Signed-off-by: Heiko Schocher Cc: Tom Rini Cc: Lukasz Majewski Cc: Marek Vasut Cc: Liu Bin Cc: Lukas Stockmann --- drivers/usb/gadget/f_dfu.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c index d040606e6f..16fc9ddf82 100644 --- a/drivers/usb/gadget/f_dfu.c +++ b/drivers/usb/gadget/f_dfu.c @@ -229,6 +229,7 @@ static inline void to_dfu_mode(struct f_dfu *f_dfu) { f_dfu->usb_function.strings = dfu_strings; f_dfu->usb_function.hs_descriptors = f_dfu->function; + f_dfu->usb_function.descriptors = f_dfu->function; f_dfu->dfu_state = DFU_STATE_dfuIDLE; } @@ -236,6 +237,7 @@ static inline void to_runtime_mode(struct f_dfu *f_dfu) { f_dfu->usb_function.strings = NULL; f_dfu->usb_function.hs_descriptors = dfu_runtime_descs; + f_dfu->usb_function.descriptors = dfu_runtime_descs; } static int handle_upload(struct usb_request *req, u16 len) @@ -800,6 +802,7 @@ static int dfu_bind_config(struct usb_configuration *c) return -ENOMEM; f_dfu->usb_function.name = "dfu"; f_dfu->usb_function.hs_descriptors = dfu_runtime_descs; + f_dfu->usb_function.descriptors = dfu_runtime_descs; f_dfu->usb_function.bind = dfu_bind; f_dfu->usb_function.unbind = dfu_unbind; f_dfu->usb_function.set_alt = dfu_set_alt; -- cgit v1.2.1 From f9935c87b6c8e81ef8d621bd06d24a78eec8a821 Mon Sep 17 00:00:00 2001 From: Eric Nelson Date: Fri, 19 Sep 2014 17:06:46 -0700 Subject: usb: f_mass_storage: set removable flag in do_inquiry based on LUN Without this flag, tools like Alex Page's USB Image Tool won't see drives exposed over USB Gadget as removable, and won't allow access to them. http://www.alexpage.de/usb-image-tool/ The code was pulled from the main-line kernel: drivers/usb/gadget/function/f_mass_storage.c Signed-off-by: Eric Nelson --- drivers/usb/gadget/f_mass_storage.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index f274d9679f..e045957d07 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -1110,6 +1110,7 @@ static int do_inquiry(struct fsg_common *common, struct fsg_buffhd *bh) memset(buf, 0, 8); buf[0] = TYPE_DISK; + buf[1] = curlun->removable ? 0x80 : 0; buf[2] = 2; /* ANSI SCSI level 2 */ buf[3] = 2; /* SCSI-2 INQUIRY data format */ buf[4] = 31; /* Additional length */ -- cgit v1.2.1 From 23d1d10c4248f1b9f838e512e7f18e600f06b348 Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Fri, 19 Sep 2014 14:15:12 +0800 Subject: usb: gadget: fastboot: improve download progress bar When download is ongoing, if the actual size of one transfer is not the same as BYTES_PER_DOT, which will cause the dot won't print anymore. Then it will let the user thinking it is stuck, actually it is transfering without dot printed. So, improve the method to show the progress bar (print dot). Signed-off-by: Bo Shen Acked-by: Marek Vasut --- drivers/usb/gadget/f_fastboot.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c index 38c09658cc..9d15f6352e 100644 --- a/drivers/usb/gadget/f_fastboot.c +++ b/drivers/usb/gadget/f_fastboot.c @@ -386,6 +386,7 @@ static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req) unsigned int transfer_size = download_size - download_bytes; const unsigned char *buffer = req->buf; unsigned int buffer_size = req->actual; + unsigned int pre_dot_num, now_dot_num; if (req->status != 0) { printf("Bad status: %d\n", req->status); @@ -398,7 +399,15 @@ static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req) memcpy((void *)CONFIG_USB_FASTBOOT_BUF_ADDR + download_bytes, buffer, transfer_size); + pre_dot_num = download_bytes / BYTES_PER_DOT; download_bytes += transfer_size; + now_dot_num = download_bytes / BYTES_PER_DOT; + + if (pre_dot_num != now_dot_num) { + putc('.'); + if (!(now_dot_num % 74)) + putc('\n'); + } /* Check if transfer is done */ if (download_bytes >= download_size) { @@ -420,11 +429,6 @@ static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req) req->length = ep->maxpacket; } - if (download_bytes && !(download_bytes % BYTES_PER_DOT)) { - putc('.'); - if (!(download_bytes % (74 * BYTES_PER_DOT))) - putc('\n'); - } req->actual = 0; usb_ep_queue(ep, req, 0); } -- cgit v1.2.1 From e206799370f77097a29577599960b7f123f61b8c Mon Sep 17 00:00:00 2001 From: Eric Nelson Date: Sun, 28 Sep 2014 18:35:14 -0700 Subject: usb: ci_udc: respect CONFIG_USB_GADGET_DUALSPEED Force full-speed (12 Mbit/s) operation if CONFIG_USB_GADGET_DUALSPEED is not defined. The controller is capable of high-speed (480 Mbit/s) operation, but some designs may require the use of lower-speed operation. Signed-off-by: Eric Nelson --- drivers/usb/gadget/ci_udc.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/ci_udc.c b/drivers/usb/gadget/ci_udc.c index 2572b346eb..b0ef35e745 100644 --- a/drivers/usb/gadget/ci_udc.c +++ b/drivers/usb/gadget/ci_udc.c @@ -777,6 +777,11 @@ static int ci_pullup(struct usb_gadget *gadget, int is_on) /* select DEVICE mode */ writel(USBMODE_DEVICE, &udc->usbmode); +#if !defined(CONFIG_USB_GADGET_DUALSPEED) + /* Port force Full-Speed Connect */ + setbits_le32(&udc->portsc, PFSC); +#endif + writel(0xffffffff, &udc->epflush); /* Turn on the USB connection by enabling the pullup resistor */ -- cgit v1.2.1 From c674a6660e9934cf332bb007726997b1c3686bf1 Mon Sep 17 00:00:00 2001 From: Eric Nelson Date: Tue, 30 Sep 2014 12:05:40 -0700 Subject: usb: gadget: fastboot: add max-download-size variable Current Android Fastboot seems to use 'max-download-size' instead of 'downloadsize' variable to indicate the maximum size of sparse segments. See function get_target_sparse_limit() in file fastboot/fastboot.c in the AOSP: https://android.googlesource.com/platform/system/core/+/master Signed-off-by: Eric Nelson --- drivers/usb/gadget/f_fastboot.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c index 9d15f6352e..3e1c0a9faf 100644 --- a/drivers/usb/gadget/f_fastboot.c +++ b/drivers/usb/gadget/f_fastboot.c @@ -351,7 +351,8 @@ static void cb_getvar(struct usb_ep *ep, struct usb_request *req) strncat(response, FASTBOOT_VERSION, chars_left); } else if (!strcmp_l1("bootloader-version", cmd)) { strncat(response, U_BOOT_VERSION, chars_left); - } else if (!strcmp_l1("downloadsize", cmd)) { + } else if (!strcmp_l1("downloadsize", cmd) || + !strcmp_l1("max-download-size", cmd)) { char str_num[12]; sprintf(str_num, "%08x", CONFIG_USB_FASTBOOT_BUF_SIZE); -- cgit v1.2.1 From 84c24f66c2971f2a4149f60228bfc08f29ba9d30 Mon Sep 17 00:00:00 2001 From: Eric Nelson Date: Tue, 30 Sep 2014 12:05:41 -0700 Subject: usb: gadget: fastboot: explicitly set radix of maximum download size The processing of the max-download-size variable requires a radix specifier, or the fastboot host tool will interpret it as an octal number. See function get_target_sparse_limit() in file fastboot/fastboot.c in the AOSP: https://android.googlesource.com/platform/system/core/+/master Signed-off-by: Eric Nelson --- drivers/usb/gadget/f_fastboot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c index 3e1c0a9faf..392379dce4 100644 --- a/drivers/usb/gadget/f_fastboot.c +++ b/drivers/usb/gadget/f_fastboot.c @@ -355,7 +355,7 @@ static void cb_getvar(struct usb_ep *ep, struct usb_request *req) !strcmp_l1("max-download-size", cmd)) { char str_num[12]; - sprintf(str_num, "%08x", CONFIG_USB_FASTBOOT_BUF_SIZE); + sprintf(str_num, "0x%08x", CONFIG_USB_FASTBOOT_BUF_SIZE); strncat(response, str_num, chars_left); } else if (!strcmp_l1("serialno", cmd)) { s = getenv("serial#"); -- cgit v1.2.1 From d1fcbae1173f00917f5a71e4c074a61120605021 Mon Sep 17 00:00:00 2001 From: Marcel Ziswiler Date: Sat, 4 Oct 2014 01:46:10 +0200 Subject: usb: tegra: ULPI regression on tegra20 Trying to enumerate USB devices connected via ULPI to T20 failed as follows: USB2: ULPI integrity check failed Git bisecting revealed the following commit being at odds: commit 2d34151f7501ddaa599897f0d89ad576126b03eb usb: tegra: refactor PHY type selection Looking at above commit one quickly identifies a copy paste error which this patch fixes. Happy ULPIing again (;-p). Signed-off-by: Marcel Ziswiler --- drivers/usb/host/ehci-tegra.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 33e5ea9ebd..5f0a98e8b8 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -305,11 +305,11 @@ static void init_phy_mux(struct fdt_usb *config, uint pts, #if defined(CONFIG_TEGRA20) if (config->periph_id == PERIPH_ID_USBD) { clrsetbits_le32(&usbctlr->port_sc1, PTS1_MASK, - PTS_UTMI << PTS1_SHIFT); + pts << PTS1_SHIFT); clrbits_le32(&usbctlr->port_sc1, STS1); } else { clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK, - PTS_UTMI << PTS_SHIFT); + pts << PTS_SHIFT); clrbits_le32(&usbctlr->port_sc1, STS); } #else -- cgit v1.2.1 From 0ae16cbb40a2881f6dfbe00fcb023ee7b548bc5c Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 16 Sep 2014 20:21:42 +0200 Subject: fpga: altera: Clean up the printing and debug Clean up the printf() statements and get rid of the PRINTF() macro by replacing it with debug_cond(). Signed-off-by: Marek Vasut Cc: Chin Liang See Cc: Dinh Nguyen Cc: Albert Aribaud Cc: Tom Rini Cc: Wolfgang Denk Cc: Pavel Machek Acked-by: Pavel Machek --- drivers/fpga/altera.c | 117 +++++++++++++++++++++++++------------------------- 1 file changed, 58 insertions(+), 59 deletions(-) (limited to 'drivers') diff --git a/drivers/fpga/altera.c b/drivers/fpga/altera.c index 6e34a8e56e..ed3f0c882f 100644 --- a/drivers/fpga/altera.c +++ b/drivers/fpga/altera.c @@ -15,14 +15,8 @@ #include #include -/* Define FPGA_DEBUG to get debug printf's */ -/* #define FPGA_DEBUG */ - -#ifdef FPGA_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#endif +/* Define FPGA_DEBUG to 1 to get debug printf's */ +#define FPGA_DEBUG 0 /* Local Static Functions */ static int altera_validate (Altera_desc * desc, const char *fn); @@ -32,36 +26,39 @@ int altera_load(Altera_desc *desc, const void *buf, size_t bsize) { int ret_val = FPGA_FAIL; /* assume a failure */ - if (!altera_validate (desc, (char *)__FUNCTION__)) { - printf ("%s: Invalid device descriptor\n", __FUNCTION__); + if (!altera_validate (desc, (char *)__func__)) { + printf("%s: Invalid device descriptor\n", __func__); } else { switch (desc->family) { case Altera_ACEX1K: case Altera_CYC2: #if defined(CONFIG_FPGA_ACEX1K) - PRINTF ("%s: Launching the ACEX1K Loader...\n", - __FUNCTION__); + debug_cond(FPGA_DEBUG, + "%s: Launching the ACEX1K Loader...\n", + __func__); ret_val = ACEX1K_load (desc, buf, bsize); #elif defined(CONFIG_FPGA_CYCLON2) - PRINTF ("%s: Launching the CYCLONE II Loader...\n", - __FUNCTION__); + debug_cond(FPGA_DEBUG, + "%s: Launching the CYCLONE II Loader...\n", + __func__); ret_val = CYC2_load (desc, buf, bsize); #else - printf ("%s: No support for ACEX1K devices.\n", - __FUNCTION__); + printf("%s: No support for ACEX1K devices.\n", + __func__); #endif break; #if defined(CONFIG_FPGA_STRATIX_II) case Altera_StratixII: - PRINTF ("%s: Launching the Stratix II Loader...\n", - __FUNCTION__); + debug_cond(FPGA_DEBUG, + "%s: Launching the Stratix II Loader...\n", + __func__); ret_val = StratixII_load (desc, buf, bsize); break; #endif default: - printf ("%s: Unsupported family type, %d\n", - __FUNCTION__, desc->family); + printf("%s: Unsupported family type, %d\n", + __func__, desc->family); } } @@ -72,31 +69,33 @@ int altera_dump(Altera_desc *desc, const void *buf, size_t bsize) { int ret_val = FPGA_FAIL; /* assume a failure */ - if (!altera_validate (desc, (char *)__FUNCTION__)) { - printf ("%s: Invalid device descriptor\n", __FUNCTION__); + if (!altera_validate (desc, (char *)__func__)) { + printf("%s: Invalid device descriptor\n", __func__); } else { switch (desc->family) { case Altera_ACEX1K: #if defined(CONFIG_FPGA_ACEX) - PRINTF ("%s: Launching the ACEX1K Reader...\n", - __FUNCTION__); + debug_cond(FPGA_DEBUG, + "%s: Launching the ACEX1K Reader...\n", + __func__); ret_val = ACEX1K_dump (desc, buf, bsize); #else - printf ("%s: No support for ACEX1K devices.\n", - __FUNCTION__); + printf("%s: No support for ACEX1K devices.\n", + __func__); #endif break; #if defined(CONFIG_FPGA_STRATIX_II) case Altera_StratixII: - PRINTF ("%s: Launching the Stratix II Reader...\n", - __FUNCTION__); + debug_cond(FPGA_DEBUG, + "%s: Launching the Stratix II Reader...\n", + __func__); ret_val = StratixII_dump (desc, buf, bsize); break; #endif default: - printf ("%s: Unsupported family type, %d\n", - __FUNCTION__, desc->family); + printf("%s: Unsupported family type, %d\n", + __func__, desc->family); } } @@ -107,42 +106,42 @@ int altera_info( Altera_desc *desc ) { int ret_val = FPGA_FAIL; - if (altera_validate (desc, (char *)__FUNCTION__)) { - printf ("Family: \t"); + if (altera_validate (desc, (char *)__func__)) { + printf("Family: \t"); switch (desc->family) { case Altera_ACEX1K: - printf ("ACEX1K\n"); + printf("ACEX1K\n"); break; case Altera_CYC2: - printf ("CYCLON II\n"); + printf("CYCLON II\n"); break; case Altera_StratixII: - printf ("Stratix II\n"); + printf("Stratix II\n"); break; /* Add new family types here */ default: - printf ("Unknown family type, %d\n", desc->family); + printf("Unknown family type, %d\n", desc->family); } - printf ("Interface type:\t"); + printf("Interface type:\t"); switch (desc->iface) { case passive_serial: - printf ("Passive Serial (PS)\n"); + printf("Passive Serial (PS)\n"); break; case passive_parallel_synchronous: - printf ("Passive Parallel Synchronous (PPS)\n"); + printf("Passive Parallel Synchronous (PPS)\n"); break; case passive_parallel_asynchronous: - printf ("Passive Parallel Asynchronous (PPA)\n"); + printf("Passive Parallel Asynchronous (PPA)\n"); break; case passive_serial_asynchronous: - printf ("Passive Serial Asynchronous (PSA)\n"); + printf("Passive Serial Asynchronous (PSA)\n"); break; case altera_jtag_mode: /* Not used */ - printf ("JTAG Mode\n"); + printf("JTAG Mode\n"); break; case fast_passive_parallel: - printf ("Fast Passive Parallel (FPP)\n"); + printf("Fast Passive Parallel (FPP)\n"); break; case fast_passive_parallel_security: printf @@ -150,31 +149,31 @@ int altera_info( Altera_desc *desc ) break; /* Add new interface types here */ default: - printf ("Unsupported interface type, %d\n", desc->iface); + printf("Unsupported interface type, %d\n", desc->iface); } printf("Device Size: \t%zd bytes\n" - "Cookie: \t0x%x (%d)\n", - desc->size, desc->cookie, desc->cookie); + "Cookie: \t0x%x (%d)\n", + desc->size, desc->cookie, desc->cookie); if (desc->iface_fns) { - printf ("Device Function Table @ 0x%p\n", desc->iface_fns); + printf("Device Function Table @ 0x%p\n", desc->iface_fns); switch (desc->family) { case Altera_ACEX1K: case Altera_CYC2: #if defined(CONFIG_FPGA_ACEX1K) - ACEX1K_info (desc); + ACEX1K_info(desc); #elif defined(CONFIG_FPGA_CYCLON2) - CYC2_info (desc); + CYC2_info(desc); #else /* just in case */ - printf ("%s: No support for ACEX1K devices.\n", - __FUNCTION__); + printf("%s: No support for ACEX1K devices.\n", + __func__); #endif break; #if defined(CONFIG_FPGA_STRATIX_II) case Altera_StratixII: - StratixII_info (desc); + StratixII_info(desc); break; #endif /* Add new family types here */ @@ -183,12 +182,12 @@ int altera_info( Altera_desc *desc ) break; } } else { - printf ("No Device Function Table.\n"); + printf("No Device Function Table.\n"); } ret_val = FPGA_SUCCESS; } else { - printf ("%s: Invalid device descriptor\n", __FUNCTION__); + printf("%s: Invalid device descriptor\n", __func__); } return ret_val; @@ -208,17 +207,17 @@ static int altera_validate (Altera_desc * desc, const char *fn) if (desc->size) { ret_val = true; } else { - printf ("%s: NULL part size\n", fn); + printf("%s: NULL part size\n", fn); } } else { - printf ("%s: Invalid Interface type, %d\n", - fn, desc->iface); + printf("%s: Invalid Interface type, %d\n", + fn, desc->iface); } } else { - printf ("%s: Invalid family type, %d\n", fn, desc->family); + printf("%s: Invalid family type, %d\n", fn, desc->family); } } else { - printf ("%s: NULL descriptor!\n", fn); + printf("%s: NULL descriptor!\n", fn); } return ret_val; -- cgit v1.2.1 From 5561a841487fa246ebc6df17bed8eabfa33f3557 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 16 Sep 2014 20:26:07 +0200 Subject: fpga: altera: Clean up altera_validate function Boldly go, where no programmer has gone before and just clean up the indentation mayhem. No functional change. Signed-off-by: Marek Vasut Cc: Chin Liang See Cc: Dinh Nguyen Cc: Albert Aribaud Cc: Tom Rini Cc: Wolfgang Denk Cc: Pavel Machek --- drivers/fpga/altera.c | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/fpga/altera.c b/drivers/fpga/altera.c index ed3f0c882f..6394afe095 100644 --- a/drivers/fpga/altera.c +++ b/drivers/fpga/altera.c @@ -195,32 +195,31 @@ int altera_info( Altera_desc *desc ) /* ------------------------------------------------------------------------- */ -static int altera_validate (Altera_desc * desc, const char *fn) +static int altera_validate(Altera_desc *desc, const char *fn) { - int ret_val = false; - - if (desc) { - if ((desc->family > min_altera_type) && - (desc->family < max_altera_type)) { - if ((desc->iface > min_altera_iface_type) && - (desc->iface < max_altera_iface_type)) { - if (desc->size) { - ret_val = true; - } else { - printf("%s: NULL part size\n", fn); - } - } else { - printf("%s: Invalid Interface type, %d\n", - fn, desc->iface); - } - } else { - printf("%s: Invalid family type, %d\n", fn, desc->family); - } - } else { + if (!desc) { printf("%s: NULL descriptor!\n", fn); + return false; } - return ret_val; + if ((desc->family < min_altera_type) || + (desc->family > max_altera_type)) { + printf("%s: Invalid family type, %d\n", fn, desc->family); + return false; + } + + if ((desc->iface < min_altera_iface_type) || + (desc->iface > max_altera_iface_type)) { + printf("%s: Invalid Interface type, %d\n", fn, desc->iface); + return false; + } + + if (!desc->size) { + printf("%s: NULL part size\n", fn); + return false; + } + + return true; } /* ------------------------------------------------------------------------- */ -- cgit v1.2.1 From 4a4c0a5e9a2b65711f733bc2178e506131b0693b Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 16 Sep 2014 20:29:24 +0200 Subject: fpga: altera: More indentation trimdown Further improve the indentation in the rest of the file, where the indentation is initially a bit less brutal. There is no functional change in this patch. Signed-off-by: Marek Vasut Cc: Chin Liang See Cc: Dinh Nguyen Cc: Albert Aribaud Cc: Tom Rini Cc: Wolfgang Denk Cc: Pavel Machek Acked-by: Pavel Machek --- drivers/fpga/altera.c | 238 +++++++++++++++++++++++++------------------------- 1 file changed, 120 insertions(+), 118 deletions(-) (limited to 'drivers') diff --git a/drivers/fpga/altera.c b/drivers/fpga/altera.c index 6394afe095..b0f323fbef 100644 --- a/drivers/fpga/altera.c +++ b/drivers/fpga/altera.c @@ -26,40 +26,41 @@ int altera_load(Altera_desc *desc, const void *buf, size_t bsize) { int ret_val = FPGA_FAIL; /* assume a failure */ - if (!altera_validate (desc, (char *)__func__)) { + if (!altera_validate(desc, (char *)__func__)) { printf("%s: Invalid device descriptor\n", __func__); - } else { - switch (desc->family) { - case Altera_ACEX1K: - case Altera_CYC2: + return FPGA_FAIL; + } + + switch (desc->family) { + case Altera_ACEX1K: + case Altera_CYC2: #if defined(CONFIG_FPGA_ACEX1K) - debug_cond(FPGA_DEBUG, - "%s: Launching the ACEX1K Loader...\n", - __func__); - ret_val = ACEX1K_load (desc, buf, bsize); + debug_cond(FPGA_DEBUG, + "%s: Launching the ACEX1K Loader...\n", + __func__); + ret_val = ACEX1K_load (desc, buf, bsize); #elif defined(CONFIG_FPGA_CYCLON2) - debug_cond(FPGA_DEBUG, - "%s: Launching the CYCLONE II Loader...\n", - __func__); - ret_val = CYC2_load (desc, buf, bsize); + debug_cond(FPGA_DEBUG, + "%s: Launching the CYCLONE II Loader...\n", + __func__); + ret_val = CYC2_load (desc, buf, bsize); #else - printf("%s: No support for ACEX1K devices.\n", - __func__); + printf("%s: No support for ACEX1K devices.\n", + __func__); #endif - break; + break; #if defined(CONFIG_FPGA_STRATIX_II) - case Altera_StratixII: - debug_cond(FPGA_DEBUG, - "%s: Launching the Stratix II Loader...\n", - __func__); - ret_val = StratixII_load (desc, buf, bsize); - break; + case Altera_StratixII: + debug_cond(FPGA_DEBUG, + "%s: Launching the Stratix II Loader...\n", + __func__); + ret_val = StratixII_load (desc, buf, bsize); + break; #endif - default: - printf("%s: Unsupported family type, %d\n", - __func__, desc->family); - } + default: + printf("%s: Unsupported family type, %d\n", + __func__, desc->family); } return ret_val; @@ -71,125 +72,126 @@ int altera_dump(Altera_desc *desc, const void *buf, size_t bsize) if (!altera_validate (desc, (char *)__func__)) { printf("%s: Invalid device descriptor\n", __func__); - } else { - switch (desc->family) { - case Altera_ACEX1K: + return FPGA_FAIL; + } + + switch (desc->family) { + case Altera_ACEX1K: #if defined(CONFIG_FPGA_ACEX) - debug_cond(FPGA_DEBUG, - "%s: Launching the ACEX1K Reader...\n", - __func__); - ret_val = ACEX1K_dump (desc, buf, bsize); + debug_cond(FPGA_DEBUG, + "%s: Launching the ACEX1K Reader...\n", + __func__); + ret_val = ACEX1K_dump (desc, buf, bsize); #else - printf("%s: No support for ACEX1K devices.\n", - __func__); + printf("%s: No support for ACEX1K devices.\n", + __func__); #endif - break; + break; #if defined(CONFIG_FPGA_STRATIX_II) - case Altera_StratixII: - debug_cond(FPGA_DEBUG, - "%s: Launching the Stratix II Reader...\n", - __func__); - ret_val = StratixII_dump (desc, buf, bsize); - break; + case Altera_StratixII: + debug_cond(FPGA_DEBUG, + "%s: Launching the Stratix II Reader...\n", + __func__); + ret_val = StratixII_dump (desc, buf, bsize); + break; #endif - default: - printf("%s: Unsupported family type, %d\n", - __func__, desc->family); - } + default: + printf("%s: Unsupported family type, %d\n", + __func__, desc->family); } return ret_val; } -int altera_info( Altera_desc *desc ) +int altera_info(Altera_desc *desc) { int ret_val = FPGA_FAIL; - if (altera_validate (desc, (char *)__func__)) { - printf("Family: \t"); - switch (desc->family) { - case Altera_ACEX1K: - printf("ACEX1K\n"); - break; - case Altera_CYC2: - printf("CYCLON II\n"); - break; - case Altera_StratixII: - printf("Stratix II\n"); - break; - /* Add new family types here */ - default: - printf("Unknown family type, %d\n", desc->family); - } + if (!altera_validate (desc, (char *)__func__)) { + printf("%s: Invalid device descriptor\n", __func__); + return FPGA_FAIL; + } - printf("Interface type:\t"); - switch (desc->iface) { - case passive_serial: - printf("Passive Serial (PS)\n"); - break; - case passive_parallel_synchronous: - printf("Passive Parallel Synchronous (PPS)\n"); - break; - case passive_parallel_asynchronous: - printf("Passive Parallel Asynchronous (PPA)\n"); - break; - case passive_serial_asynchronous: - printf("Passive Serial Asynchronous (PSA)\n"); - break; - case altera_jtag_mode: /* Not used */ - printf("JTAG Mode\n"); - break; - case fast_passive_parallel: - printf("Fast Passive Parallel (FPP)\n"); - break; - case fast_passive_parallel_security: - printf - ("Fast Passive Parallel with Security (FPPS) \n"); - break; - /* Add new interface types here */ - default: - printf("Unsupported interface type, %d\n", desc->iface); - } + printf("Family: \t"); + switch (desc->family) { + case Altera_ACEX1K: + printf("ACEX1K\n"); + break; + case Altera_CYC2: + printf("CYCLON II\n"); + break; + case Altera_StratixII: + printf("Stratix II\n"); + break; + /* Add new family types here */ + default: + printf("Unknown family type, %d\n", desc->family); + } - printf("Device Size: \t%zd bytes\n" - "Cookie: \t0x%x (%d)\n", - desc->size, desc->cookie, desc->cookie); + printf("Interface type:\t"); + switch (desc->iface) { + case passive_serial: + printf("Passive Serial (PS)\n"); + break; + case passive_parallel_synchronous: + printf("Passive Parallel Synchronous (PPS)\n"); + break; + case passive_parallel_asynchronous: + printf("Passive Parallel Asynchronous (PPA)\n"); + break; + case passive_serial_asynchronous: + printf("Passive Serial Asynchronous (PSA)\n"); + break; + case altera_jtag_mode: /* Not used */ + printf("JTAG Mode\n"); + break; + case fast_passive_parallel: + printf("Fast Passive Parallel (FPP)\n"); + break; + case fast_passive_parallel_security: + printf("Fast Passive Parallel with Security (FPPS)\n"); + break; + /* Add new interface types here */ + default: + printf("Unsupported interface type, %d\n", desc->iface); + } + + printf("Device Size: \t%zd bytes\n" + "Cookie: \t0x%x (%d)\n", + desc->size, desc->cookie, desc->cookie); - if (desc->iface_fns) { - printf("Device Function Table @ 0x%p\n", desc->iface_fns); - switch (desc->family) { - case Altera_ACEX1K: - case Altera_CYC2: + if (desc->iface_fns) { + printf("Device Function Table @ 0x%p\n", desc->iface_fns); + switch (desc->family) { + case Altera_ACEX1K: + case Altera_CYC2: #if defined(CONFIG_FPGA_ACEX1K) - ACEX1K_info(desc); + ACEX1K_info(desc); #elif defined(CONFIG_FPGA_CYCLON2) - CYC2_info(desc); + CYC2_info(desc); #else - /* just in case */ - printf("%s: No support for ACEX1K devices.\n", - __func__); + /* just in case */ + printf("%s: No support for ACEX1K devices.\n", + __func__); #endif - break; + break; #if defined(CONFIG_FPGA_STRATIX_II) - case Altera_StratixII: - StratixII_info(desc); - break; + case Altera_StratixII: + StratixII_info(desc); + break; #endif - /* Add new family types here */ - default: - /* we don't need a message here - we give one up above */ - break; - } - } else { - printf("No Device Function Table.\n"); + /* Add new family types here */ + default: + /* we don't need a message here - we give one up above */ + break; } - - ret_val = FPGA_SUCCESS; } else { - printf("%s: Invalid device descriptor\n", __func__); + printf("No Device Function Table.\n"); } + ret_val = FPGA_SUCCESS; + return ret_val; } -- cgit v1.2.1 From 54c96b18a22a6ee5d5a67c057ed5d3812ac16b39 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 16 Sep 2014 20:32:51 +0200 Subject: fpga: altera: Move altera_validate to the top Move the function to the top of the file to avoid forward declaration. No functional change. Signed-off-by: Marek Vasut Cc: Chin Liang See Cc: Dinh Nguyen Cc: Albert Aribaud Cc: Tom Rini Cc: Wolfgang Denk Cc: Pavel Machek Acked-by: Pavel Machek --- drivers/fpga/altera.c | 58 +++++++++++++++++++++++---------------------------- 1 file changed, 26 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/fpga/altera.c b/drivers/fpga/altera.c index b0f323fbef..9e9df505e5 100644 --- a/drivers/fpga/altera.c +++ b/drivers/fpga/altera.c @@ -19,7 +19,32 @@ #define FPGA_DEBUG 0 /* Local Static Functions */ -static int altera_validate (Altera_desc * desc, const char *fn); +static int altera_validate(Altera_desc *desc, const char *fn) +{ + if (!desc) { + printf("%s: NULL descriptor!\n", fn); + return false; + } + + if ((desc->family < min_altera_type) || + (desc->family > max_altera_type)) { + printf("%s: Invalid family type, %d\n", fn, desc->family); + return false; + } + + if ((desc->iface < min_altera_iface_type) || + (desc->iface > max_altera_iface_type)) { + printf("%s: Invalid Interface type, %d\n", fn, desc->iface); + return false; + } + + if (!desc->size) { + printf("%s: NULL part size\n", fn); + return false; + } + + return true; +} /* ------------------------------------------------------------------------- */ int altera_load(Altera_desc *desc, const void *buf, size_t bsize) @@ -194,34 +219,3 @@ int altera_info(Altera_desc *desc) return ret_val; } - -/* ------------------------------------------------------------------------- */ - -static int altera_validate(Altera_desc *desc, const char *fn) -{ - if (!desc) { - printf("%s: NULL descriptor!\n", fn); - return false; - } - - if ((desc->family < min_altera_type) || - (desc->family > max_altera_type)) { - printf("%s: Invalid family type, %d\n", fn, desc->family); - return false; - } - - if ((desc->iface < min_altera_iface_type) || - (desc->iface > max_altera_iface_type)) { - printf("%s: Invalid Interface type, %d\n", fn, desc->iface); - return false; - } - - if (!desc->size) { - printf("%s: NULL part size\n", fn); - return false; - } - - return true; -} - -/* ------------------------------------------------------------------------- */ -- cgit v1.2.1 From fda915a4cf171f4ef3077adbc7bc1680a140b0d6 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 16 Sep 2014 20:33:54 +0200 Subject: fpga: altera: Make altera_validate return normal values Make the function return either 0 or -EINVAL, that is, normal expected error codes and success codes instead of true/false nonsense. Signed-off-by: Marek Vasut Cc: Chin Liang See Cc: Dinh Nguyen Cc: Albert Aribaud Cc: Tom Rini Cc: Wolfgang Denk Cc: Pavel Machek Acked-by: Pavel Machek --- drivers/fpga/altera.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/fpga/altera.c b/drivers/fpga/altera.c index 9e9df505e5..941e7c8933 100644 --- a/drivers/fpga/altera.c +++ b/drivers/fpga/altera.c @@ -12,38 +12,38 @@ * Altera FPGA support */ #include +#include #include #include /* Define FPGA_DEBUG to 1 to get debug printf's */ #define FPGA_DEBUG 0 -/* Local Static Functions */ static int altera_validate(Altera_desc *desc, const char *fn) { if (!desc) { printf("%s: NULL descriptor!\n", fn); - return false; + return -EINVAL; } if ((desc->family < min_altera_type) || (desc->family > max_altera_type)) { printf("%s: Invalid family type, %d\n", fn, desc->family); - return false; + return -EINVAL; } if ((desc->iface < min_altera_iface_type) || (desc->iface > max_altera_iface_type)) { printf("%s: Invalid Interface type, %d\n", fn, desc->iface); - return false; + return -EINVAL; } if (!desc->size) { printf("%s: NULL part size\n", fn); - return false; + return -EINVAL; } - return true; + return 0; } /* ------------------------------------------------------------------------- */ @@ -51,7 +51,7 @@ int altera_load(Altera_desc *desc, const void *buf, size_t bsize) { int ret_val = FPGA_FAIL; /* assume a failure */ - if (!altera_validate(desc, (char *)__func__)) { + if (altera_validate(desc, (char *)__func__)) { printf("%s: Invalid device descriptor\n", __func__); return FPGA_FAIL; } @@ -95,7 +95,7 @@ int altera_dump(Altera_desc *desc, const void *buf, size_t bsize) { int ret_val = FPGA_FAIL; /* assume a failure */ - if (!altera_validate (desc, (char *)__func__)) { + if (altera_validate(desc, (char *)__func__)) { printf("%s: Invalid device descriptor\n", __func__); return FPGA_FAIL; } @@ -133,7 +133,7 @@ int altera_info(Altera_desc *desc) { int ret_val = FPGA_FAIL; - if (!altera_validate (desc, (char *)__func__)) { + if (altera_validate (desc, (char *)__func__)) { printf("%s: Invalid device descriptor\n", __func__); return FPGA_FAIL; } -- cgit v1.2.1 From 2012f238bd4383904e898cfc26c9fd433af835aa Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 16 Sep 2014 21:17:51 +0200 Subject: fpga: altera: Turn the switches into table lookup Add a table of FPGA family with matching functions associated with it and make all the code just look up the family in that table and call the associated function instead of the horrible switch voodoo which was duplicated all over the place. Signed-off-by: Marek Vasut Cc: Chin Liang See Cc: Dinh Nguyen Cc: Albert Aribaud Cc: Tom Rini Cc: Wolfgang Denk Cc: Pavel Machek Acked-by: Pavel Machek --- drivers/fpga/altera.c | 171 ++++++++++++++++++-------------------------------- 1 file changed, 60 insertions(+), 111 deletions(-) (limited to 'drivers') diff --git a/drivers/fpga/altera.c b/drivers/fpga/altera.c index 941e7c8933..fd2b4f0103 100644 --- a/drivers/fpga/altera.c +++ b/drivers/fpga/altera.c @@ -19,6 +19,26 @@ /* Define FPGA_DEBUG to 1 to get debug printf's */ #define FPGA_DEBUG 0 +static const struct altera_fpga { + enum altera_family family; + const char *name; + int (*load)(Altera_desc *, const void *, size_t); + int (*dump)(Altera_desc *, const void *, size_t); + int (*info)(Altera_desc *); +} altera_fpga[] = { +#if defined(CONFIG_FPGA_ACEX1K) + { Altera_ACEX1K, "ACEX1K", ACEX1K_load, ACEX1K_dump, ACEX1K_info }, + { Altera_CYC2, "ACEX1K", ACEX1K_load, ACEX1K_dump, ACEX1K_info }, +#elif defined(CONFIG_FPGA_CYCLON2) + { Altera_ACEX1K, "CycloneII", CYC2_load, CYC2_dump, CYC2_info }, + { Altera_CYC2, "CycloneII", CYC2_load, CYC2_dump, CYC2_info }, +#endif +#if defined(CONFIG_FPGA_STRATIX_II) + { Altera_StratixII, "StratixII", StratixII_load, + StratixII_dump, StratixII_info }, +#endif +}; + static int altera_validate(Altera_desc *desc, const char *fn) { if (!desc) { @@ -46,113 +66,65 @@ static int altera_validate(Altera_desc *desc, const char *fn) return 0; } -/* ------------------------------------------------------------------------- */ -int altera_load(Altera_desc *desc, const void *buf, size_t bsize) +static const struct altera_fpga * +altera_desc_to_fpga(Altera_desc *desc, const char *fn) { - int ret_val = FPGA_FAIL; /* assume a failure */ + int i; - if (altera_validate(desc, (char *)__func__)) { - printf("%s: Invalid device descriptor\n", __func__); - return FPGA_FAIL; + if (altera_validate(desc, fn)) { + printf("%s: Invalid device descriptor\n", fn); + return NULL; } - switch (desc->family) { - case Altera_ACEX1K: - case Altera_CYC2: -#if defined(CONFIG_FPGA_ACEX1K) - debug_cond(FPGA_DEBUG, - "%s: Launching the ACEX1K Loader...\n", - __func__); - ret_val = ACEX1K_load (desc, buf, bsize); -#elif defined(CONFIG_FPGA_CYCLON2) - debug_cond(FPGA_DEBUG, - "%s: Launching the CYCLONE II Loader...\n", - __func__); - ret_val = CYC2_load (desc, buf, bsize); -#else - printf("%s: No support for ACEX1K devices.\n", - __func__); -#endif - break; + for (i = 0; i < ARRAY_SIZE(altera_fpga); i++) { + if (desc->family == altera_fpga[i].family) + break; + } -#if defined(CONFIG_FPGA_STRATIX_II) - case Altera_StratixII: - debug_cond(FPGA_DEBUG, - "%s: Launching the Stratix II Loader...\n", - __func__); - ret_val = StratixII_load (desc, buf, bsize); - break; -#endif - default: - printf("%s: Unsupported family type, %d\n", - __func__, desc->family); + if (i == ARRAY_SIZE(altera_fpga)) { + printf("%s: Unsupported family type, %d\n", fn, desc->family); + return NULL; } - return ret_val; + return &altera_fpga[i]; } -int altera_dump(Altera_desc *desc, const void *buf, size_t bsize) +int altera_load(Altera_desc *desc, const void *buf, size_t bsize) { - int ret_val = FPGA_FAIL; /* assume a failure */ + const struct altera_fpga *fpga = altera_desc_to_fpga(desc, __func__); - if (altera_validate(desc, (char *)__func__)) { - printf("%s: Invalid device descriptor\n", __func__); + if (!fpga) return FPGA_FAIL; - } - switch (desc->family) { - case Altera_ACEX1K: -#if defined(CONFIG_FPGA_ACEX) - debug_cond(FPGA_DEBUG, - "%s: Launching the ACEX1K Reader...\n", - __func__); - ret_val = ACEX1K_dump (desc, buf, bsize); -#else - printf("%s: No support for ACEX1K devices.\n", - __func__); -#endif - break; + debug_cond(FPGA_DEBUG, "%s: Launching the %s Loader...\n", + __func__, fpga->name); + if (fpga->load) + return fpga->load(desc, buf, bsize); + return 0; +} -#if defined(CONFIG_FPGA_STRATIX_II) - case Altera_StratixII: - debug_cond(FPGA_DEBUG, - "%s: Launching the Stratix II Reader...\n", - __func__); - ret_val = StratixII_dump (desc, buf, bsize); - break; -#endif - default: - printf("%s: Unsupported family type, %d\n", - __func__, desc->family); - } +int altera_dump(Altera_desc *desc, const void *buf, size_t bsize) +{ + const struct altera_fpga *fpga = altera_desc_to_fpga(desc, __func__); - return ret_val; + if (!fpga) + return FPGA_FAIL; + + debug_cond(FPGA_DEBUG, "%s: Launching the %s Reader...\n", + __func__, fpga->name); + if (fpga->dump) + return fpga->dump(desc, buf, bsize); + return 0; } int altera_info(Altera_desc *desc) { - int ret_val = FPGA_FAIL; + const struct altera_fpga *fpga = altera_desc_to_fpga(desc, __func__); - if (altera_validate (desc, (char *)__func__)) { - printf("%s: Invalid device descriptor\n", __func__); + if (!fpga) return FPGA_FAIL; - } - printf("Family: \t"); - switch (desc->family) { - case Altera_ACEX1K: - printf("ACEX1K\n"); - break; - case Altera_CYC2: - printf("CYCLON II\n"); - break; - case Altera_StratixII: - printf("Stratix II\n"); - break; - /* Add new family types here */ - default: - printf("Unknown family type, %d\n", desc->family); - } + printf("Family: \t%s\n", fpga->name); printf("Interface type:\t"); switch (desc->iface) { @@ -188,34 +160,11 @@ int altera_info(Altera_desc *desc) if (desc->iface_fns) { printf("Device Function Table @ 0x%p\n", desc->iface_fns); - switch (desc->family) { - case Altera_ACEX1K: - case Altera_CYC2: -#if defined(CONFIG_FPGA_ACEX1K) - ACEX1K_info(desc); -#elif defined(CONFIG_FPGA_CYCLON2) - CYC2_info(desc); -#else - /* just in case */ - printf("%s: No support for ACEX1K devices.\n", - __func__); -#endif - break; -#if defined(CONFIG_FPGA_STRATIX_II) - case Altera_StratixII: - StratixII_info(desc); - break; -#endif - /* Add new family types here */ - default: - /* we don't need a message here - we give one up above */ - break; - } + if (fpga->info) + fpga->info(desc); } else { printf("No Device Function Table.\n"); } - ret_val = FPGA_SUCCESS; - - return ret_val; + return FPGA_SUCCESS; } -- cgit v1.2.1 From f33c9305830d5f8b996a2aaea66591dc93143fe5 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 5 Sep 2014 12:49:48 +0200 Subject: mmc: dw_mmc: cleanups The dw_mmc driver was responding to errors with debug(). Change that to prinf()/puts() respectively so that any errors are immediately obvious. Also adjust english in comments. Signed-off-by: Pavel Machek Signed-off-by: Marek Vasut Cc: Chin Liang See Cc: Dinh Nguyen Cc: Albert Aribaud Cc: Tom Rini Cc: Wolfgang Denk Cc: Pavel Machek Cc: Pantelis Antoniou Acked-by: Chin Liang See --- drivers/mmc/dw_mmc.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 0df30bc045..785eed567c 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -119,7 +119,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, while (dwmci_readl(host, DWMCI_STATUS) & DWMCI_BUSY) { if (get_timer(start) > timeout) { - printf("Timeout on data busy\n"); + printf("%s: Timeout on data busy\n", __func__); return TIMEOUT; } } @@ -177,14 +177,24 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, } } - if (i == retry) + if (i == retry) { + printf("%s: Timeout.\n", __func__); return TIMEOUT; + } if (mask & DWMCI_INTMSK_RTO) { - debug("Response Timeout..\n"); + /* + * Timeout here is not necessarily fatal. (e)MMC cards + * will splat here when they receive CMD55 as they do + * not support this command and that is exactly the way + * to tell them apart from SD cards. Thus, this output + * below shall be debug(). eMMC cards also do not favor + * CMD8, please keep that in mind. + */ + debug("%s: Response Timeout.\n", __func__); return TIMEOUT; } else if (mask & DWMCI_INTMSK_RE) { - debug("Response Error..\n"); + printf("%s: Response Error.\n", __func__); return -1; } @@ -204,7 +214,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, do { mask = dwmci_readl(host, DWMCI_RINTSTS); if (mask & (DWMCI_DATA_ERR | DWMCI_DATA_TOUT)) { - debug("DATA ERROR!\n"); + printf("%s: DATA ERROR!\n", __func__); return -1; } } while (!(mask & DWMCI_INTMSK_DTO)); @@ -232,16 +242,16 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq) if ((freq == host->clock) || (freq == 0)) return 0; /* - * If host->get_mmc_clk didn't define, + * If host->get_mmc_clk isn't defined, * then assume that host->bus_hz is source clock value. - * host->bus_hz should be set from user. + * host->bus_hz should be set by user. */ if (host->get_mmc_clk) sclk = host->get_mmc_clk(host); else if (host->bus_hz) sclk = host->bus_hz; else { - printf("Didn't get source clock value..\n"); + printf("%s: Didn't get source clock value.\n", __func__); return -EINVAL; } @@ -260,7 +270,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq) do { status = dwmci_readl(host, DWMCI_CMD); if (timeout-- < 0) { - printf("TIMEOUT error!!\n"); + printf("%s: Timeout!\n", __func__); return -ETIMEDOUT; } } while (status & DWMCI_CMD_START); @@ -275,7 +285,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq) do { status = dwmci_readl(host, DWMCI_CMD); if (timeout-- < 0) { - printf("TIMEOUT error!!\n"); + printf("%s: Timeout!\n", __func__); return -ETIMEDOUT; } } while (status & DWMCI_CMD_START); @@ -290,7 +300,7 @@ static void dwmci_set_ios(struct mmc *mmc) struct dwmci_host *host = (struct dwmci_host *)mmc->priv; u32 ctype, regs; - debug("Buswidth = %d, clock: %d\n",mmc->bus_width, mmc->clock); + debug("Buswidth = %d, clock: %d\n", mmc->bus_width, mmc->clock); dwmci_setup_bus(host, mmc->clock); switch (mmc->bus_width) { @@ -329,7 +339,7 @@ static int dwmci_init(struct mmc *mmc) dwmci_writel(host, DWMCI_PWREN, 1); if (!dwmci_wait_reset(host, DWMCI_RESET_ALL)) { - debug("%s[%d] Fail-reset!!\n",__func__,__LINE__); + printf("%s[%d] Fail-reset!!\n", __func__, __LINE__); return -1; } -- cgit v1.2.1 From 58ec63d6bcbe392ebed83197c90dc743f3b9e701 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Tue, 9 Sep 2014 14:26:51 +0200 Subject: net: phy: Cleanup drivers/net/phy/micrel.c Old saying says that more than three exclamation marks in a row are sign of mental disease. Cleanup micrel.c. Signed-off-by: Pavel Machek Signed-off-by: Marek Vasut Cc: Chin Liang See Cc: Dinh Nguyen Cc: Albert Aribaud Cc: Tom Rini Cc: Wolfgang Denk Cc: Pavel Machek Cc: Joe Hershberger Acked-by: Chin Liang See --- drivers/net/phy/micrel.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 5d7e3be52e..507b9a368b 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -25,8 +25,7 @@ static struct phy_driver KSZ804_driver = { #ifndef CONFIG_PHY_MICREL_KSZ9021 /* * I can't believe Micrel used the exact same part number - * for the KSZ9021 - * Shame Micrel, Shame!!!!! + * for the KSZ9021. Shame Micrel, Shame! */ static struct phy_driver KS8721_driver = { .name = "Micrel KS8721BL", @@ -40,7 +39,7 @@ static struct phy_driver KS8721_driver = { #endif -/** +/* * KSZ9021 - KSZ9031 common */ @@ -69,8 +68,8 @@ static int ksz90xx_startup(struct phy_device *phydev) phydev->speed = SPEED_10; return 0; } -#ifdef CONFIG_PHY_MICREL_KSZ9021 +#ifdef CONFIG_PHY_MICREL_KSZ9021 /* * KSZ9021 */ -- cgit v1.2.1 From 4f68678b1941af7d75f391d1189c776fb434dc08 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 15 Sep 2014 00:50:37 +0200 Subject: net: dwc: Fix cache alignment issues Fix remaining cache alignment issues in the DWC Ethernet driver. Please note that the cache handling in the driver is making the code hideous and thus the next patch cleans that up. In order to make this change reviewable though, the cleanup is split from it. Signed-off-by: Marek Vasut Cc: Chin Liang See Cc: Dinh Nguyen Cc: Albert Aribaud Cc: Tom Rini Cc: Wolfgang Denk Cc: Pavel Machek Cc: Joe Hershberger Acked-by: Pavel Machek --- drivers/net/designware.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/designware.c b/drivers/net/designware.c index 7186e3b491..aaf146d444 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -303,7 +303,8 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length) /* Flush data to be sent */ flush_dcache_range((unsigned long)desc_p->dmamac_addr, - (unsigned long)desc_p->dmamac_addr + length); + (unsigned long)desc_p->dmamac_addr + + roundup(length, ARCH_DMA_MINALIGN)); #if defined(CONFIG_DW_ALTDESCRIPTOR) desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST; @@ -372,7 +373,8 @@ static int dw_eth_recv(struct eth_device *dev) /* Flush only status field - others weren't changed */ flush_dcache_range((unsigned long)&desc_p->txrx_status, (unsigned long)&desc_p->txrx_status + - sizeof(desc_p->txrx_status)); + roundup(sizeof(desc_p->txrx_status), + ARCH_DMA_MINALIGN)); /* Test the wrap-around condition. */ if (++desc_num >= CONFIG_RX_DESCR_NUM) -- cgit v1.2.1 From 96cec17d3cd22ca2251d6f7946409933a231ce6f Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 15 Sep 2014 01:05:23 +0200 Subject: net: dwc: Make the cache handling less cryptic Add a few new variables to make the cache handling less cryptic. Add a variable for DMA and DATA descriptor start and end, so the correctness of the code is easier to inspect. Signed-off-by: Marek Vasut Cc: Chin Liang See Cc: Dinh Nguyen Cc: Albert Aribaud Cc: Tom Rini Cc: Wolfgang Denk Cc: Pavel Machek Cc: Joe Hershberger Acked-by: Pavel Machek Acked-by: Chin Liang See --- drivers/net/designware.c | 48 +++++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/designware.c b/drivers/net/designware.c index aaf146d444..9ded8950b8 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -279,19 +279,21 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length) struct eth_dma_regs *dma_p = priv->dma_regs_p; u32 desc_num = priv->tx_currdescnum; struct dmamacdescr *desc_p = &priv->tx_mac_descrtable[desc_num]; - + uint32_t desc_start = (uint32_t)desc_p; + uint32_t desc_end = desc_start + + roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN); + uint32_t data_start = (uint32_t)desc_p->dmamac_addr; + uint32_t data_end = data_start + + roundup(length, ARCH_DMA_MINALIGN); /* * Strictly we only need to invalidate the "txrx_status" field * for the following check, but on some platforms we cannot - * invalidate only 4 bytes, so roundup to - * ARCH_DMA_MINALIGN. This is safe because the individual - * descriptors in the array are each aligned to - * ARCH_DMA_MINALIGN. + * invalidate only 4 bytes, so we flush the entire descriptor, + * which is 16 bytes in total. This is safe because the + * individual descriptors in the array are each aligned to + * ARCH_DMA_MINALIGN and padded appropriately. */ - invalidate_dcache_range( - (unsigned long)desc_p, - (unsigned long)desc_p + - roundup(sizeof(desc_p->txrx_status), ARCH_DMA_MINALIGN)); + invalidate_dcache_range(desc_start, desc_end); /* Check if the descriptor is owned by CPU */ if (desc_p->txrx_status & DESC_TXSTS_OWNBYDMA) { @@ -299,12 +301,10 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length) return -1; } - memcpy((void *)desc_p->dmamac_addr, packet, length); + memcpy(desc_p->dmamac_addr, packet, length); /* Flush data to be sent */ - flush_dcache_range((unsigned long)desc_p->dmamac_addr, - (unsigned long)desc_p->dmamac_addr + - roundup(length, ARCH_DMA_MINALIGN)); + flush_dcache_range(data_start, data_end); #if defined(CONFIG_DW_ALTDESCRIPTOR) desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST; @@ -322,8 +322,7 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length) #endif /* Flush modified buffer descriptor */ - flush_dcache_range((unsigned long)desc_p, - (unsigned long)desc_p + sizeof(struct dmamacdescr)); + flush_dcache_range(desc_start, desc_end); /* Test the wrap-around condition. */ if (++desc_num >= CONFIG_TX_DESCR_NUM) @@ -343,11 +342,14 @@ static int dw_eth_recv(struct eth_device *dev) u32 status, desc_num = priv->rx_currdescnum; struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num]; int length = 0; + uint32_t desc_start = (uint32_t)desc_p; + uint32_t desc_end = desc_start + + roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN); + uint32_t data_start = (uint32_t)desc_p->dmamac_addr; + uint32_t data_end; /* Invalidate entire buffer descriptor */ - invalidate_dcache_range((unsigned long)desc_p, - (unsigned long)desc_p + - sizeof(struct dmamacdescr)); + invalidate_dcache_range(desc_start, desc_end); status = desc_p->txrx_status; @@ -358,9 +360,8 @@ static int dw_eth_recv(struct eth_device *dev) DESC_RXSTS_FRMLENSHFT; /* Invalidate received data */ - invalidate_dcache_range((unsigned long)desc_p->dmamac_addr, - (unsigned long)desc_p->dmamac_addr + - roundup(length, ARCH_DMA_MINALIGN)); + data_end = data_start + roundup(length, ARCH_DMA_MINALIGN); + invalidate_dcache_range(data_start, data_end); NetReceive(desc_p->dmamac_addr, length); @@ -371,10 +372,7 @@ static int dw_eth_recv(struct eth_device *dev) desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA; /* Flush only status field - others weren't changed */ - flush_dcache_range((unsigned long)&desc_p->txrx_status, - (unsigned long)&desc_p->txrx_status + - roundup(sizeof(desc_p->txrx_status), - ARCH_DMA_MINALIGN)); + flush_dcache_range(desc_start, desc_end); /* Test the wrap-around condition. */ if (++desc_num >= CONFIG_RX_DESCR_NUM) -- cgit v1.2.1 From 498d1a62db4374c9d6223771bcbe8ae612a0f59f Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Mon, 8 Sep 2014 14:08:45 +0200 Subject: arm: socfpga: mmc: Pick the clock from clock manager Make the SoCFPGA MMC stub pick clock via the clock manager frequency accessors instead of hard-coding the frequency. Also fix calloc() misuse. Signed-off-by: Pavel Machek Signed-off-by: Marek Vasut Cc: Chin Liang See Cc: Dinh Nguyen Cc: Albert Aribaud Cc: Tom Rini Cc: Wolfgang Denk Cc: Pavel Machek Acked-by: Dinh Nguyen --- drivers/mmc/socfpga_dw_mmc.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/socfpga_dw_mmc.c b/drivers/mmc/socfpga_dw_mmc.c index 1f96382dea..eb69aed9df 100644 --- a/drivers/mmc/socfpga_dw_mmc.c +++ b/drivers/mmc/socfpga_dw_mmc.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -44,12 +45,18 @@ static void socfpga_dwmci_clksel(struct dwmci_host *host) int socfpga_dwmmc_init(u32 regbase, int bus_width, int index) { struct dwmci_host *host; + unsigned long clk = cm_get_mmc_controller_clk_hz(); + + if (clk == 0) { + printf("%s: MMC clock is zero!", __func__); + return -EINVAL; + } /* calloc for zero init */ - host = calloc(sizeof(struct dwmci_host), 1); + host = calloc(1, sizeof(struct dwmci_host)); if (!host) { - printf("dwmci_host calloc fail!\n"); - return -1; + printf("%s: calloc() failed!\n", __func__); + return -ENOMEM; } host->name = "SOCFPGA DWMMC"; @@ -58,7 +65,7 @@ int socfpga_dwmmc_init(u32 regbase, int bus_width, int index) 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->bus_hz = clk; host->fifoth_val = MSIZE(0x2) | RX_WMARK(CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH / 2 - 1) | TX_WMARK(CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH / 2); -- cgit v1.2.1 From 230fe9b202ff0ca396ad9a564816cc87d42daa6e Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Mon, 8 Sep 2014 14:08:45 +0200 Subject: arm: socfpga: fpga: Add SoCFPGA FPGA programming interface Add code necessary to program the FPGA part of SoCFPGA from U-Boot with an RBF blob. This patch also integrates the code into the FPGA driver framework in U-Boot so it can be used via the 'fpga' command. Signed-off-by: Pavel Machek Signed-off-by: Marek Vasut Cc: Chin Liang See Cc: Dinh Nguyen Cc: Albert Aribaud Cc: Tom Rini Cc: Wolfgang Denk Cc: Pavel Machek V2: Move the not-CPU specific stuff into drivers/fpga/ and base this on the cleaned up altera FPGA support. --- drivers/fpga/Makefile | 1 + drivers/fpga/altera.c | 3 + drivers/fpga/socfpga.c | 301 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 305 insertions(+) create mode 100644 drivers/fpga/socfpga.c (limited to 'drivers') diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile index dfb2e7fc76..6aa24d4359 100644 --- a/drivers/fpga/Makefile +++ b/drivers/fpga/Makefile @@ -17,4 +17,5 @@ obj-y += altera.o obj-$(CONFIG_FPGA_ACEX1K) += ACEX1K.o obj-$(CONFIG_FPGA_CYCLON2) += cyclon2.o obj-$(CONFIG_FPGA_STRATIX_II) += stratixII.o +obj-$(CONFIG_FPGA_SOCFPGA) += socfpga.o endif diff --git a/drivers/fpga/altera.c b/drivers/fpga/altera.c index fd2b4f0103..a5bfe5dce1 100644 --- a/drivers/fpga/altera.c +++ b/drivers/fpga/altera.c @@ -37,6 +37,9 @@ static const struct altera_fpga { { Altera_StratixII, "StratixII", StratixII_load, StratixII_dump, StratixII_info }, #endif +#if defined(CONFIG_FPGA_SOCFPGA) + { Altera_SoCFPGA, "SoC FPGA", socfpga_load, NULL, NULL }, +#endif }; static int altera_validate(Altera_desc *desc, const char *fn) diff --git a/drivers/fpga/socfpga.c b/drivers/fpga/socfpga.c new file mode 100644 index 0000000000..63b3566e3e --- /dev/null +++ b/drivers/fpga/socfpga.c @@ -0,0 +1,301 @@ +/* + * Copyright (C) 2012 Altera Corporation + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +/* Timeout count */ +#define FPGA_TIMEOUT_CNT 0x1000000 + +static struct socfpga_fpga_manager *fpgamgr_regs = + (struct socfpga_fpga_manager *)SOCFPGA_FPGAMGRREGS_ADDRESS; +static struct socfpga_system_manager *sysmgr_regs = + (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; + +/* Set CD ratio */ +static void fpgamgr_set_cd_ratio(unsigned long ratio) +{ + clrsetbits_le32(&fpgamgr_regs->ctrl, + 0x3 << FPGAMGRREGS_CTRL_CDRATIO_LSB, + (ratio & 0x3) << FPGAMGRREGS_CTRL_CDRATIO_LSB); +} + +static int fpgamgr_dclkcnt_set(unsigned long cnt) +{ + unsigned long i; + + /* Clear any existing done status */ + if (readl(&fpgamgr_regs->dclkstat)) + writel(0x1, &fpgamgr_regs->dclkstat); + + /* Write the dclkcnt */ + writel(cnt, &fpgamgr_regs->dclkcnt); + + /* Wait till the dclkcnt done */ + for (i = 0; i < FPGA_TIMEOUT_CNT; i++) { + if (!readl(&fpgamgr_regs->dclkstat)) + continue; + + writel(0x1, &fpgamgr_regs->dclkstat); + return 0; + } + + return -ETIMEDOUT; +} + +/* Start the FPGA programming by initialize the FPGA Manager */ +static int fpgamgr_program_init(void) +{ + unsigned long msel, i; + + /* Get the MSEL value */ + msel = readl(&fpgamgr_regs->stat); + msel &= FPGAMGRREGS_STAT_MSEL_MASK; + msel >>= FPGAMGRREGS_STAT_MSEL_LSB; + + /* + * Set the cfg width + * If MSEL[3] = 1, cfg width = 32 bit + */ + if (msel & 0x8) { + setbits_le32(&fpgamgr_regs->ctrl, + FPGAMGRREGS_CTRL_CFGWDTH_MASK); + + /* To determine the CD ratio */ + /* MSEL[1:0] = 0, CD Ratio = 1 */ + if ((msel & 0x3) == 0x0) + fpgamgr_set_cd_ratio(CDRATIO_x1); + /* MSEL[1:0] = 1, CD Ratio = 4 */ + else if ((msel & 0x3) == 0x1) + fpgamgr_set_cd_ratio(CDRATIO_x4); + /* MSEL[1:0] = 2, CD Ratio = 8 */ + else if ((msel & 0x3) == 0x2) + fpgamgr_set_cd_ratio(CDRATIO_x8); + + } else { /* MSEL[3] = 0 */ + clrbits_le32(&fpgamgr_regs->ctrl, + FPGAMGRREGS_CTRL_CFGWDTH_MASK); + + /* To determine the CD ratio */ + /* MSEL[1:0] = 0, CD Ratio = 1 */ + if ((msel & 0x3) == 0x0) + fpgamgr_set_cd_ratio(CDRATIO_x1); + /* MSEL[1:0] = 1, CD Ratio = 2 */ + else if ((msel & 0x3) == 0x1) + fpgamgr_set_cd_ratio(CDRATIO_x2); + /* MSEL[1:0] = 2, CD Ratio = 4 */ + else if ((msel & 0x3) == 0x2) + fpgamgr_set_cd_ratio(CDRATIO_x4); + } + + /* To enable FPGA Manager configuration */ + clrbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_NCE_MASK); + + /* To enable FPGA Manager drive over configuration line */ + setbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_EN_MASK); + + /* Put FPGA into reset phase */ + setbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_NCONFIGPULL_MASK); + + /* (1) wait until FPGA enter reset phase */ + for (i = 0; i < FPGA_TIMEOUT_CNT; i++) { + if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_RESETPHASE) + break; + } + + /* If not in reset state, return error */ + if (fpgamgr_get_mode() != FPGAMGRREGS_MODE_RESETPHASE) { + puts("FPGA: Could not reset\n"); + return -1; + } + + /* Release FPGA from reset phase */ + clrbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_NCONFIGPULL_MASK); + + /* (2) wait until FPGA enter configuration phase */ + for (i = 0; i < FPGA_TIMEOUT_CNT; i++) { + if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_CFGPHASE) + break; + } + + /* If not in configuration state, return error */ + if (fpgamgr_get_mode() != FPGAMGRREGS_MODE_CFGPHASE) { + puts("FPGA: Could not configure\n"); + return -2; + } + + /* Clear all interrupts in CB Monitor */ + writel(0xFFF, &fpgamgr_regs->gpio_porta_eoi); + + /* Enable AXI configuration */ + setbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_AXICFGEN_MASK); + + return 0; +} + +/* Write the RBF data to FPGA Manager */ +static void fpgamgr_program_write(const void *rbf_data, unsigned long rbf_size) +{ + uint32_t src = (uint32_t)rbf_data; + uint32_t dst = SOCFPGA_FPGAMGRDATA_ADDRESS; + + /* Number of loops for 32-byte long copying. */ + uint32_t loops32 = rbf_size / 32; + /* Number of loops for 4-byte long copying + trailing bytes */ + uint32_t loops4 = DIV_ROUND_UP(rbf_size % 32, 4); + + asm volatile( + "1: ldmia %0!, {r0-r7}\n" + " stmia %1!, {r0-r7}\n" + " sub %1, #32\n" + " subs %2, #1\n" + " bne 1b\n" + "2: ldr %2, [%0], #4\n" + " str %2, [%1]\n" + " subs %3, #1\n" + " bne 2b\n" + : "+r"(src), "+r"(dst), "+r"(loops32), "+r"(loops4) : + : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "cc"); +} + +/* Ensure the FPGA entering config done */ +static int fpgamgr_program_poll_cd(void) +{ + const uint32_t mask = FPGAMGRREGS_MON_GPIO_EXT_PORTA_NS_MASK | + FPGAMGRREGS_MON_GPIO_EXT_PORTA_CD_MASK; + unsigned long reg, i; + + /* (3) wait until full config done */ + for (i = 0; i < FPGA_TIMEOUT_CNT; i++) { + reg = readl(&fpgamgr_regs->gpio_ext_porta); + + /* Config error */ + if (!(reg & mask)) { + printf("FPGA: Configuration error.\n"); + return -3; + } + + /* Config done without error */ + if (reg & mask) + break; + } + + /* Timeout happened, return error */ + if (i == FPGA_TIMEOUT_CNT) { + printf("FPGA: Timeout waiting for program.\n"); + return -4; + } + + /* Disable AXI configuration */ + clrbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_AXICFGEN_MASK); + + return 0; +} + +/* Ensure the FPGA entering init phase */ +static int fpgamgr_program_poll_initphase(void) +{ + unsigned long i; + + /* Additional clocks for the CB to enter initialization phase */ + if (fpgamgr_dclkcnt_set(0x4)) + return -5; + + /* (4) wait until FPGA enter init phase or user mode */ + for (i = 0; i < FPGA_TIMEOUT_CNT; i++) { + if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_INITPHASE) + break; + if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_USERMODE) + break; + } + + /* If not in configuration state, return error */ + if (i == FPGA_TIMEOUT_CNT) + return -6; + + return 0; +} + +/* Ensure the FPGA entering user mode */ +static int fpgamgr_program_poll_usermode(void) +{ + unsigned long i; + + /* Additional clocks for the CB to exit initialization phase */ + if (fpgamgr_dclkcnt_set(0x5000)) + return -7; + + /* (5) wait until FPGA enter user mode */ + for (i = 0; i < FPGA_TIMEOUT_CNT; i++) { + if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_USERMODE) + break; + } + /* If not in configuration state, return error */ + if (i == FPGA_TIMEOUT_CNT) + return -8; + + /* To release FPGA Manager drive over configuration line */ + clrbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_EN_MASK); + + return 0; +} + +/* + * FPGA Manager to program the FPGA. This is the interface used by FPGA driver. + * Return 0 for sucess, non-zero for error. + */ +int socfpga_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size) +{ + unsigned long status; + + if ((uint32_t)rbf_data & 0x3) { + puts("FPGA: Unaligned data, realign to 32bit boundary.\n"); + return -EINVAL; + } + + /* Prior programming the FPGA, all bridges need to be shut off */ + + /* Disable all signals from hps peripheral controller to fpga */ + writel(0, &sysmgr_regs->fpgaintfgrp_module); + + /* Disable all signals from FPGA to HPS SDRAM */ +#define SDR_CTRLGRP_FPGAPORTRST_ADDRESS 0x5080 + writel(0, SOCFPGA_SDR_ADDRESS + SDR_CTRLGRP_FPGAPORTRST_ADDRESS); + + /* Disable all axi bridge (hps2fpga, lwhps2fpga & fpga2hps) */ + socfpga_bridges_reset(1); + + /* Unmap the bridges from NIC-301 */ + writel(0x1, SOCFPGA_L3REGS_ADDRESS); + + /* Initialize the FPGA Manager */ + status = fpgamgr_program_init(); + if (status) + return status; + + /* Write the RBF data to FPGA Manager */ + fpgamgr_program_write(rbf_data, rbf_size); + + /* Ensure the FPGA entering config done */ + status = fpgamgr_program_poll_cd(); + if (status) + return status; + + /* Ensure the FPGA entering init phase */ + status = fpgamgr_program_poll_initphase(); + if (status) + return status; + + /* Ensure the FPGA entering user mode */ + return fpgamgr_program_poll_usermode(); +} -- cgit v1.2.1 From 16b61d13bab361853564da401b15fc34ae1dfea7 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Tue, 22 Jul 2014 12:47:02 +0200 Subject: usb: musb-new: core: set MUSB_POWER_HSENAB in MUSB_POWER for host mode This bit allows the MUSB controller to negotiate for high-speed mode when the device is reset by the hub. If unset, Babble errors occur with high-speed mass storage devices right after the first packet. This condition is not caught by the interrupt handles in U-Boot, so no recovery is done, and the USB communication is stuck. To fix this, set the bit unconditionally, not only for CONFIG_USB_GADGET_DUALSPEED but also for host-only modes. Signed-off-by: Daniel Mack --- drivers/usb/musb-new/musb_core.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb-new/musb_core.c b/drivers/usb/musb-new/musb_core.c index 4edd6d729d..242cc30b1c 100644 --- a/drivers/usb/musb-new/musb_core.c +++ b/drivers/usb/musb-new/musb_core.c @@ -942,9 +942,7 @@ void musb_start(struct musb *musb) /* put into basic highspeed mode and start session */ musb_writeb(regs, MUSB_POWER, MUSB_POWER_ISOUPDATE -#ifdef CONFIG_USB_GADGET_DUALSPEED | MUSB_POWER_HSENAB -#endif /* ENSUSPEND wedges tusb */ /* | MUSB_POWER_ENSUSPEND */ ); -- cgit v1.2.1 From e2140588dd2f3e619f21d9575281b7c7ea771c09 Mon Sep 17 00:00:00 2001 From: Eric Nelson Date: Wed, 1 Oct 2014 14:30:56 -0700 Subject: usb: gadget: fastboot: terminate commands with NULL Without NULL termination, various commands will read past the end of input. In particular, this was noticed with error() calls in cb_getvar and simple_strtoul() in cb_download. Since the download callback happens elsewhere, the 4k buffer should always be sufficient to handle command arguments. Signed-off-by: Eric Nelson --- drivers/usb/gadget/f_fastboot.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c index 392379dce4..71b62e5005 100644 --- a/drivers/usb/gadget/f_fastboot.c +++ b/drivers/usb/gadget/f_fastboot.c @@ -546,7 +546,14 @@ static void rx_handler_command(struct usb_ep *ep, struct usb_request *req) error("unknown command: %s\n", cmdbuf); fastboot_tx_write_str("FAILunknown command"); } else { - func_cb(ep, req); + if (req->actual < req->length) { + u8 *buf = (u8 *)req->buf; + buf[req->actual] = 0; + func_cb(ep, req); + } else { + error("buffer overflow\n"); + fastboot_tx_write_str("FAILbuffer overflow"); + } } if (req->status == 0) { -- cgit v1.2.1 From 05968e7cfd5dcc50cfe51d03d119a5e9d77bd07c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 3 Oct 2014 20:03:03 +0900 Subject: mtd: denali: fix NAND_CMD_PARAM command NAND_CMD_PARAM (0xEC) command is not working on the Denali NAND controller driver. Unlike NAND_CMD_READID (0x90), when the NAND_CMD_PARAM command is followed by an address cycle, the target device goes busy. (R/B# is deasserted) Wait until the parameter data are ready. In addition, unnecessary clear_interrupts() should be removed. Signed-off-by: Masahiro Yamada Acked-by: Chin Liang See --- drivers/mtd/nand/denali.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index ba3de1a635..d9abc7e1d6 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c @@ -1059,9 +1059,8 @@ static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col, addr = MODE_11 | BANK(denali->flash_bank); index_addr(denali, addr | 0, cmd); break; - case NAND_CMD_PARAM: - clear_interrupts(denali); case NAND_CMD_READID: + case NAND_CMD_PARAM: reset_buf(denali); /* sometimes ManufactureId read from register is not right * e.g. some of Micron MT29F32G08QAA MLC NAND chips @@ -1070,6 +1069,8 @@ static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col, addr = MODE_11 | BANK(denali->flash_bank); index_addr(denali, addr | 0, cmd); index_addr(denali, addr | 1, col & 0xFF); + if (cmd == NAND_CMD_PARAM) + udelay(50); break; case NAND_CMD_READ0: case NAND_CMD_SEQIN: -- cgit v1.2.1 From ed3c980bee74dc1bd599dd44b41b2c32ee78c0a8 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 3 Oct 2014 20:03:04 +0900 Subject: mtd: denali: support NAND_CMD_RNDOUT command The function nand_flash_detect_ext_param_page() requires NAND_CMD_RNDOUT command supported. It is necessary to detect some types of ONFi-compliant devices. Without it, the error message "unsupported command received 0x5" is shown. Let's support this command on the Denali NAND controller driver. Signed-off-by: Masahiro Yamada Acked-by: Chin Liang See --- drivers/mtd/nand/denali.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index d9abc7e1d6..308b7845f1 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c @@ -1072,6 +1072,13 @@ static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col, if (cmd == NAND_CMD_PARAM) udelay(50); break; + case NAND_CMD_RNDOUT: + addr = MODE_11 | BANK(denali->flash_bank); + index_addr(denali, addr | 0, cmd); + index_addr(denali, addr | 1, col & 0xFF); + index_addr(denali, addr | 1, col >> 8); + index_addr(denali, addr | 0, NAND_CMD_RNDOUTSTART); + break; case NAND_CMD_READ0: case NAND_CMD_SEQIN: denali->page = page; -- cgit v1.2.1 From 02590aa31cc282cffafac559032981094f716fa9 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 23 Sep 2014 18:07:01 +0300 Subject: ahci: Don't start command DMA engine before buffers are set The DMA/FIS buffers are set in ahci_port_start() which is called after ahci_host_init(). So don't start the DMA engine here (i.e. don't set FIS_RX) This fixes the following error at kernel boot on OMAP platforms (e.g. DRA7x) WARNING: CPU: 0 PID: 0 at drivers/bus/omap_l3_noc.c:147 l3_interrupt_handler+0x260/0x358() 44000000.ocp:L3 Custom Error: MASTER SATA TARGET GPMC (Idle): Data Access in User mode during Functional access Signed-off-by: Roger Quadros --- drivers/block/ahci.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c index dce99adc6b..a93a8e1c04 100644 --- a/drivers/block/ahci.c +++ b/drivers/block/ahci.c @@ -229,7 +229,6 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent) * already be on in the command register. */ cmd = readl(port_mmio + PORT_CMD); - cmd |= PORT_CMD_FIS_RX; cmd |= PORT_CMD_SPIN_UP; writel_with_flush(cmd, port_mmio + PORT_CMD); -- cgit v1.2.1