diff options
author | Tom Rini <trini@konsulko.com> | 2020-06-19 16:25:50 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2020-06-19 16:25:50 -0400 |
commit | 5575f79bdaa824a90747d5a3d063b5219521b066 (patch) | |
tree | 6f25a65e9044c48192caa224936207fe1e510e81 /drivers | |
parent | 04909251fdecac9d05e527b83e86e043e8df00ea (diff) | |
parent | 2a2b94a9d9a3139853c6ccd911c55db77b714a68 (diff) |
Merge https://gitlab.denx.de/u-boot/custodians/u-boot-spi into next
- Convert fsl_espi to driver model (Chuanhua)
- Enable am335x baltos to DM_SPI (Jagan)
- Drop few powerpc board which doesn't have DM enabled (Jagan)
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/Kconfig | 15 | ||||
-rw-r--r-- | drivers/mmc/ca_dw_mmc.c | 34 | ||||
-rw-r--r-- | drivers/mmc/fsl_esdhc.c | 47 | ||||
-rw-r--r-- | drivers/mmc/fsl_esdhc_imx.c | 6 | ||||
-rw-r--r-- | drivers/power/regulator/regulator-uclass.c | 3 | ||||
-rw-r--r-- | drivers/power/regulator/regulator_common.c | 2 | ||||
-rw-r--r-- | drivers/spi/Kconfig | 37 | ||||
-rw-r--r-- | drivers/spi/Makefile | 1 | ||||
-rw-r--r-- | drivers/spi/atmel_spi.c | 286 | ||||
-rw-r--r-- | drivers/spi/atmel_spi.h | 15 | ||||
-rw-r--r-- | drivers/spi/davinci_spi.c | 157 | ||||
-rw-r--r-- | drivers/spi/fsl_dspi.c | 132 | ||||
-rw-r--r-- | drivers/spi/fsl_espi.c | 444 | ||||
-rw-r--r-- | drivers/spi/mxs_spi.c | 158 | ||||
-rw-r--r-- | drivers/spi/soft_spi_legacy.c | 168 | ||||
-rw-r--r-- | drivers/usb/eth/r8152.h | 8 | ||||
-rw-r--r-- | drivers/usb/eth/r8152_fw.c | 481 |
17 files changed, 779 insertions, 1215 deletions
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 3c4f057373..8f56572c39 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -727,6 +727,21 @@ config FSL_ESDHC This selects support for the eSDHC (Enhanced Secure Digital Host Controller) found on numerous Freescale/NXP SoCs. +config FSL_ESDHC_33V_IO_RELIABILITY_WORKAROUND + bool "enable eSDHC workaround for 3.3v IO reliability issue" + depends on FSL_ESDHC && DM_MMC + default n + help + When eSDHC operates at 3.3v, damage can accumulate in an internal + level shifter at a higher than expected rate. The faster the interface + runs, the more damage accumulates. This issue now is found on LX2160A + eSDHC1 for only SD card. The hardware workaround is recommended to use + an on-board level shifter that is 1.8v on SoC side and 3.3v on SD card + side. For boards without hardware workaround, this option could be + enabled, ensuring 1.8v IO voltage and disabling eSDHC if no card. + This option assumes no hotplug, and u-boot has to make all the way to + to linux to use 1.8v UHS-I speed mode if has card. + config FSL_ESDHC_IMX bool "Freescale/NXP i.MX eSDHC controller support" help diff --git a/drivers/mmc/ca_dw_mmc.c b/drivers/mmc/ca_dw_mmc.c index acbc850fcb..198c41f451 100644 --- a/drivers/mmc/ca_dw_mmc.c +++ b/drivers/mmc/ca_dw_mmc.c @@ -19,6 +19,7 @@ #define SD_CLK_SEL_200MHZ (0x2) #define SD_CLK_SEL_100MHZ (0x1) +#define SD_CLK_SEL_50MHZ (0x0) #define IO_DRV_SD_DS_OFFSET (16) #define IO_DRV_SD_DS_MASK (0xff << IO_DRV_SD_DS_OFFSET) @@ -44,15 +45,11 @@ static void ca_dwmci_clksel(struct dwmci_host *host) struct ca_dwmmc_priv_data *priv = host->priv; u32 val = readl(priv->sd_dll_reg); - if (host->bus_hz >= 200000000) { - val &= ~SD_CLK_SEL_MASK; + val &= ~SD_CLK_SEL_MASK; + if (host->bus_hz >= 200000000) val |= SD_CLK_SEL_200MHZ; - } else if (host->bus_hz >= 100000000) { - val &= ~SD_CLK_SEL_MASK; + else if (host->bus_hz >= 100000000) val |= SD_CLK_SEL_100MHZ; - } else { - val &= ~SD_CLK_SEL_MASK; - } writel(val, priv->sd_dll_reg); } @@ -77,14 +74,14 @@ unsigned int ca_dwmci_get_mmc_clock(struct dwmci_host *host, uint freq) u8 clk_div; switch (sd_clk_sel) { - case 2: - clk_div = 1; + case SD_CLK_SEL_50MHZ: + clk_div = 4; break; - case 1: + case SD_CLK_SEL_100MHZ: clk_div = 2; break; default: - clk_div = 4; + clk_div = 1; } return SD_SCLK_MAX / clk_div / (host->div + 1); @@ -100,9 +97,6 @@ static int ca_dwmmc_ofdata_to_platdata(struct udevice *dev) host->dev_index = 0; host->buswidth = dev_read_u32_default(dev, "bus-width", 1); - if (host->buswidth != 1 && host->buswidth != 4) - return -EINVAL; - host->bus_hz = dev_read_u32_default(dev, "max-frequency", 50000000); priv->ds = dev_read_u32_default(dev, "io_ds", 0x33); host->fifo_mode = dev_read_bool(dev, "fifo-mode"); @@ -118,10 +112,8 @@ static int ca_dwmmc_ofdata_to_platdata(struct udevice *dev) return -EINVAL; host->ioaddr = dev_read_addr_ptr(dev); - if (host->ioaddr == (void *)FDT_ADDR_T_NONE) { - printf("DWMMC: base address is invalid\n"); + if (!host->ioaddr) return -EINVAL; - } host->priv = priv; @@ -140,10 +132,8 @@ static int ca_dwmmc_probe(struct udevice *dev) memcpy(&ca_dwmci_dm_ops, &dm_dwmci_ops, sizeof(struct dm_mmc_ops)); dwmci_setup_cfg(&plat->cfg, host, host->bus_hz, MIN_FREQ); - if (host->buswidth == 1) { - (&plat->cfg)->host_caps &= ~MMC_MODE_8BIT; - (&plat->cfg)->host_caps &= ~MMC_MODE_4BIT; - } + if (host->buswidth == 1) + (&plat->cfg)->host_caps &= ~(MMC_MODE_8BIT | MMC_MODE_4BIT); host->mmc = &plat->mmc; host->mmc->priv = &priv->host; @@ -164,7 +154,7 @@ static int ca_dwmmc_bind(struct udevice *dev) } static const struct udevice_id ca_dwmmc_ids[] = { - { .compatible = "snps,dw-cortina" }, + { .compatible = "cortina,ca-mmc" }, { } }; diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index d5d955846c..a4b923ab99 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ /* * Copyright 2007, 2010-2011 Freescale Semiconductor, Inc - * Copyright 2019 NXP Semiconductors + * Copyright 2019-2020 NXP * Andy Fleming * * Based vaguely on the pxa mmc code: @@ -630,16 +630,15 @@ static int esdhc_init_common(struct fsl_esdhc_priv *priv, struct mmc *mmc) static int esdhc_getcd_common(struct fsl_esdhc_priv *priv) { struct fsl_esdhc *regs = priv->esdhc_regs; - int timeout = 1000; #ifdef CONFIG_ESDHC_DETECT_QUIRK if (CONFIG_ESDHC_DETECT_QUIRK) return 1; #endif - while (!(esdhc_read32(®s->prsstat) & PRSSTAT_CINS) && --timeout) - udelay(1000); + if (esdhc_read32(®s->prsstat) & PRSSTAT_CINS) + return 1; - return timeout > 0; + return 0; } static void fsl_esdhc_get_cfg_common(struct fsl_esdhc_priv *priv, @@ -724,13 +723,38 @@ __weak int esdhc_status_fixup(void *blob, const char *compat) return 0; } +#ifdef CONFIG_FSL_ESDHC_33V_IO_RELIABILITY_WORKAROUND +static int fsl_esdhc_get_cd(struct udevice *dev); + +static void esdhc_disable_for_no_card(void *blob) +{ + struct udevice *dev; + + for (uclass_first_device(UCLASS_MMC, &dev); + dev; + uclass_next_device(&dev)) { + char esdhc_path[50]; + + if (fsl_esdhc_get_cd(dev)) + continue; + + snprintf(esdhc_path, sizeof(esdhc_path), "/soc/esdhc@%lx", + (unsigned long)dev_read_addr(dev)); + do_fixup_by_path(blob, esdhc_path, "status", "disabled", + sizeof("disabled"), 1); + } +} +#endif + void fdt_fixup_esdhc(void *blob, bd_t *bd) { const char *compat = "fsl,esdhc"; if (esdhc_status_fixup(blob, compat)) return; - +#ifdef CONFIG_FSL_ESDHC_33V_IO_RELIABILITY_WORKAROUND + esdhc_disable_for_no_card(blob); +#endif do_fixup_by_compat_u32(blob, compat, "clock-frequency", gd->arch.sdhc_clk, 1); } @@ -849,6 +873,7 @@ static int fsl_esdhc_probe(struct udevice *dev) struct fsl_esdhc_priv *priv = dev_get_priv(dev); fdt_addr_t addr; struct mmc *mmc; + int ret; addr = dev_read_addr(dev); if (addr == FDT_ADDR_T_NONE) @@ -882,7 +907,15 @@ static int fsl_esdhc_probe(struct udevice *dev) upriv->mmc = mmc; - return esdhc_init_common(priv, mmc); + ret = esdhc_init_common(priv, mmc); + if (ret) + return ret; + +#ifdef CONFIG_FSL_ESDHC_33V_IO_RELIABILITY_WORKAROUND + if (!fsl_esdhc_get_cd(dev)) + esdhc_setbits32(&priv->esdhc_regs->proctl, PROCTL_VOLT_SEL); +#endif + return 0; } static int fsl_esdhc_get_cd(struct udevice *dev) diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c index 588d6a9d76..f42e018434 100644 --- a/drivers/mmc/fsl_esdhc_imx.c +++ b/drivers/mmc/fsl_esdhc_imx.c @@ -791,7 +791,7 @@ static int esdhc_set_voltage(struct mmc *mmc) switch (mmc->signal_voltage) { case MMC_SIGNAL_VOLTAGE_330: if (priv->vs18_enable) - return -EIO; + return -ENOTSUPP; #if CONFIG_IS_ENABLED(DM_REGULATOR) if (!IS_ERR_OR_NULL(priv->vqmmc_dev)) { ret = regulator_set_value(priv->vqmmc_dev, 3300000); @@ -972,7 +972,8 @@ static int esdhc_set_ios_common(struct fsl_esdhc_priv *priv, struct mmc *mmc) if (priv->signal_voltage != mmc->signal_voltage) { ret = esdhc_set_voltage(mmc); if (ret) { - printf("esdhc_set_voltage error %d\n", ret); + if (ret != -ENOTSUPP) + printf("esdhc_set_voltage error %d\n", ret); return ret; } } @@ -1455,6 +1456,7 @@ static int fsl_esdhc_probe(struct udevice *dev) if (ret) { dev_dbg(dev, "no vqmmc-supply\n"); } else { + priv->vqmmc_dev = vqmmc_dev; ret = regulator_set_enable(vqmmc_dev, true); if (ret) { dev_err(dev, "fail to enable vqmmc-supply\n"); diff --git a/drivers/power/regulator/regulator-uclass.c b/drivers/power/regulator/regulator-uclass.c index 7dcb317192..da679a572c 100644 --- a/drivers/power/regulator/regulator-uclass.c +++ b/drivers/power/regulator/regulator-uclass.c @@ -466,9 +466,6 @@ static int regulator_pre_probe(struct udevice *dev) (uc_pdata->min_uA == uc_pdata->max_uA)) uc_pdata->flags |= REGULATOR_FLAG_AUTOSET_UA; - if (uc_pdata->boot_on) - regulator_set_enable(dev, uc_pdata->boot_on); - return 0; } diff --git a/drivers/power/regulator/regulator_common.c b/drivers/power/regulator/regulator_common.c index 16d9412cd5..4cfcc31298 100644 --- a/drivers/power/regulator/regulator_common.c +++ b/drivers/power/regulator/regulator_common.c @@ -19,6 +19,8 @@ int regulator_common_ofdata_to_platdata(struct udevice *dev, if (!dev_read_bool(dev, "enable-active-high")) flags |= GPIOD_ACTIVE_LOW; + if (dev_read_bool(dev, "regulator-boot-on")) + flags |= GPIOD_IS_OUT_ACTIVE; /* Get optional enable GPIO desc */ gpio = &dev_pdata->gpio; diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 59415209ee..09b9cb17d8 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -119,6 +119,12 @@ config CF_SPI Enable the ColdFire SPI driver. This driver can be used on some m68k SoCs. +config DAVINCI_SPI + bool "Davinci & Keystone SPI driver" + depends on ARCH_DAVINCI || ARCH_KEYSTONE + help + Enable the Davinci SPI driver + config DESIGNWARE_SPI bool "Designware SPI driver" help @@ -207,6 +213,12 @@ config MVEBU_A3700_SPI used to access the SPI NOR flash on platforms embedding this Marvell IP core. +config MXS_SPI + bool "MXS SPI Driver" + help + Enable the MXS SPI controller driver. This driver can be used + on the i.MX23 and i.MX28 SoCs. + config NXP_FSPI bool "NXP FlexSPI driver" depends on SPI_MEM @@ -280,6 +292,12 @@ config SPI_SIFIVE The SiFive SPI controller driver is found on various SiFive SoCs. +config SOFT_SPI + bool "Soft SPI driver" + help + Enable Soft SPI driver. This driver is to use GPIO simulate + the SPI protocol. + config SPI_SUNXI bool "Allwinner SoC SPI controllers" default ARCH_SUNXI @@ -385,13 +403,6 @@ config ZYNQMP_GQSPI endif # if DM_SPI -config SOFT_SPI - bool "Soft SPI driver" - depends on DM_SPI || (DEPRECATED && !DM_SPI) - help - Enable Soft SPI driver. This driver is to use GPIO simulate - the SPI protocol. - config FSL_ESPI bool "Freescale eSPI driver" imply SPI_FLASH_BAR @@ -400,12 +411,6 @@ config FSL_ESPI access the SPI interface and SPI NOR flash on platforms embedding this Freescale eSPI IP core. -config DAVINCI_SPI - bool "Davinci & Keystone SPI driver" - depends on ARCH_DAVINCI || ARCH_KEYSTONE - help - Enable the Davinci SPI driver - config SH_QSPI bool "Renesas Quad SPI driver" help @@ -424,12 +429,6 @@ config MXC_SPI Enable the MXC SPI controller driver. This driver can be used on various i.MX SoCs such as i.MX31/35/51/6/7. -config MXS_SPI - bool "MXS SPI Driver" - help - Enable the MXS SPI controller driver. This driver can be used - on the i.MX23 and i.MX28 SoCs. - config OMAP3_SPI bool "McSPI driver for OMAP" help diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 342776404a..54881a7412 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -13,7 +13,6 @@ obj-$(CONFIG_TI_QSPI) += ti_qspi.o else obj-y += spi.o obj-$(CONFIG_SPI_MEM) += spi-mem-nodm.o -obj-$(CONFIG_SOFT_SPI) += soft_spi_legacy.o endif obj-$(CONFIG_ALTERA_SPI) += altera_spi.o diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index f076e92a93..b120664661 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c @@ -9,217 +9,102 @@ #include <spi.h> #include <malloc.h> #include <wait_bit.h> - #include <asm/io.h> - #include <asm/arch/clk.h> #include <asm/arch/hardware.h> -#ifdef CONFIG_DM_SPI #include <asm/arch/at91_spi.h> -#endif #if CONFIG_IS_ENABLED(DM_GPIO) #include <asm/gpio.h> #endif +#include <linux/bitops.h> -#include "atmel_spi.h" - -#ifndef CONFIG_DM_SPI - -static int spi_has_wdrbt(struct atmel_spi_slave *slave) -{ - unsigned int ver; - - ver = spi_readl(slave, VERSION); - - return (ATMEL_SPI_VERSION_REV(ver) >= 0x210); -} - -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) -{ - struct atmel_spi_slave *as; - unsigned int scbr; - u32 csrx; - void *regs; - - if (!spi_cs_is_valid(bus, cs)) - return NULL; - - switch (bus) { - case 0: - regs = (void *)ATMEL_BASE_SPI0; - break; -#ifdef ATMEL_BASE_SPI1 - case 1: - regs = (void *)ATMEL_BASE_SPI1; - break; -#endif -#ifdef ATMEL_BASE_SPI2 - case 2: - regs = (void *)ATMEL_BASE_SPI2; - break; -#endif -#ifdef ATMEL_BASE_SPI3 - case 3: - regs = (void *)ATMEL_BASE_SPI3; - break; -#endif - default: - return NULL; - } - - - scbr = (get_spi_clk_rate(bus) + max_hz - 1) / max_hz; - if (scbr > ATMEL_SPI_CSRx_SCBR_MAX) - /* Too low max SCK rate */ - return NULL; - if (scbr < 1) - scbr = 1; - - csrx = ATMEL_SPI_CSRx_SCBR(scbr); - csrx |= ATMEL_SPI_CSRx_BITS(ATMEL_SPI_BITS_8); - if (!(mode & SPI_CPHA)) - csrx |= ATMEL_SPI_CSRx_NCPHA; - if (mode & SPI_CPOL) - csrx |= ATMEL_SPI_CSRx_CPOL; - - as = spi_alloc_slave(struct atmel_spi_slave, bus, cs); - if (!as) - return NULL; - - as->regs = regs; - as->mr = ATMEL_SPI_MR_MSTR | ATMEL_SPI_MR_MODFDIS - | ATMEL_SPI_MR_PCS(~(1 << cs) & 0xf); - if (spi_has_wdrbt(as)) - as->mr |= ATMEL_SPI_MR_WDRBT; - - spi_writel(as, CSR(cs), csrx); - - return &as->slave; -} - -void spi_free_slave(struct spi_slave *slave) -{ - struct atmel_spi_slave *as = to_atmel_spi(slave); - - free(as); -} - -int spi_claim_bus(struct spi_slave *slave) -{ - struct atmel_spi_slave *as = to_atmel_spi(slave); - - /* Enable the SPI hardware */ - spi_writel(as, CR, ATMEL_SPI_CR_SPIEN); - - /* - * Select the slave. This should set SCK to the correct - * initial state, etc. - */ - spi_writel(as, MR, as->mr); - - return 0; -} - -void spi_release_bus(struct spi_slave *slave) -{ - struct atmel_spi_slave *as = to_atmel_spi(slave); - - /* Disable the SPI hardware */ - spi_writel(as, CR, ATMEL_SPI_CR_SPIDIS); -} - -int spi_xfer(struct spi_slave *slave, unsigned int bitlen, - const void *dout, void *din, unsigned long flags) -{ - struct atmel_spi_slave *as = to_atmel_spi(slave); - unsigned int len_tx; - unsigned int len_rx; - unsigned int len; - u32 status; - const u8 *txp = dout; - u8 *rxp = din; - u8 value; - - if (bitlen == 0) - /* Finish any previously submitted transfers */ - goto out; - - /* - * TODO: The controller can do non-multiple-of-8 bit - * transfers, but this driver currently doesn't support it. - * - * It's also not clear how such transfers are supposed to be - * represented as a stream of bytes...this is a limitation of - * the current SPI interface. - */ - if (bitlen % 8) { - /* Errors always terminate an ongoing transfer */ - flags |= SPI_XFER_END; - goto out; - } - - len = bitlen / 8; - - /* - * The controller can do automatic CS control, but it is - * somewhat quirky, and it doesn't really buy us much anyway - * in the context of U-Boot. - */ - if (flags & SPI_XFER_BEGIN) { - spi_cs_activate(slave); - /* - * sometimes the RDR is not empty when we get here, - * in theory that should not happen, but it DOES happen. - * Read it here to be on the safe side. - * That also clears the OVRES flag. Required if the - * following loop exits due to OVRES! - */ - spi_readl(as, RDR); - } - - for (len_tx = 0, len_rx = 0; len_rx < len; ) { - status = spi_readl(as, SR); - - if (status & ATMEL_SPI_SR_OVRES) - return -1; - - if (len_tx < len && (status & ATMEL_SPI_SR_TDRE)) { - if (txp) - value = *txp++; - else - value = 0; - spi_writel(as, TDR, value); - len_tx++; - } - if (status & ATMEL_SPI_SR_RDRF) { - value = spi_readl(as, RDR); - if (rxp) - *rxp++ = value; - len_rx++; - } - } - -out: - if (flags & SPI_XFER_END) { - /* - * Wait until the transfer is completely done before - * we deactivate CS. - */ - do { - status = spi_readl(as, SR); - } while (!(status & ATMEL_SPI_SR_TXEMPTY)); - - spi_cs_deactivate(slave); - } - - return 0; -} - -#else +/* + * Register definitions for the Atmel AT32/AT91 SPI Controller + */ +/* Register offsets */ +#define ATMEL_SPI_CR 0x0000 +#define ATMEL_SPI_MR 0x0004 +#define ATMEL_SPI_RDR 0x0008 +#define ATMEL_SPI_TDR 0x000c +#define ATMEL_SPI_SR 0x0010 +#define ATMEL_SPI_IER 0x0014 +#define ATMEL_SPI_IDR 0x0018 +#define ATMEL_SPI_IMR 0x001c +#define ATMEL_SPI_CSR(x) (0x0030 + 4 * (x)) +#define ATMEL_SPI_VERSION 0x00fc + +/* Bits in CR */ +#define ATMEL_SPI_CR_SPIEN BIT(0) +#define ATMEL_SPI_CR_SPIDIS BIT(1) +#define ATMEL_SPI_CR_SWRST BIT(7) +#define ATMEL_SPI_CR_LASTXFER BIT(24) + +/* Bits in MR */ +#define ATMEL_SPI_MR_MSTR BIT(0) +#define ATMEL_SPI_MR_PS BIT(1) +#define ATMEL_SPI_MR_PCSDEC BIT(2) +#define ATMEL_SPI_MR_FDIV BIT(3) +#define ATMEL_SPI_MR_MODFDIS BIT(4) +#define ATMEL_SPI_MR_WDRBT BIT(5) +#define ATMEL_SPI_MR_LLB BIT(7) +#define ATMEL_SPI_MR_PCS(x) (((x) & 15) << 16) +#define ATMEL_SPI_MR_DLYBCS(x) ((x) << 24) + +/* Bits in RDR */ +#define ATMEL_SPI_RDR_RD(x) (x) +#define ATMEL_SPI_RDR_PCS(x) ((x) << 16) + +/* Bits in TDR */ +#define ATMEL_SPI_TDR_TD(x) (x) +#define ATMEL_SPI_TDR_PCS(x) ((x) << 16) +#define ATMEL_SPI_TDR_LASTXFER BIT(24) + +/* Bits in SR/IER/IDR/IMR */ +#define ATMEL_SPI_SR_RDRF BIT(0) +#define ATMEL_SPI_SR_TDRE BIT(1) +#define ATMEL_SPI_SR_MODF BIT(2) +#define ATMEL_SPI_SR_OVRES BIT(3) +#define ATMEL_SPI_SR_ENDRX BIT(4) +#define ATMEL_SPI_SR_ENDTX BIT(5) +#define ATMEL_SPI_SR_RXBUFF BIT(6) +#define ATMEL_SPI_SR_TXBUFE BIT(7) +#define ATMEL_SPI_SR_NSSR BIT(8) +#define ATMEL_SPI_SR_TXEMPTY BIT(9) +#define ATMEL_SPI_SR_SPIENS BIT(16) + +/* Bits in CSRx */ +#define ATMEL_SPI_CSRx_CPOL BIT(0) +#define ATMEL_SPI_CSRx_NCPHA BIT(1) +#define ATMEL_SPI_CSRx_CSAAT BIT(3) +#define ATMEL_SPI_CSRx_BITS(x) ((x) << 4) +#define ATMEL_SPI_CSRx_SCBR(x) ((x) << 8) +#define ATMEL_SPI_CSRx_SCBR_MAX GENMASK(7, 0) +#define ATMEL_SPI_CSRx_DLYBS(x) ((x) << 16) +#define ATMEL_SPI_CSRx_DLYBCT(x) ((x) << 24) + +/* Bits in VERSION */ +#define ATMEL_SPI_VERSION_REV(x) ((x) & 0xfff) +#define ATMEL_SPI_VERSION_MFN(x) ((x) << 16) + +/* Constants for CSRx:BITS */ +#define ATMEL_SPI_BITS_8 0 +#define ATMEL_SPI_BITS_9 1 +#define ATMEL_SPI_BITS_10 2 +#define ATMEL_SPI_BITS_11 3 +#define ATMEL_SPI_BITS_12 4 +#define ATMEL_SPI_BITS_13 5 +#define ATMEL_SPI_BITS_14 6 +#define ATMEL_SPI_BITS_15 7 +#define ATMEL_SPI_BITS_16 8 #define MAX_CS_COUNT 4 +/* Register access macros */ +#define spi_readl(as, reg) \ + readl(as->regs + ATMEL_SPI_##reg) +#define spi_writel(as, reg, value) \ + writel(value, as->regs + ATMEL_SPI_##reg) + struct atmel_spi_platdata { struct at91_spi *regs; }; @@ -507,4 +392,3 @@ U_BOOT_DRIVER(atmel_spi) = { .priv_auto_alloc_size = sizeof(struct atmel_spi_priv), .probe = atmel_spi_probe, }; -#endif diff --git a/drivers/spi/atmel_spi.h b/drivers/spi/atmel_spi.h index 6167bd164b..9663cca5e6 100644 --- a/drivers/spi/atmel_spi.h +++ b/drivers/spi/atmel_spi.h @@ -79,23 +79,8 @@ #define ATMEL_SPI_BITS_15 7 #define ATMEL_SPI_BITS_16 8 -struct atmel_spi_slave { - struct spi_slave slave; - void *regs; - u32 mr; -}; - -static inline struct atmel_spi_slave *to_atmel_spi(struct spi_slave *slave) -{ - return container_of(slave, struct atmel_spi_slave, slave); -} - /* Register access macros */ #define spi_readl(as, reg) \ readl(as->regs + ATMEL_SPI_##reg) #define spi_writel(as, reg, value) \ writel(value, as->regs + ATMEL_SPI_##reg) - -#if !defined(CONFIG_SYS_SPI_WRITE_TOUT) -#define CONFIG_SYS_SPI_WRITE_TOUT (5 * CONFIG_SYS_HZ) -#endif diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c index 97ac97b1a5..e1e9b45cc9 100644 --- a/drivers/spi/davinci_spi.c +++ b/drivers/spi/davinci_spi.c @@ -55,41 +55,6 @@ /* SPIDEF */ #define SPIDEF_CSDEF0_MASK BIT(0) -#ifndef CONFIG_DM_SPI -#define SPI0_BUS 0 -#define SPI0_BASE CONFIG_SYS_SPI_BASE -/* - * Define default SPI0_NUM_CS as 1 for existing platforms that uses this - * driver. Platform can configure number of CS using CONFIG_SYS_SPI0_NUM_CS - * if more than one CS is supported and by defining CONFIG_SYS_SPI0. - */ -#ifndef CONFIG_SYS_SPI0 -#define SPI0_NUM_CS 1 -#else -#define SPI0_NUM_CS CONFIG_SYS_SPI0_NUM_CS -#endif - -/* - * define CONFIG_SYS_SPI1 when platform has spi-1 device (bus #1) and - * CONFIG_SYS_SPI1_NUM_CS defines number of CS on this bus - */ -#ifdef CONFIG_SYS_SPI1 -#define SPI1_BUS 1 -#define SPI1_NUM_CS CONFIG_SYS_SPI1_NUM_CS -#define SPI1_BASE CONFIG_SYS_SPI1_BASE -#endif - -/* - * define CONFIG_SYS_SPI2 when platform has spi-2 device (bus #2) and - * CONFIG_SYS_SPI2_NUM_CS defines number of CS on this bus - */ -#ifdef CONFIG_SYS_SPI2 -#define SPI2_BUS 2 -#define SPI2_NUM_CS CONFIG_SYS_SPI2_NUM_CS -#define SPI2_BASE CONFIG_SYS_SPI2_BASE -#endif -#endif - DECLARE_GLOBAL_DATA_PTR; /* davinci spi register set */ @@ -122,9 +87,6 @@ struct davinci_spi_regs { /* davinci spi slave */ struct davinci_spi_slave { -#ifndef CONFIG_DM_SPI - struct spi_slave slave; -#endif struct davinci_spi_regs *regs; unsigned int freq; /* current SPI bus frequency */ unsigned int mode; /* current SPI mode used */ @@ -346,124 +308,6 @@ out: return 0; } -#ifndef CONFIG_DM_SPI - -static inline struct davinci_spi_slave *to_davinci_spi(struct spi_slave *slave) -{ - return container_of(slave, struct davinci_spi_slave, slave); -} - -int spi_cs_is_valid(unsigned int bus, unsigned int cs) -{ - int ret = 0; - - switch (bus) { - case SPI0_BUS: - if (cs < SPI0_NUM_CS) - ret = 1; - break; -#ifdef CONFIG_SYS_SPI1 - case SPI1_BUS: - if (cs < SPI1_NUM_CS) - ret = 1; - break; -#endif -#ifdef CONFIG_SYS_SPI2 - case SPI2_BUS: - if (cs < SPI2_NUM_CS) - ret = 1; - break; -#endif - default: - /* Invalid bus number. Do nothing */ - break; - } - return ret; -} - -void spi_cs_activate(struct spi_slave *slave) -{ - /* do nothing */ -} - -void spi_cs_deactivate(struct spi_slave *slave) -{ - /* do nothing */ -} - -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) -{ - struct davinci_spi_slave *ds; - - if (!spi_cs_is_valid(bus, cs)) - return NULL; - - ds = spi_alloc_slave(struct davinci_spi_slave, bus, cs); - if (!ds) - return NULL; - - switch (bus) { - case SPI0_BUS: - ds->regs = (struct davinci_spi_regs *)SPI0_BASE; - break; -#ifdef CONFIG_SYS_SPI1 - case SPI1_BUS: - ds->regs = (struct davinci_spi_regs *)SPI1_BASE; - break; -#endif -#ifdef CONFIG_SYS_SPI2 - case SPI2_BUS: - ds->regs = (struct davinci_spi_regs *)SPI2_BASE; - break; -#endif - default: /* Invalid bus number */ - return NULL; - } - - ds->freq = max_hz; - ds->mode = mode; - - return &ds->slave; -} - -void spi_free_slave(struct spi_slave *slave) -{ - struct davinci_spi_slave *ds = to_davinci_spi(slave); - - free(ds); -} - -int spi_xfer(struct spi_slave *slave, unsigned int bitlen, - const void *dout, void *din, unsigned long flags) -{ - struct davinci_spi_slave *ds = to_davinci_spi(slave); - - ds->cur_cs = slave->cs; - - return __davinci_spi_xfer(ds, bitlen, dout, din, flags); -} - -int spi_claim_bus(struct spi_slave *slave) -{ - struct davinci_spi_slave *ds = to_davinci_spi(slave); - -#ifdef CONFIG_SPI_HALF_DUPLEX - ds->half_duplex = true; -#else - ds->half_duplex = false; -#endif - return __davinci_spi_claim_bus(ds, ds->slave.cs); -} - -void spi_release_bus(struct spi_slave *slave) -{ - struct davinci_spi_slave *ds = to_davinci_spi(slave); - - __davinci_spi_release_bus(ds); -} - -#else static int davinci_spi_set_speed(struct udevice *bus, uint max_hz) { struct davinci_spi_slave *ds = dev_get_priv(bus); @@ -582,4 +426,3 @@ U_BOOT_DRIVER(davinci_spi) = { .ops = &davinci_spi_ops, .priv_auto_alloc_size = sizeof(struct davinci_spi_slave), }; -#endif diff --git a/drivers/spi/fsl_dspi.c b/drivers/spi/fsl_dspi.c index 1cdb233110..78ad61ca37 100644 --- a/drivers/spi/fsl_dspi.c +++ b/drivers/spi/fsl_dspi.c @@ -100,13 +100,6 @@ struct fsl_dspi_priv { struct dspi *regs; }; -#ifndef CONFIG_DM_SPI -struct fsl_dspi { - struct spi_slave slave; - struct fsl_dspi_priv priv; -}; -#endif - __weak void cpu_dspi_port_conf(void) { } @@ -414,131 +407,7 @@ static int fsl_dspi_cfg_speed(struct fsl_dspi_priv *priv, uint speed) return 0; } -#ifndef CONFIG_DM_SPI -int spi_cs_is_valid(unsigned int bus, unsigned int cs) -{ - if (((cs >= 0) && (cs < 8)) && ((bus >= 0) && (bus < 8))) - return 1; - else - return 0; -} - -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) -{ - struct fsl_dspi *dspi; - uint mcr_cfg_val; - - dspi = spi_alloc_slave(struct fsl_dspi, bus, cs); - if (!dspi) - return NULL; - - cpu_dspi_port_conf(); - -#ifdef CONFIG_SYS_FSL_DSPI_BE - dspi->priv.flags |= DSPI_FLAG_REGMAP_ENDIAN_BIG; -#endif - - dspi->priv.regs = (struct dspi *)MMAP_DSPI; - -#ifdef CONFIG_M68K - dspi->priv.bus_clk = gd->bus_clk; -#else - dspi->priv.bus_clk = mxc_get_clock(MXC_DSPI_CLK); -#endif - dspi->priv.speed_hz = FSL_DSPI_DEFAULT_SCK_FREQ; - - /* default: all CS signals inactive state is high */ - mcr_cfg_val = DSPI_MCR_MSTR | DSPI_MCR_PCSIS_MASK | - DSPI_MCR_CRXF | DSPI_MCR_CTXF; - fsl_dspi_init_mcr(&dspi->priv, mcr_cfg_val); - - for (i = 0; i < FSL_DSPI_MAX_CHIPSELECT; i++) - dspi->priv.ctar_val[i] = DSPI_CTAR_DEFAULT_VALUE; - -#ifdef CONFIG_SYS_DSPI_CTAR0 - if (FSL_DSPI_MAX_CHIPSELECT > 0) - dspi->priv.ctar_val[0] = CONFIG_SYS_DSPI_CTAR0; -#endif -#ifdef CONFIG_SYS_DSPI_CTAR1 - if (FSL_DSPI_MAX_CHIPSELECT > 1) - dspi->priv.ctar_val[1] = CONFIG_SYS_DSPI_CTAR1; -#endif -#ifdef CONFIG_SYS_DSPI_CTAR2 - if (FSL_DSPI_MAX_CHIPSELECT > 2) - dspi->priv.ctar_val[2] = CONFIG_SYS_DSPI_CTAR2; -#endif -#ifdef CONFIG_SYS_DSPI_CTAR3 - if (FSL_DSPI_MAX_CHIPSELECT > 3) - dspi->priv.ctar_val[3] = CONFIG_SYS_DSPI_CTAR3; -#endif -#ifdef CONFIG_SYS_DSPI_CTAR4 - if (FSL_DSPI_MAX_CHIPSELECT > 4) - dspi->priv.ctar_val[4] = CONFIG_SYS_DSPI_CTAR4; -#endif -#ifdef CONFIG_SYS_DSPI_CTAR5 - if (FSL_DSPI_MAX_CHIPSELECT > 5) - dspi->priv.ctar_val[5] = CONFIG_SYS_DSPI_CTAR5; -#endif -#ifdef CONFIG_SYS_DSPI_CTAR6 - if (FSL_DSPI_MAX_CHIPSELECT > 6) - dspi->priv.ctar_val[6] = CONFIG_SYS_DSPI_CTAR6; -#endif -#ifdef CONFIG_SYS_DSPI_CTAR7 - if (FSL_DSPI_MAX_CHIPSELECT > 7) - dspi->priv.ctar_val[7] = CONFIG_SYS_DSPI_CTAR7; -#endif - fsl_dspi_cfg_speed(&dspi->priv, max_hz); - - /* configure transfer mode */ - fsl_dspi_cfg_ctar_mode(&dspi->priv, cs, mode); - - /* configure active state of CSX */ - fsl_dspi_cfg_cs_active_state(&dspi->priv, cs, mode); - - return &dspi->slave; -} - -void spi_free_slave(struct spi_slave *slave) -{ - free(slave); -} - -int spi_claim_bus(struct spi_slave *slave) -{ - uint sr_val; - struct fsl_dspi *dspi = (struct fsl_dspi *)slave; - - cpu_dspi_claim_bus(slave->bus, slave->cs); - - fsl_dspi_clr_fifo(&dspi->priv); - - /* check module TX and RX status */ - sr_val = dspi_read32(dspi->priv.flags, &dspi->priv.regs->sr); - if ((sr_val & DSPI_SR_TXRXS) != DSPI_SR_TXRXS) { - debug("DSPI RX/TX not ready!\n"); - return -EIO; - } - - return 0; -} - -void spi_release_bus(struct spi_slave *slave) -{ - struct fsl_dspi *dspi = (struct fsl_dspi *)slave; - - dspi_halt(&dspi->priv, 1); - cpu_dspi_release_bus(slave->bus.slave->cs); -} - -int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, - void *din, unsigned long flags) -{ - struct fsl_dspi *dspi = (struct fsl_dspi *)slave; - return dspi_xfer(&dspi->priv, slave->cs, bitlen, dout, din, flags); -} -#else static int fsl_dspi_child_pre_probe(struct udevice *dev) { struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); @@ -745,4 +614,3 @@ U_BOOT_DRIVER(fsl_dspi) = { .child_pre_probe = fsl_dspi_child_pre_probe, .bind = fsl_dspi_bind, }; -#endif diff --git a/drivers/spi/fsl_espi.c b/drivers/spi/fsl_espi.c index 50d194f614..5c76fd962e 100644 --- a/drivers/spi/fsl_espi.c +++ b/drivers/spi/fsl_espi.c @@ -3,7 +3,9 @@ * eSPI controller driver. * * Copyright 2010-2011 Freescale Semiconductor, Inc. + * Copyright 2020 NXP * Author: Mingkai Hu (Mingkai.hu@freescale.com) + * Chuanhua Han (chuanhua.han@nxp.com) */ #include <common.h> @@ -14,10 +16,16 @@ #include <malloc.h> #include <spi.h> #include <asm/immap_85xx.h> +#include <dm.h> +#include <errno.h> +#include <fdtdec.h> +#include <dm/platform_data/fsl_espi.h> struct fsl_spi_slave { struct spi_slave slave; ccsr_espi_t *espi; + u32 speed_hz; + unsigned int cs; unsigned int div16; unsigned int pm; int tx_timeout; @@ -31,6 +39,9 @@ struct fsl_spi_slave { #define to_fsl_spi_slave(s) container_of(s, struct fsl_spi_slave, slave) #define US_PER_SECOND 1000000UL +/* default SCK frequency, unit: HZ */ +#define FSL_ESPI_DEFAULT_SCK_FREQ 10000000 + #define ESPI_MAX_CS_NUM 4 #define ESPI_FIFO_WIDTH_BIT 32 @@ -65,116 +76,27 @@ struct fsl_spi_slave { #define ESPI_MAX_DATA_TRANSFER_LEN 0xFFF0 -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) -{ - struct fsl_spi_slave *fsl; - sys_info_t sysinfo; - unsigned long spibrg = 0; - unsigned long spi_freq = 0; - unsigned char pm = 0; - - if (!spi_cs_is_valid(bus, cs)) - return NULL; - - fsl = spi_alloc_slave(struct fsl_spi_slave, bus, cs); - if (!fsl) - return NULL; - - fsl->espi = (void *)(CONFIG_SYS_MPC85xx_ESPI_ADDR); - fsl->mode = mode; - fsl->max_transfer_length = ESPI_MAX_DATA_TRANSFER_LEN; - - /* Set eSPI BRG clock source */ - get_sys_info(&sysinfo); - spibrg = sysinfo.freq_systembus / 2; - fsl->div16 = 0; - if ((spibrg / max_hz) > 32) { - fsl->div16 = ESPI_CSMODE_DIV16; - pm = spibrg / (max_hz * 16 * 2); - if (pm > 16) { - pm = 16; - debug("Requested speed is too low: %d Hz, %ld Hz " - "is used.\n", max_hz, spibrg / (32 * 16)); - } - } else - pm = spibrg / (max_hz * 2); - if (pm) - pm--; - fsl->pm = pm; - - if (fsl->div16) - spi_freq = spibrg / ((pm + 1) * 2 * 16); - else - spi_freq = spibrg / ((pm + 1) * 2); - - /* set tx_timeout to 10 times of one espi FIFO entry go out */ - fsl->tx_timeout = DIV_ROUND_UP((US_PER_SECOND * ESPI_FIFO_WIDTH_BIT - * 10), spi_freq); - - return &fsl->slave; -} - -void spi_free_slave(struct spi_slave *slave) -{ - struct fsl_spi_slave *fsl = to_fsl_spi_slave(slave); - free(fsl); -} - -int spi_claim_bus(struct spi_slave *slave) +void fsl_spi_cs_activate(struct spi_slave *slave, uint cs) { struct fsl_spi_slave *fsl = to_fsl_spi_slave(slave); ccsr_espi_t *espi = fsl->espi; - unsigned char pm = fsl->pm; - unsigned int cs = slave->cs; - unsigned int mode = fsl->mode; - unsigned int div16 = fsl->div16; - int i; - - debug("%s: bus:%i cs:%i\n", __func__, slave->bus, cs); - - /* Enable eSPI interface */ - out_be32(&espi->mode, ESPI_MODE_RXTHR(3) - | ESPI_MODE_TXTHR(4) | ESPI_MODE_EN); - - out_be32(&espi->event, 0xffffffff); /* Clear all eSPI events */ - out_be32(&espi->mask, 0x00000000); /* Mask all eSPI interrupts */ - - /* Init CS mode interface */ - for (i = 0; i < ESPI_MAX_CS_NUM; i++) - out_be32(&espi->csmode[i], ESPI_CSMODE_INIT_VAL); - - out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs]) & - ~(ESPI_CSMODE_PM(0xF) | ESPI_CSMODE_DIV16 - | ESPI_CSMODE_CI_INACTIVEHIGH | ESPI_CSMODE_CP_BEGIN_EDGCLK - | ESPI_CSMODE_REV_MSB_FIRST | ESPI_CSMODE_LEN(0xF))); - - /* Set eSPI BRG clock source */ - out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs]) - | ESPI_CSMODE_PM(pm) | div16); - - /* Set eSPI mode */ - if (mode & SPI_CPHA) - out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs]) - | ESPI_CSMODE_CP_BEGIN_EDGCLK); - if (mode & SPI_CPOL) - out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs]) - | ESPI_CSMODE_CI_INACTIVEHIGH); - - /* Character bit order: msb first */ - out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs]) - | ESPI_CSMODE_REV_MSB_FIRST); - - /* Character length in bits, between 0x3~0xf, i.e. 4bits~16bits */ - out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs]) - | ESPI_CSMODE_LEN(7)); + unsigned int com = 0; + size_t data_len = fsl->data_len; - return 0; + com &= ~(ESPI_COM_CS(0x3) | ESPI_COM_TRANLEN(0xFFFF)); + com |= ESPI_COM_CS(cs); + com |= ESPI_COM_TRANLEN(data_len - 1); + out_be32(&espi->com, com); } -void spi_release_bus(struct spi_slave *slave) +void fsl_spi_cs_deactivate(struct spi_slave *slave) { + struct fsl_spi_slave *fsl = to_fsl_spi_slave(slave); + ccsr_espi_t *espi = fsl->espi; + /* clear the RXCNT and TXCNT */ + out_be32(&espi->mode, in_be32(&espi->mode) & (~ESPI_MODE_EN)); + out_be32(&espi->mode, in_be32(&espi->mode) | ESPI_MODE_EN); } static void fsl_espi_tx(struct fsl_spi_slave *fsl, const void *dout) @@ -207,7 +129,8 @@ static void fsl_espi_tx(struct fsl_spi_slave *fsl, const void *dout) debug("***spi_xfer:...Tx timeout! event = %08x\n", event); } -static int fsl_espi_rx(struct fsl_spi_slave *fsl, void *din, unsigned int bytes) +static int fsl_espi_rx(struct fsl_spi_slave *fsl, void *din, + unsigned int bytes) { ccsr_espi_t *espi = fsl->espi; unsigned int tmpdin, rx_times; @@ -239,10 +162,17 @@ static int fsl_espi_rx(struct fsl_spi_slave *fsl, void *din, unsigned int bytes) return bytes; } -int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out, - void *data_in, unsigned long flags) +void espi_release_bus(struct fsl_spi_slave *fsl) { - struct fsl_spi_slave *fsl = to_fsl_spi_slave(slave); + /* Disable the SPI hardware */ + out_be32(&fsl->espi->mode, + in_be32(&fsl->espi->mode) & (~ESPI_MODE_EN)); +} + +int espi_xfer(struct fsl_spi_slave *fsl, uint cs, unsigned int bitlen, + const void *data_out, void *data_in, unsigned long flags) +{ + struct spi_slave *slave = &fsl->slave; ccsr_espi_t *espi = fsl->espi; unsigned int event, rx_bytes; const void *dout = NULL; @@ -261,13 +191,14 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out, max_tran_len = fsl->max_transfer_length; switch (flags) { case SPI_XFER_BEGIN: - cmd_len = fsl->cmd_len = data_len; + cmd_len = data_len; + fsl->cmd_len = cmd_len; memcpy(cmd_buf, data_out, cmd_len); return 0; case 0: case SPI_XFER_END: if (bitlen == 0) { - spi_cs_deactivate(slave); + fsl_spi_cs_deactivate(slave); return 0; } buf_len = 2 * cmd_len + min(data_len, (size_t)max_tran_len); @@ -307,7 +238,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out, num_blks = DIV_ROUND_UP(tran_len + cmd_len, 4); num_bytes = (tran_len + cmd_len) % 4; fsl->data_len = tran_len + cmd_len; - spi_cs_activate(slave); + fsl_spi_cs_activate(slave, cs); /* Clear all eSPI events */ out_be32(&espi->event , 0xffffffff); @@ -350,37 +281,304 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out, *(int *)buffer += tran_len; } } - spi_cs_deactivate(slave); + fsl_spi_cs_deactivate(slave); } free(buffer); return 0; } +void espi_claim_bus(struct fsl_spi_slave *fsl, unsigned int cs) +{ + ccsr_espi_t *espi = fsl->espi; + unsigned char pm = fsl->pm; + unsigned int mode = fsl->mode; + unsigned int div16 = fsl->div16; + int i; + + /* Enable eSPI interface */ + out_be32(&espi->mode, ESPI_MODE_RXTHR(3) + | ESPI_MODE_TXTHR(4) | ESPI_MODE_EN); + + out_be32(&espi->event, 0xffffffff); /* Clear all eSPI events */ + out_be32(&espi->mask, 0x00000000); /* Mask all eSPI interrupts */ + + /* Init CS mode interface */ + for (i = 0; i < ESPI_MAX_CS_NUM; i++) + out_be32(&espi->csmode[i], ESPI_CSMODE_INIT_VAL); + + out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs]) & + ~(ESPI_CSMODE_PM(0xF) | ESPI_CSMODE_DIV16 + | ESPI_CSMODE_CI_INACTIVEHIGH | ESPI_CSMODE_CP_BEGIN_EDGCLK + | ESPI_CSMODE_REV_MSB_FIRST | ESPI_CSMODE_LEN(0xF))); + + /* Set eSPI BRG clock source */ + out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs]) + | ESPI_CSMODE_PM(pm) | div16); + + /* Set eSPI mode */ + if (mode & SPI_CPHA) + out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs]) + | ESPI_CSMODE_CP_BEGIN_EDGCLK); + if (mode & SPI_CPOL) + out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs]) + | ESPI_CSMODE_CI_INACTIVEHIGH); + + /* Character bit order: msb first */ + out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs]) + | ESPI_CSMODE_REV_MSB_FIRST); + + /* Character length in bits, between 0x3~0xf, i.e. 4bits~16bits */ + out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs]) + | ESPI_CSMODE_LEN(7)); +} + +void espi_setup_slave(struct fsl_spi_slave *fsl) +{ + unsigned int max_hz; + sys_info_t sysinfo; + unsigned long spibrg = 0; + unsigned long spi_freq = 0; + unsigned char pm = 0; + + max_hz = fsl->speed_hz; + + get_sys_info(&sysinfo); + spibrg = sysinfo.freq_systembus / 2; + fsl->div16 = 0; + if ((spibrg / max_hz) > 32) { + fsl->div16 = ESPI_CSMODE_DIV16; + pm = spibrg / (max_hz * 16 * 2); + if (pm > 16) { + pm = 16; + debug("max_hz is too low: %d Hz, %ld Hz is used.\n", + max_hz, spibrg / (32 * 16)); + } + } else { + pm = spibrg / (max_hz * 2); + } + if (pm) + pm--; + fsl->pm = pm; + + if (fsl->div16) + spi_freq = spibrg / ((pm + 1) * 2 * 16); + else + spi_freq = spibrg / ((pm + 1) * 2); + + /* set tx_timeout to 10 times of one espi FIFO entry go out */ + fsl->tx_timeout = DIV_ROUND_UP((US_PER_SECOND * ESPI_FIFO_WIDTH_BIT + * 10), spi_freq);/* Set eSPI BRG clock source */ +} + +#if !CONFIG_IS_ENABLED(DM_SPI) int spi_cs_is_valid(unsigned int bus, unsigned int cs) { return bus == 0 && cs < ESPI_MAX_CS_NUM; } -void spi_cs_activate(struct spi_slave *slave) +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + struct fsl_spi_slave *fsl; + + if (!spi_cs_is_valid(bus, cs)) + return NULL; + + fsl = spi_alloc_slave(struct fsl_spi_slave, bus, cs); + if (!fsl) + return NULL; + + fsl->espi = (void *)(CONFIG_SYS_MPC85xx_ESPI_ADDR); + fsl->mode = mode; + fsl->max_transfer_length = ESPI_MAX_DATA_TRANSFER_LEN; + fsl->speed_hz = max_hz; + + espi_setup_slave(fsl); + + return &fsl->slave; +} + +void spi_free_slave(struct spi_slave *slave) { struct fsl_spi_slave *fsl = to_fsl_spi_slave(slave); - ccsr_espi_t *espi = fsl->espi; - unsigned int com = 0; - size_t data_len = fsl->data_len; - com &= ~(ESPI_COM_CS(0x3) | ESPI_COM_TRANLEN(0xFFFF)); - com |= ESPI_COM_CS(slave->cs); - com |= ESPI_COM_TRANLEN(data_len - 1); - out_be32(&espi->com, com); + free(fsl); } -void spi_cs_deactivate(struct spi_slave *slave) +int spi_claim_bus(struct spi_slave *slave) { struct fsl_spi_slave *fsl = to_fsl_spi_slave(slave); - ccsr_espi_t *espi = fsl->espi; - /* clear the RXCNT and TXCNT */ - out_be32(&espi->mode, in_be32(&espi->mode) & (~ESPI_MODE_EN)); - out_be32(&espi->mode, in_be32(&espi->mode) | ESPI_MODE_EN); + espi_claim_bus(fsl, slave->cs); + + return 0; } + +void spi_release_bus(struct spi_slave *slave) +{ + struct fsl_spi_slave *fsl = to_fsl_spi_slave(slave); + + espi_release_bus(fsl); +} + +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, + void *din, unsigned long flags) +{ + struct fsl_spi_slave *fsl = (struct fsl_spi_slave *)slave; + + return espi_xfer(fsl, slave->cs, bitlen, dout, din, flags); +} +#else +static void __espi_set_speed(struct fsl_spi_slave *fsl) +{ + espi_setup_slave(fsl); + + /* Set eSPI BRG clock source */ + out_be32(&fsl->espi->csmode[fsl->cs], + in_be32(&fsl->espi->csmode[fsl->cs]) + | ESPI_CSMODE_PM(fsl->pm) | fsl->div16); +} + +static void __espi_set_mode(struct fsl_spi_slave *fsl) +{ + /* Set eSPI mode */ + if (fsl->mode & SPI_CPHA) + out_be32(&fsl->espi->csmode[fsl->cs], + in_be32(&fsl->espi->csmode[fsl->cs]) + | ESPI_CSMODE_CP_BEGIN_EDGCLK); + if (fsl->mode & SPI_CPOL) + out_be32(&fsl->espi->csmode[fsl->cs], + in_be32(&fsl->espi->csmode[fsl->cs]) + | ESPI_CSMODE_CI_INACTIVEHIGH); +} + +static int fsl_espi_claim_bus(struct udevice *dev) +{ + struct udevice *bus = dev->parent; + struct fsl_spi_slave *fsl = dev_get_priv(bus); + + espi_claim_bus(fsl, fsl->cs); + + return 0; +} + +static int fsl_espi_release_bus(struct udevice *dev) +{ + struct udevice *bus = dev->parent; + struct fsl_spi_slave *fsl = dev_get_priv(bus); + + espi_release_bus(fsl); + + return 0; +} + +static int fsl_espi_xfer(struct udevice *dev, unsigned int bitlen, + const void *dout, void *din, unsigned long flags) +{ + struct udevice *bus = dev->parent; + struct fsl_spi_slave *fsl = dev_get_priv(bus); + + return espi_xfer(fsl, fsl->cs, bitlen, dout, din, flags); +} + +static int fsl_espi_set_speed(struct udevice *bus, uint speed) +{ + struct fsl_spi_slave *fsl = dev_get_priv(bus); + + debug("%s speed %u\n", __func__, speed); + fsl->speed_hz = speed; + + __espi_set_speed(fsl); + + return 0; +} + +static int fsl_espi_set_mode(struct udevice *bus, uint mode) +{ + struct fsl_spi_slave *fsl = dev_get_priv(bus); + + debug("%s mode %u\n", __func__, mode); + fsl->mode = mode; + + __espi_set_mode(fsl); + + return 0; +} + +static int fsl_espi_child_pre_probe(struct udevice *dev) +{ + struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); + struct udevice *bus = dev->parent; + struct fsl_spi_slave *fsl = dev_get_priv(bus); + + debug("%s cs %u\n", __func__, slave_plat->cs); + fsl->cs = slave_plat->cs; + + return 0; +} + +static int fsl_espi_probe(struct udevice *bus) +{ + struct fsl_espi_platdata *plat = dev_get_platdata(bus); + struct fsl_spi_slave *fsl = dev_get_priv(bus); + + fsl->espi = (ccsr_espi_t *)((u32)plat->regs_addr); + fsl->max_transfer_length = ESPI_MAX_DATA_TRANSFER_LEN; + fsl->speed_hz = plat->speed_hz; + + debug("%s probe done, bus-num %d.\n", bus->name, bus->seq); + + return 0; +} + +static const struct dm_spi_ops fsl_espi_ops = { + .claim_bus = fsl_espi_claim_bus, + .release_bus = fsl_espi_release_bus, + .xfer = fsl_espi_xfer, + .set_speed = fsl_espi_set_speed, + .set_mode = fsl_espi_set_mode, +}; + +#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) +static int fsl_espi_ofdata_to_platdata(struct udevice *bus) +{ + fdt_addr_t addr; + struct fsl_espi_platdata *plat = bus->platdata; + const void *blob = gd->fdt_blob; + int node = dev_of_offset(bus); + + addr = dev_read_addr(bus); + if (addr == FDT_ADDR_T_NONE) + return -EINVAL; + + plat->regs_addr = lower_32_bits(addr); + plat->speed_hz = fdtdec_get_int(blob, node, "spi-max-frequency", + FSL_ESPI_DEFAULT_SCK_FREQ); + + debug("ESPI: regs=%p, max-frequency=%d\n", + &plat->regs_addr, plat->speed_hz); + + return 0; +} + +static const struct udevice_id fsl_espi_ids[] = { + { .compatible = "fsl,mpc8536-espi" }, + { } +}; +#endif + +U_BOOT_DRIVER(fsl_espi) = { + .name = "fsl_espi", + .id = UCLASS_SPI, +#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) + .of_match = fsl_espi_ids, + .ofdata_to_platdata = fsl_espi_ofdata_to_platdata, +#endif + .ops = &fsl_espi_ops, + .platdata_auto_alloc_size = sizeof(struct fsl_espi_platdata), + .priv_auto_alloc_size = sizeof(struct fsl_spi_slave), + .probe = fsl_espi_probe, + .child_pre_probe = fsl_espi_child_pre_probe, +}; +#endif diff --git a/drivers/spi/mxs_spi.c b/drivers/spi/mxs_spi.c index 0da4a80d71..e231e96e58 100644 --- a/drivers/spi/mxs_spi.c +++ b/drivers/spi/mxs_spi.c @@ -13,7 +13,10 @@ */ #include <common.h> +#include <dm.h> +#include <dt-structs.h> #include <cpu_func.h> +#include <errno.h> #include <log.h> #include <malloc.h> #include <memalign.h> @@ -34,34 +37,9 @@ #define MXSSSP_SMALL_TRANSFER 512 -static void mxs_spi_start_xfer(struct mxs_ssp_regs *ssp_regs) -{ - writel(SSP_CTRL0_LOCK_CS, &ssp_regs->hw_ssp_ctrl0_set); - writel(SSP_CTRL0_IGNORE_CRC, &ssp_regs->hw_ssp_ctrl0_clr); -} - -static void mxs_spi_end_xfer(struct mxs_ssp_regs *ssp_regs) -{ - writel(SSP_CTRL0_LOCK_CS, &ssp_regs->hw_ssp_ctrl0_clr); - writel(SSP_CTRL0_IGNORE_CRC, &ssp_regs->hw_ssp_ctrl0_set); -} - -#if !CONFIG_IS_ENABLED(DM_SPI) -struct mxs_spi_slave { - struct spi_slave slave; - uint32_t max_khz; - uint32_t mode; - struct mxs_ssp_regs *regs; -}; - -static inline struct mxs_spi_slave *to_mxs_slave(struct spi_slave *slave) -{ - return container_of(slave, struct mxs_spi_slave, slave); -} -#else -#include <dm.h> -#include <errno.h> -#include <dt-structs.h> +/* Base numbers of i.MX2[38] clk for ssp0 IP block */ +#define MXS_SSP_IMX23_CLKID_SSP0 33 +#define MXS_SSP_IMX28_CLKID_SSP0 46 #ifdef CONFIG_MX28 #define dtd_fsl_imx_spi dtd_fsl_imx28_spi @@ -87,20 +65,24 @@ struct mxs_spi_priv { unsigned int clk_id; unsigned int mode; }; -#endif -#if !CONFIG_IS_ENABLED(DM_SPI) -static int mxs_spi_xfer_pio(struct mxs_spi_slave *slave, - char *data, int length, int write, unsigned long flags) +static void mxs_spi_start_xfer(struct mxs_ssp_regs *ssp_regs) { - struct mxs_ssp_regs *ssp_regs = slave->regs; -#else + writel(SSP_CTRL0_LOCK_CS, &ssp_regs->hw_ssp_ctrl0_set); + writel(SSP_CTRL0_IGNORE_CRC, &ssp_regs->hw_ssp_ctrl0_clr); +} + +static void mxs_spi_end_xfer(struct mxs_ssp_regs *ssp_regs) +{ + writel(SSP_CTRL0_LOCK_CS, &ssp_regs->hw_ssp_ctrl0_clr); + writel(SSP_CTRL0_IGNORE_CRC, &ssp_regs->hw_ssp_ctrl0_set); +} + static int mxs_spi_xfer_pio(struct mxs_spi_priv *priv, char *data, int length, int write, unsigned long flags) { struct mxs_ssp_regs *ssp_regs = priv->regs; -#endif if (flags & SPI_XFER_BEGIN) mxs_spi_start_xfer(ssp_regs); @@ -156,17 +138,10 @@ static int mxs_spi_xfer_pio(struct mxs_spi_priv *priv, return 0; } -#if !CONFIG_IS_ENABLED(DM_SPI) -static int mxs_spi_xfer_dma(struct mxs_spi_slave *slave, - char *data, int length, int write, unsigned long flags) -{ - struct mxs_ssp_regs *ssp_regs = slave->regs; -#else static int mxs_spi_xfer_dma(struct mxs_spi_priv *priv, char *data, int length, int write, unsigned long flags) { struct mxs_ssp_regs *ssp_regs = priv->regs; -#endif const int xfer_max_sz = 0xff00; const int desc_count = DIV_ROUND_UP(length, xfer_max_sz) + 1; struct mxs_dma_desc *dp; @@ -207,11 +182,7 @@ static int mxs_spi_xfer_dma(struct mxs_spi_priv *priv, /* Invalidate the area, so no writeback into the RAM races with DMA */ invalidate_dcache_range(dstart, dstart + cache_data_count); -#if !CONFIG_IS_ENABLED(DM_SPI) - dmach = MXS_DMA_CHANNEL_AHB_APBH_SSP0 + slave->slave.bus; -#else dmach = priv->dma_channel; -#endif dp = desc; while (length) { @@ -288,20 +259,12 @@ static int mxs_spi_xfer_dma(struct mxs_spi_priv *priv, return ret; } -#if !CONFIG_IS_ENABLED(DM_SPI) -int spi_xfer(struct spi_slave *slave, unsigned int bitlen, - const void *dout, void *din, unsigned long flags) -{ - struct mxs_spi_slave *mxs_slave = to_mxs_slave(slave); - struct mxs_ssp_regs *ssp_regs = mxs_slave->regs; -#else int mxs_spi_xfer(struct udevice *dev, unsigned int bitlen, const void *dout, void *din, unsigned long flags) { struct udevice *bus = dev_get_parent(dev); struct mxs_spi_priv *priv = dev_get_priv(bus); struct mxs_ssp_regs *ssp_regs = priv->regs; -#endif int len = bitlen / 8; char dummy; int write = 0; @@ -345,99 +308,13 @@ int mxs_spi_xfer(struct udevice *dev, unsigned int bitlen, if (!dma || (len < MXSSSP_SMALL_TRANSFER)) { writel(SSP_CTRL1_DMA_ENABLE, &ssp_regs->hw_ssp_ctrl1_clr); -#if !CONFIG_IS_ENABLED(DM_SPI) - return mxs_spi_xfer_pio(mxs_slave, data, len, write, flags); -#else return mxs_spi_xfer_pio(priv, data, len, write, flags); -#endif } else { writel(SSP_CTRL1_DMA_ENABLE, &ssp_regs->hw_ssp_ctrl1_set); -#if !CONFIG_IS_ENABLED(DM_SPI) - return mxs_spi_xfer_dma(mxs_slave, data, len, write, flags); -#else return mxs_spi_xfer_dma(priv, data, len, write, flags); -#endif } } -#if !CONFIG_IS_ENABLED(DM_SPI) -int spi_cs_is_valid(unsigned int bus, unsigned int cs) -{ - /* MXS SPI: 4 ports and 3 chip selects maximum */ - if (!mxs_ssp_bus_id_valid(bus) || cs > 2) - return 0; - else - return 1; -} - -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) -{ - struct mxs_spi_slave *mxs_slave; - - if (!spi_cs_is_valid(bus, cs)) { - printf("mxs_spi: invalid bus %d / chip select %d\n", bus, cs); - return NULL; - } - - mxs_slave = spi_alloc_slave(struct mxs_spi_slave, bus, cs); - if (!mxs_slave) - return NULL; - - if (mxs_dma_init_channel(MXS_DMA_CHANNEL_AHB_APBH_SSP0 + bus)) - goto err_init; - - mxs_slave->max_khz = max_hz / 1000; - mxs_slave->mode = mode; - mxs_slave->regs = mxs_ssp_regs_by_bus(bus); - - return &mxs_slave->slave; - -err_init: - free(mxs_slave); - return NULL; -} - -void spi_free_slave(struct spi_slave *slave) -{ - struct mxs_spi_slave *mxs_slave = to_mxs_slave(slave); - - free(mxs_slave); -} - -int spi_claim_bus(struct spi_slave *slave) -{ - struct mxs_spi_slave *mxs_slave = to_mxs_slave(slave); - struct mxs_ssp_regs *ssp_regs = mxs_slave->regs; - u32 reg = 0; - - mxs_reset_block(&ssp_regs->hw_ssp_ctrl0_reg); - - writel((slave->cs << MXS_SSP_CHIPSELECT_SHIFT) | - SSP_CTRL0_BUS_WIDTH_ONE_BIT, - &ssp_regs->hw_ssp_ctrl0); - - reg = SSP_CTRL1_SSP_MODE_SPI | SSP_CTRL1_WORD_LENGTH_EIGHT_BITS; - reg |= (mxs_slave->mode & SPI_CPOL) ? SSP_CTRL1_POLARITY : 0; - reg |= (mxs_slave->mode & SPI_CPHA) ? SSP_CTRL1_PHASE : 0; - writel(reg, &ssp_regs->hw_ssp_ctrl1); - - writel(0, &ssp_regs->hw_ssp_cmd0); - - mxs_set_ssp_busclock(slave->bus, mxs_slave->max_khz); - - return 0; -} - -void spi_release_bus(struct spi_slave *slave) -{ -} - -#else /* CONFIG_DM_SPI */ -/* Base numbers of i.MX2[38] clk for ssp0 IP block */ -#define MXS_SSP_IMX23_CLKID_SSP0 33 -#define MXS_SSP_IMX28_CLKID_SSP0 46 - static int mxs_spi_probe(struct udevice *bus) { struct mxs_spi_platdata *plat = dev_get_platdata(bus); @@ -625,4 +502,3 @@ U_BOOT_DRIVER(mxs_spi) = { .priv_auto_alloc_size = sizeof(struct mxs_spi_priv), .probe = mxs_spi_probe, }; -#endif diff --git a/drivers/spi/soft_spi_legacy.c b/drivers/spi/soft_spi_legacy.c deleted file mode 100644 index cc5ab5f991..0000000000 --- a/drivers/spi/soft_spi_legacy.c +++ /dev/null @@ -1,168 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * (C) Copyright 2002 - * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com. - * - * Influenced by code from: - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - */ - -#include <common.h> -#include <spi.h> - -#include <malloc.h> - -/*----------------------------------------------------------------------- - * Definitions - */ - -#ifdef DEBUG_SPI -#define PRINTD(fmt,args...) printf (fmt ,##args) -#else -#define PRINTD(fmt,args...) -#endif - -struct soft_spi_slave { - struct spi_slave slave; - unsigned int mode; -}; - -static inline struct soft_spi_slave *to_soft_spi(struct spi_slave *slave) -{ - return container_of(slave, struct soft_spi_slave, slave); -} - -/*=====================================================================*/ -/* Public Functions */ -/*=====================================================================*/ - -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) -{ - struct soft_spi_slave *ss; - - if (!spi_cs_is_valid(bus, cs)) - return NULL; - - ss = spi_alloc_slave(struct soft_spi_slave, bus, cs); - if (!ss) - return NULL; - - ss->mode = mode; - - /* TODO: Use max_hz to limit the SCK rate */ - - return &ss->slave; -} - -void spi_free_slave(struct spi_slave *slave) -{ - struct soft_spi_slave *ss = to_soft_spi(slave); - - free(ss); -} - -int spi_claim_bus(struct spi_slave *slave) -{ -#ifdef CONFIG_SYS_IMMR - volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; -#endif - struct soft_spi_slave *ss = to_soft_spi(slave); - - /* - * Make sure the SPI clock is in idle state as defined for - * this slave. - */ - if (ss->mode & SPI_CPOL) - SPI_SCL(1); - else - SPI_SCL(0); - - return 0; -} - -void spi_release_bus(struct spi_slave *slave) -{ - /* Nothing to do */ -} - -/*----------------------------------------------------------------------- - * SPI transfer - * - * This writes "bitlen" bits out the SPI MOSI port and simultaneously clocks - * "bitlen" bits in the SPI MISO port. That's just the way SPI works. - * - * The source of the outgoing bits is the "dout" parameter and the - * destination of the input bits is the "din" parameter. Note that "dout" - * and "din" can point to the same memory location, in which case the - * input data overwrites the output data (since both are buffered by - * temporary variables, this is OK). - */ -int spi_xfer(struct spi_slave *slave, unsigned int bitlen, - const void *dout, void *din, unsigned long flags) -{ -#ifdef CONFIG_SYS_IMMR - volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; -#endif - struct soft_spi_slave *ss = to_soft_spi(slave); - uchar tmpdin = 0; - uchar tmpdout = 0; - const u8 *txd = dout; - u8 *rxd = din; - int cpol = ss->mode & SPI_CPOL; - int cpha = ss->mode & SPI_CPHA; - unsigned int j; - - PRINTD("spi_xfer: slave %u:%u dout %08X din %08X bitlen %u\n", - slave->bus, slave->cs, *(uint *)txd, *(uint *)rxd, bitlen); - - if (flags & SPI_XFER_BEGIN) - spi_cs_activate(slave); - - for(j = 0; j < bitlen; j++) { - /* - * Check if it is time to work on a new byte. - */ - if ((j % 8) == 0) { - if (txd) - tmpdout = *txd++; - else - tmpdout = 0; - if(j != 0) { - if (rxd) - *rxd++ = tmpdin; - } - tmpdin = 0; - } - - if (!cpha) - SPI_SCL(!cpol); - SPI_SDA(tmpdout & 0x80); - SPI_DELAY; - if (cpha) - SPI_SCL(!cpol); - else - SPI_SCL(cpol); - tmpdin <<= 1; - tmpdin |= SPI_READ; - tmpdout <<= 1; - SPI_DELAY; - if (cpha) - SPI_SCL(cpol); - } - /* - * If the number of bits isn't a multiple of 8, shift the last - * bits over to left-justify them. Then store the last byte - * read in. - */ - if (rxd) { - if ((bitlen % 8) != 0) - tmpdin <<= 8 - (bitlen % 8); - *rxd++ = tmpdin; - } - - if (flags & SPI_XFER_END) - spi_cs_deactivate(slave); - - return(0); -} diff --git a/drivers/usb/eth/r8152.h b/drivers/usb/eth/r8152.h index c7f62b8b3e..10e0da8eb1 100644 --- a/drivers/usb/eth/r8152.h +++ b/drivers/usb/eth/r8152.h @@ -25,6 +25,7 @@ #define PLA_BDC_CR 0xd1a0 #define PLA_TEREDO_TIMER 0xd2cc #define PLA_REALWOW_TIMER 0xd2e8 +#define PLA_EXTRA_STATUS 0xd398 #define PLA_LEDSEL 0xdd90 #define PLA_LED_FEATURE 0xdd92 #define PLA_PHYAR 0xde00 @@ -76,6 +77,7 @@ #define USB_DEV_STAT 0xb808 #define USB_CONNECT_TIMER 0xcbf8 #define USB_BURST_SIZE 0xcfc0 +#define USB_FW_FIX_EN1 0xcfcc #define USB_USB_CTRL 0xd406 #define USB_PHY_CTRL 0xd408 #define USB_TX_AGG 0xd40a @@ -285,6 +287,9 @@ /* PLA_BOOT_CTRL */ #define AUTOLOAD_DONE 0x0002 +/* PLA_EXTRA_STATUS */ +#define U3P3_CHECK_EN BIT(7) + /* USB_USB2PHY */ #define USB2PHY_SUSPEND 0x0001 #define USB2PHY_L1 0x0002 @@ -304,6 +309,9 @@ #define STAT_SPEED_HIGH 0x0000 #define STAT_SPEED_FULL 0x0002 +/* USB_FW_FIX_EN1 */ +#define FW_IP_RESET_EN BIT(9) + /* USB_TX_AGG */ #define TX_AGG_MAX_THRESHOLD 0x03 diff --git a/drivers/usb/eth/r8152_fw.c b/drivers/usb/eth/r8152_fw.c index 3ebbd533cc..f953b0384b 100644 --- a/drivers/usb/eth/r8152_fw.c +++ b/drivers/usb/eth/r8152_fw.c @@ -293,7 +293,7 @@ static u8 r8152b_pla_patch_a2[] = { 0x00, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static u16 r8152b_pla_patch_a2_bp[] = { - 0xfc28, 0x8000, 0xfc28, 0x17a5, 0xfc2a, 0x13ad, + 0xfc26, 0x8000, 0xfc28, 0x17a5, 0xfc2a, 0x13ad, 0xfc2c, 0x184d, 0xfc2e, 0x01e1 }; static u16 r8153_ram_code_a[] = { @@ -321,181 +321,150 @@ static u16 r8153_ram_code_a[] = { 0xB438, 0x3591, 0xB436, 0xB820, 0xB438, 0x0210 }; static u8 r8153_usb_patch_c[] = { - 0x08, 0xe0, 0x0a, 0xe0, 0x14, 0xe0, 0x2e, 0xe0, - 0x37, 0xe0, 0x3e, 0xe0, 0x6d, 0xe0, 0x78, 0xe0, + 0x08, 0xe0, 0x0a, 0xe0, 0x14, 0xe0, 0x58, 0xe0, + 0x64, 0xe0, 0x79, 0xe0, 0xab, 0xe0, 0xb6, 0xe0, 0x02, 0xc5, 0x00, 0xbd, 0x38, 0x3b, 0xdb, 0x49, 0x04, 0xf1, 0x06, 0xc3, 0x00, 0xbb, 0x5a, 0x02, 0x05, 0xc4, 0x03, 0xc3, 0x00, 0xbb, 0xa4, 0x04, - 0x7e, 0x02, 0x30, 0xd4, 0x30, 0x18, 0x18, 0xc1, - 0x0c, 0xe8, 0x17, 0xc6, 0xc7, 0x65, 0xd0, 0x49, + 0x7e, 0x02, 0x30, 0xd4, 0x65, 0xc6, 0x66, 0x61, + 0x92, 0x49, 0x12, 0xf1, 0x3e, 0xc0, 0x02, 0x61, + 0x97, 0x49, 0x05, 0xf0, 0x3c, 0xc0, 0x00, 0x61, + 0x90, 0x49, 0x0a, 0xf1, 0xca, 0x63, 0xb0, 0x49, + 0x09, 0xf1, 0xb1, 0x49, 0x05, 0xf0, 0x32, 0xc0, + 0x00, 0x71, 0x9e, 0x49, 0x03, 0xf1, 0xb0, 0x48, + 0x05, 0xe0, 0x30, 0x48, 0xda, 0x61, 0x10, 0x48, + 0xda, 0x89, 0x4a, 0xc6, 0xc0, 0x60, 0x85, 0x49, + 0x03, 0xf0, 0x31, 0x48, 0x04, 0xe0, 0xb1, 0x48, + 0xb2, 0x48, 0x0f, 0xe0, 0x30, 0x18, 0x1b, 0xc1, + 0x0f, 0xe8, 0x1a, 0xc6, 0xc7, 0x65, 0xd0, 0x49, 0x05, 0xf0, 0x32, 0x48, 0x02, 0xc2, 0x00, 0xba, 0x3e, 0x16, 0x02, 0xc2, 0x00, 0xba, 0x48, 0x16, - 0x02, 0xb4, 0x09, 0xc2, 0x40, 0x99, 0x0e, 0x48, - 0x42, 0x98, 0x42, 0x70, 0x8e, 0x49, 0xfe, 0xf1, - 0x02, 0xb0, 0x80, 0xff, 0xc0, 0xd4, 0xe4, 0x40, - 0x20, 0xd4, 0xb0, 0x49, 0x04, 0xf0, 0x30, 0x18, - 0x06, 0xc1, 0xef, 0xef, 0xfa, 0xc7, 0x02, 0xc0, - 0x00, 0xb8, 0xd0, 0x10, 0xe4, 0x4b, 0x07, 0xc3, - 0x70, 0x61, 0x12, 0x48, 0x70, 0x89, 0x02, 0xc3, - 0x00, 0xbb, 0x9c, 0x15, 0x20, 0xd4, 0x2b, 0xc5, - 0xa0, 0x77, 0x00, 0x1c, 0xa0, 0x9c, 0x28, 0xc5, - 0xa0, 0x64, 0xc0, 0x48, 0xc1, 0x48, 0xc2, 0x48, - 0xa0, 0x8c, 0xb1, 0x64, 0xc0, 0x48, 0xb1, 0x8c, - 0x20, 0xc5, 0xa0, 0x64, 0x40, 0x48, 0x41, 0x48, - 0xc2, 0x48, 0xa0, 0x8c, 0x19, 0xc5, 0xa4, 0x64, - 0x44, 0x48, 0xa4, 0x8c, 0xb1, 0x64, 0x40, 0x48, - 0xb1, 0x8c, 0x14, 0xc4, 0x80, 0x73, 0x13, 0xc4, - 0x82, 0x9b, 0x11, 0x1b, 0x80, 0x9b, 0x0c, 0xc5, - 0xa0, 0x64, 0x40, 0x48, 0x41, 0x48, 0x42, 0x48, - 0xa0, 0x8c, 0x05, 0xc5, 0xa0, 0x9f, 0x02, 0xc5, - 0x00, 0xbd, 0x6c, 0x3a, 0x1e, 0xfc, 0x10, 0xd8, - 0x86, 0xd4, 0xf8, 0xcb, 0x20, 0xe4, 0x0a, 0xc0, - 0x16, 0x61, 0x91, 0x48, 0x16, 0x89, 0x07, 0xc0, - 0x11, 0x19, 0x0c, 0x89, 0x02, 0xc1, 0x00, 0xb9, - 0x02, 0x06, 0x00, 0xd4, 0x40, 0xb4, 0xfe, 0xc0, - 0x16, 0x61, 0x91, 0x48, 0x16, 0x89, 0xfb, 0xc0, - 0x11, 0x19, 0x0c, 0x89, 0x02, 0xc1, 0x00, 0xb9, - 0xd2, 0x05, 0x00, 0x00 }; + 0x02, 0xc2, 0x00, 0xba, 0x4a, 0x16, 0x02, 0xb4, + 0x09, 0xc2, 0x40, 0x99, 0x0e, 0x48, 0x42, 0x98, + 0x42, 0x70, 0x8e, 0x49, 0xfe, 0xf1, 0x02, 0xb0, + 0x80, 0xff, 0xc0, 0xd4, 0xe4, 0x40, 0x20, 0xd4, + 0xca, 0xcf, 0x00, 0xcf, 0x3c, 0xe4, 0x0c, 0xc0, + 0x00, 0x63, 0xb5, 0x49, 0x09, 0xc0, 0x30, 0x18, + 0x06, 0xc1, 0xea, 0xef, 0xf5, 0xc7, 0x02, 0xc0, + 0x00, 0xb8, 0xd0, 0x10, 0xe4, 0x4b, 0x00, 0xd8, + 0x14, 0xc3, 0x60, 0x61, 0x90, 0x49, 0x06, 0xf0, + 0x11, 0xc3, 0x70, 0x61, 0x12, 0x48, 0x70, 0x89, + 0x08, 0xe0, 0x0a, 0xc6, 0xd4, 0x61, 0x93, 0x48, + 0xd4, 0x89, 0x02, 0xc1, 0x00, 0xb9, 0x72, 0x17, + 0x02, 0xc1, 0x00, 0xb9, 0x9c, 0x15, 0x00, 0xd8, + 0xef, 0xcf, 0x20, 0xd4, 0x30, 0x18, 0xe7, 0xc1, + 0xcb, 0xef, 0x2b, 0xc5, 0xa0, 0x77, 0x00, 0x1c, + 0xa0, 0x9c, 0x28, 0xc5, 0xa0, 0x64, 0xc0, 0x48, + 0xc1, 0x48, 0xc2, 0x48, 0xa0, 0x8c, 0xb1, 0x64, + 0xc0, 0x48, 0xb1, 0x8c, 0x20, 0xc5, 0xa0, 0x64, + 0x40, 0x48, 0x41, 0x48, 0xc2, 0x48, 0xa0, 0x8c, + 0x19, 0xc5, 0xa4, 0x64, 0x44, 0x48, 0xa4, 0x8c, + 0xb1, 0x64, 0x40, 0x48, 0xb1, 0x8c, 0x14, 0xc4, + 0x80, 0x73, 0x13, 0xc4, 0x82, 0x9b, 0x11, 0x1b, + 0x80, 0x9b, 0x0c, 0xc5, 0xa0, 0x64, 0x40, 0x48, + 0x41, 0x48, 0x42, 0x48, 0xa0, 0x8c, 0x05, 0xc5, + 0xa0, 0x9f, 0x02, 0xc5, 0x00, 0xbd, 0x6c, 0x3a, + 0x1e, 0xfc, 0x10, 0xd8, 0x86, 0xd4, 0xf8, 0xcb, + 0x20, 0xe4, 0x0a, 0xc0, 0x16, 0x61, 0x91, 0x48, + 0x16, 0x89, 0x07, 0xc0, 0x11, 0x19, 0x0c, 0x89, + 0x02, 0xc1, 0x00, 0xb9, 0x02, 0x06, 0x00, 0xd4, + 0x40, 0xb4, 0xfe, 0xc0, 0x16, 0x61, 0x91, 0x48, + 0x16, 0x89, 0xfb, 0xc0, 0x11, 0x19, 0x0c, 0x89, + 0x02, 0xc1, 0x00, 0xb9, 0xd2, 0x05, 0x00, 0x00 }; static u16 r8153_usb_patch_c_bp[] = { - 0xfc26, 0xa000, 0xfc28, 0x3b34, 0xfc2a, 0x027c, 0xfc2c, 0x162c, - 0xfc2e, 0x10ce, 0xfc30, 0x0000, 0xfc32, 0x3a28, 0xfc34, 0x05f8, - 0xfc36, 0x05c8 }; + 0xfc26, 0xa000, 0xfc28, 0x3b34, 0xfc2a, 0x027c, 0xfc2c, 0x15de, + 0xfc2e, 0x10ce, 0xfc30, 0x1adc, 0xfc32, 0x3a28, 0xfc34, 0x05f8, + 0xfc36, 0x05c8, 0xfc38, 0x00f3 }; static u8 r8153_pla_patch_c[] = { - 0x08, 0xe0, 0xea, 0xe0, 0xf2, 0xe0, 0x04, 0xe1, - 0x06, 0xe1, 0x08, 0xe1, 0x40, 0xe1, 0xf1, 0xe1, - 0x14, 0xc2, 0x40, 0x73, 0xba, 0x48, 0x40, 0x9b, - 0x11, 0xc2, 0x40, 0x73, 0xb0, 0x49, 0x17, 0xf0, - 0xbf, 0x49, 0x03, 0xf1, 0x09, 0xc5, 0x00, 0xbd, - 0xb1, 0x49, 0x11, 0xf0, 0xb1, 0x48, 0x40, 0x9b, - 0x02, 0xc2, 0x00, 0xba, 0xde, 0x18, 0x00, 0xe0, - 0x1e, 0xfc, 0xbc, 0xc0, 0xf0, 0xc0, 0xde, 0xe8, - 0x00, 0x80, 0x00, 0x20, 0x2c, 0x75, 0xd4, 0x49, - 0x12, 0xf1, 0x32, 0xe0, 0xf8, 0xc2, 0x46, 0x71, - 0xf7, 0xc2, 0x40, 0x73, 0xbe, 0x49, 0x03, 0xf1, - 0xf5, 0xc7, 0x02, 0xe0, 0xf2, 0xc7, 0x4f, 0x30, - 0x26, 0x62, 0xa1, 0x49, 0xf0, 0xf1, 0x22, 0x72, - 0xa0, 0x49, 0xed, 0xf1, 0x25, 0x25, 0x18, 0x1f, - 0x97, 0x30, 0x91, 0x30, 0x36, 0x9a, 0x2c, 0x75, - 0x3c, 0xc3, 0x60, 0x73, 0xb1, 0x49, 0x0d, 0xf1, - 0xdc, 0x21, 0xbc, 0x25, 0x30, 0xc6, 0xc0, 0x77, - 0x04, 0x13, 0x21, 0xf0, 0x03, 0x13, 0x22, 0xf0, - 0x02, 0x13, 0x23, 0xf0, 0x01, 0x13, 0x24, 0xf0, - 0x08, 0x13, 0x08, 0xf1, 0x2e, 0x73, 0xba, 0x21, - 0xbd, 0x25, 0x05, 0x13, 0x03, 0xf1, 0x24, 0xc5, - 0x00, 0xbd, 0xd4, 0x49, 0x03, 0xf1, 0x1c, 0xc5, - 0x00, 0xbd, 0xc4, 0xc6, 0xc6, 0x67, 0x2e, 0x75, - 0xd7, 0x22, 0xdd, 0x26, 0x05, 0x15, 0x1b, 0xf0, - 0x14, 0xc6, 0x00, 0xbe, 0x13, 0xc5, 0x00, 0xbd, - 0x12, 0xc5, 0x00, 0xbd, 0xf1, 0x49, 0xfb, 0xf1, - 0xef, 0xe7, 0xf4, 0x49, 0xfa, 0xf1, 0xec, 0xe7, - 0xf3, 0x49, 0xf7, 0xf1, 0xe9, 0xe7, 0xf2, 0x49, - 0xf4, 0xf1, 0xe6, 0xe7, 0xb6, 0xc0, 0x50, 0x14, - 0x90, 0x13, 0xbc, 0x13, 0xf2, 0x14, 0x00, 0xa0, - 0xa0, 0xd1, 0x00, 0x00, 0xc0, 0x75, 0xd0, 0x49, - 0x46, 0xf0, 0x26, 0x72, 0xa7, 0x49, 0x43, 0xf0, - 0x22, 0x72, 0x25, 0x25, 0x20, 0x1f, 0x97, 0x30, - 0x91, 0x30, 0x40, 0x73, 0xf3, 0xc4, 0x1c, 0x40, - 0x04, 0xf0, 0xd7, 0x49, 0x05, 0xf1, 0x37, 0xe0, - 0x53, 0x48, 0xc0, 0x9d, 0x08, 0x02, 0x40, 0x66, - 0x64, 0x27, 0x06, 0x16, 0x30, 0xf1, 0x46, 0x63, - 0x3b, 0x13, 0x2d, 0xf1, 0x34, 0x9b, 0x18, 0x1b, - 0x93, 0x30, 0x2b, 0xc3, 0x10, 0x1c, 0x2b, 0xe8, - 0x01, 0x14, 0x25, 0xf1, 0x00, 0x1d, 0x26, 0x1a, - 0x8a, 0x30, 0x22, 0x73, 0xb5, 0x25, 0x0e, 0x0b, - 0x00, 0x1c, 0x2c, 0xe8, 0x1f, 0xc7, 0x27, 0x40, - 0x1a, 0xf1, 0x38, 0xe8, 0x32, 0x1f, 0x8f, 0x30, - 0x08, 0x1b, 0x24, 0xe8, 0x36, 0x72, 0x46, 0x77, - 0x00, 0x17, 0x0d, 0xf0, 0x13, 0xc3, 0x1f, 0x40, - 0x03, 0xf1, 0x00, 0x1f, 0x46, 0x9f, 0x44, 0x77, - 0x9f, 0x44, 0x5f, 0x44, 0x17, 0xe8, 0x0a, 0xc7, - 0x27, 0x40, 0x05, 0xf1, 0x02, 0xc3, 0x00, 0xbb, - 0xbe, 0x1a, 0x74, 0x14, 0xff, 0xc7, 0x00, 0xbf, - 0xb8, 0xcd, 0xff, 0xff, 0x02, 0x0c, 0x54, 0xa5, - 0xdc, 0xa5, 0x2f, 0x40, 0x05, 0xf1, 0x00, 0x14, - 0xfa, 0xf1, 0x01, 0x1c, 0x02, 0xe0, 0x00, 0x1c, - 0x80, 0xff, 0xb0, 0x49, 0x04, 0xf0, 0x01, 0x0b, - 0xd3, 0xa1, 0x03, 0xe0, 0x02, 0x0b, 0xd3, 0xa5, - 0x27, 0x31, 0x20, 0x37, 0x02, 0x0b, 0xd3, 0xa5, - 0x27, 0x31, 0x20, 0x37, 0x00, 0x13, 0xfb, 0xf1, - 0x80, 0xff, 0x22, 0x73, 0xb5, 0x25, 0x18, 0x1e, - 0xde, 0x30, 0xd9, 0x30, 0x64, 0x72, 0x11, 0x1e, - 0x68, 0x23, 0x16, 0x31, 0x80, 0xff, 0x08, 0xc2, - 0x40, 0x73, 0x3a, 0x48, 0x40, 0x9b, 0x06, 0xff, - 0x02, 0xc6, 0x00, 0xbe, 0xcc, 0x17, 0x1e, 0xfc, - 0x2c, 0x75, 0xdc, 0x21, 0xbc, 0x25, 0x04, 0x13, - 0x0b, 0xf0, 0x03, 0x13, 0x09, 0xf0, 0x02, 0x13, - 0x07, 0xf0, 0x01, 0x13, 0x05, 0xf0, 0x08, 0x13, - 0x03, 0xf0, 0x04, 0xc3, 0x00, 0xbb, 0x03, 0xc3, - 0x00, 0xbb, 0x50, 0x17, 0x3a, 0x17, 0x02, 0xc6, - 0x00, 0xbe, 0x00, 0x00, 0x02, 0xc6, 0x00, 0xbe, - 0x00, 0x00, 0x33, 0xc5, 0xa0, 0x74, 0xc0, 0x49, - 0x1f, 0xf0, 0x30, 0xc5, 0xa0, 0x73, 0x00, 0x13, - 0x04, 0xf1, 0xa2, 0x73, 0x00, 0x13, 0x14, 0xf0, - 0x28, 0xc5, 0xa0, 0x74, 0xc8, 0x49, 0x1b, 0xf1, - 0x26, 0xc5, 0xa0, 0x76, 0xa2, 0x74, 0x01, 0x06, - 0x20, 0x37, 0xa0, 0x9e, 0xa2, 0x9c, 0x1e, 0xc5, - 0xa2, 0x73, 0x23, 0x40, 0x10, 0xf8, 0x04, 0xf3, - 0xa0, 0x73, 0x33, 0x40, 0x0c, 0xf8, 0x15, 0xc5, - 0xa0, 0x74, 0x41, 0x48, 0xa0, 0x9c, 0x14, 0xc5, - 0xa0, 0x76, 0x62, 0x48, 0xe0, 0x48, 0xa0, 0x9e, - 0x10, 0xc6, 0x00, 0xbe, 0x0a, 0xc5, 0xa0, 0x74, - 0x48, 0x48, 0xa0, 0x9c, 0x0b, 0xc5, 0x20, 0x1e, - 0xa0, 0x9e, 0xe5, 0x48, 0xa0, 0x9e, 0xf0, 0xe7, - 0xbc, 0xc0, 0xc8, 0xd2, 0xcc, 0xd2, 0x28, 0xe4, - 0xfa, 0x01, 0xf0, 0xc0, 0x18, 0x89, 0x00, 0x1d, - 0x43, 0xc3, 0x62, 0x62, 0xa0, 0x49, 0x06, 0xf0, - 0x41, 0xc0, 0x02, 0x71, 0x60, 0x99, 0x3f, 0xc1, - 0x03, 0xe0, 0x3c, 0xc0, 0x3d, 0xc1, 0x02, 0x99, - 0x00, 0x61, 0x67, 0x11, 0x3d, 0xf1, 0x69, 0x33, - 0x34, 0xc0, 0x28, 0x40, 0xf7, 0xf1, 0x35, 0xc0, - 0x00, 0x19, 0x81, 0x1b, 0x89, 0xe8, 0x32, 0xc0, - 0x04, 0x1a, 0x84, 0x1b, 0x85, 0xe8, 0x7a, 0xe8, - 0xa3, 0x49, 0xfe, 0xf0, 0x2c, 0xc0, 0x76, 0xe8, - 0xa1, 0x48, 0x29, 0xc0, 0x84, 0x1b, 0x7c, 0xe8, - 0x00, 0x1d, 0x69, 0x33, 0x00, 0x1e, 0x01, 0x06, - 0xff, 0x18, 0x30, 0x40, 0xfd, 0xf1, 0x7f, 0xc0, - 0x00, 0x76, 0x2e, 0x40, 0xf7, 0xf1, 0x21, 0x48, - 0x1a, 0xc0, 0x84, 0x1b, 0x6d, 0xe8, 0x76, 0xc0, - 0x61, 0xe8, 0xa1, 0x49, 0xfd, 0xf0, 0x12, 0xc0, - 0x00, 0x1a, 0x84, 0x1b, 0x65, 0xe8, 0x5a, 0xe8, - 0xa5, 0x49, 0xfe, 0xf0, 0x0a, 0xc0, 0x01, 0x19, - 0x81, 0x1b, 0x5e, 0xe8, 0x48, 0xe0, 0x8c, 0xd3, - 0xb8, 0x0b, 0x50, 0xe8, 0x83, 0x00, 0x82, 0x00, - 0x20, 0xb4, 0x10, 0xd8, 0x84, 0xd4, 0xfa, 0xc0, - 0x00, 0x61, 0x9c, 0x20, 0x9c, 0x24, 0x06, 0x11, - 0x06, 0xf1, 0x5d, 0xc0, 0x00, 0x61, 0x11, 0x48, - 0x00, 0x89, 0x35, 0xe0, 0x00, 0x11, 0x02, 0xf1, - 0x03, 0xe0, 0x04, 0x11, 0x06, 0xf1, 0x53, 0xc0, - 0x00, 0x61, 0x92, 0x48, 0x00, 0x89, 0x2b, 0xe0, - 0x05, 0x11, 0x08, 0xf1, 0x4c, 0xc0, 0x00, 0x61, - 0x91, 0x49, 0x04, 0xf0, 0x91, 0x48, 0x00, 0x89, - 0x11, 0xe0, 0xdc, 0xc0, 0x00, 0x61, 0x98, 0x20, - 0x98, 0x24, 0x25, 0x11, 0x1c, 0xf1, 0x40, 0xc0, - 0x25, 0xe8, 0x95, 0x49, 0x18, 0xf0, 0xd2, 0xc0, - 0x00, 0x61, 0x98, 0x20, 0x98, 0x24, 0x25, 0x11, - 0x12, 0xf1, 0x35, 0xc0, 0x00, 0x61, 0x92, 0x49, - 0x0e, 0xf1, 0x12, 0x48, 0x00, 0x89, 0x2d, 0xc0, - 0x00, 0x19, 0x00, 0x89, 0x2b, 0xc0, 0x01, 0x89, - 0x27, 0xc0, 0x10, 0xe8, 0x25, 0xc0, 0x12, 0x48, - 0x81, 0x1b, 0x16, 0xe8, 0xb9, 0xc3, 0x62, 0x62, - 0xa0, 0x49, 0x05, 0xf0, 0xb5, 0xc3, 0x60, 0x71, - 0xb5, 0xc0, 0x02, 0x99, 0x02, 0xc0, 0x00, 0xb8, - 0xd6, 0x07, 0x13, 0xc4, 0x84, 0x98, 0x00, 0x1b, - 0x86, 0x8b, 0x86, 0x73, 0xbf, 0x49, 0xfe, 0xf1, - 0x80, 0x71, 0x82, 0x72, 0x80, 0xff, 0x09, 0xc4, - 0x84, 0x98, 0x80, 0x99, 0x82, 0x9a, 0x86, 0x8b, - 0x86, 0x73, 0xbf, 0x49, 0xfe, 0xf1, 0x80, 0xff, - 0x08, 0xea, 0x10, 0xd4, 0x88, 0xd3, 0x30, 0xd4, - 0x10, 0xc0, 0x12, 0xe8, 0x8a, 0xd3, 0x00, 0xd8, - 0x02, 0xc0, 0x00, 0xb8, 0xe0, 0x08, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + 0x5d, 0xe0, 0x07, 0xe0, 0x0f, 0xe0, 0x5a, 0xe0, + 0x59, 0xe0, 0x1f, 0xe0, 0x57, 0xe0, 0x3e, 0xe1, + 0x08, 0xc2, 0x40, 0x73, 0x3a, 0x48, 0x40, 0x9b, + 0x06, 0xff, 0x02, 0xc6, 0x00, 0xbe, 0xcc, 0x17, + 0x1e, 0xfc, 0x2c, 0x75, 0xdc, 0x21, 0xbc, 0x25, + 0x04, 0x13, 0x0b, 0xf0, 0x03, 0x13, 0x09, 0xf0, + 0x02, 0x13, 0x07, 0xf0, 0x01, 0x13, 0x05, 0xf0, + 0x08, 0x13, 0x03, 0xf0, 0x04, 0xc3, 0x00, 0xbb, + 0x03, 0xc3, 0x00, 0xbb, 0x50, 0x17, 0x3a, 0x17, + 0x33, 0xc5, 0xa0, 0x74, 0xc0, 0x49, 0x1f, 0xf0, + 0x30, 0xc5, 0xa0, 0x73, 0x00, 0x13, 0x04, 0xf1, + 0xa2, 0x73, 0x00, 0x13, 0x14, 0xf0, 0x28, 0xc5, + 0xa0, 0x74, 0xc8, 0x49, 0x1b, 0xf1, 0x26, 0xc5, + 0xa0, 0x76, 0xa2, 0x74, 0x01, 0x06, 0x20, 0x37, + 0xa0, 0x9e, 0xa2, 0x9c, 0x1e, 0xc5, 0xa2, 0x73, + 0x23, 0x40, 0x10, 0xf8, 0x04, 0xf3, 0xa0, 0x73, + 0x33, 0x40, 0x0c, 0xf8, 0x15, 0xc5, 0xa0, 0x74, + 0x41, 0x48, 0xa0, 0x9c, 0x14, 0xc5, 0xa0, 0x76, + 0x62, 0x48, 0xe0, 0x48, 0xa0, 0x9e, 0x10, 0xc6, + 0x00, 0xbe, 0x0a, 0xc5, 0xa0, 0x74, 0x48, 0x48, + 0xa0, 0x9c, 0x0b, 0xc5, 0x20, 0x1e, 0xa0, 0x9e, + 0xe5, 0x48, 0xa0, 0x9e, 0xf0, 0xe7, 0xbc, 0xc0, + 0xc8, 0xd2, 0xcc, 0xd2, 0x28, 0xe4, 0xfa, 0x01, + 0xf0, 0xc0, 0x18, 0x89, 0x74, 0xc0, 0xcd, 0xe8, + 0x80, 0x76, 0x00, 0x1d, 0x6e, 0xc3, 0x66, 0x62, + 0xa0, 0x49, 0x06, 0xf0, 0x64, 0xc0, 0x02, 0x71, + 0x60, 0x99, 0x62, 0xc1, 0x03, 0xe0, 0x5f, 0xc0, + 0x60, 0xc1, 0x02, 0x99, 0x00, 0x61, 0x0f, 0x1b, + 0x59, 0x41, 0x03, 0x13, 0x18, 0xf1, 0xe4, 0x49, + 0x20, 0xf1, 0xe5, 0x49, 0x1e, 0xf0, 0x59, 0xc6, + 0xd0, 0x73, 0xb7, 0x49, 0x08, 0xf0, 0x01, 0x0b, + 0x80, 0x13, 0x03, 0xf0, 0xd0, 0x8b, 0x03, 0xe0, + 0x3f, 0x48, 0xd0, 0x9b, 0x51, 0xc0, 0x10, 0x1a, + 0x84, 0x1b, 0xb1, 0xe8, 0x4b, 0xc2, 0x40, 0x63, + 0x30, 0x48, 0x0a, 0xe0, 0xe5, 0x49, 0x09, 0xf0, + 0x47, 0xc0, 0x00, 0x1a, 0x84, 0x1b, 0xa7, 0xe8, + 0x41, 0xc2, 0x40, 0x63, 0xb0, 0x48, 0x40, 0x8b, + 0x67, 0x11, 0x3f, 0xf1, 0x69, 0x33, 0x32, 0xc0, + 0x28, 0x40, 0xd2, 0xf1, 0x33, 0xc0, 0x00, 0x19, + 0x81, 0x1b, 0x99, 0xe8, 0x30, 0xc0, 0x04, 0x1a, + 0x84, 0x1b, 0x95, 0xe8, 0x8a, 0xe8, 0xa3, 0x49, + 0xfe, 0xf0, 0x2a, 0xc0, 0x86, 0xe8, 0xa1, 0x48, + 0x84, 0x1b, 0x8d, 0xe8, 0x00, 0x1d, 0x69, 0x33, + 0x00, 0x1e, 0x01, 0x06, 0xff, 0x18, 0x30, 0x40, + 0xfd, 0xf1, 0x1f, 0xc0, 0x00, 0x76, 0x2e, 0x40, + 0xf7, 0xf1, 0x21, 0x48, 0x19, 0xc0, 0x84, 0x1b, + 0x7e, 0xe8, 0x74, 0x08, 0x72, 0xe8, 0xa1, 0x49, + 0xfd, 0xf0, 0x11, 0xc0, 0x00, 0x1a, 0x84, 0x1b, + 0x76, 0xe8, 0x6b, 0xe8, 0xa5, 0x49, 0xfe, 0xf0, + 0x09, 0xc0, 0x01, 0x19, 0x81, 0x1b, 0x6f, 0xe8, + 0x5a, 0xe0, 0xb8, 0x0b, 0x50, 0xe8, 0x83, 0x00, + 0x82, 0x00, 0x20, 0xb4, 0x10, 0xd8, 0x84, 0xd4, + 0x88, 0xd3, 0x10, 0xe0, 0x00, 0xd8, 0x24, 0xd4, + 0xf9, 0xc0, 0x57, 0xe8, 0x48, 0x33, 0xf3, 0xc0, + 0x00, 0x61, 0x6a, 0xc0, 0x47, 0x11, 0x03, 0xf0, + 0x57, 0x11, 0x05, 0xf1, 0x00, 0x61, 0x17, 0x48, + 0x00, 0x89, 0x41, 0xe0, 0x9c, 0x20, 0x9c, 0x24, + 0xd0, 0x49, 0x09, 0xf0, 0x04, 0x11, 0x07, 0xf1, + 0x00, 0x61, 0x97, 0x49, 0x38, 0xf0, 0x97, 0x48, + 0x00, 0x89, 0x2b, 0xe0, 0x00, 0x11, 0x05, 0xf1, + 0x00, 0x61, 0x92, 0x48, 0x00, 0x89, 0x2f, 0xe0, + 0x06, 0x11, 0x05, 0xf1, 0x00, 0x61, 0x11, 0x48, + 0x00, 0x89, 0x29, 0xe0, 0x05, 0x11, 0x0f, 0xf1, + 0x00, 0x61, 0x93, 0x49, 0x1a, 0xf1, 0x91, 0x49, + 0x0a, 0xf0, 0x91, 0x48, 0x00, 0x89, 0x0f, 0xe0, + 0xc6, 0xc0, 0x00, 0x61, 0x98, 0x20, 0x98, 0x24, + 0x25, 0x11, 0x80, 0xff, 0xfa, 0xef, 0x17, 0xf1, + 0x38, 0xc0, 0x1f, 0xe8, 0x95, 0x49, 0x13, 0xf0, + 0xf4, 0xef, 0x11, 0xf1, 0x31, 0xc0, 0x00, 0x61, + 0x92, 0x49, 0x0d, 0xf1, 0x12, 0x48, 0x00, 0x89, + 0x29, 0xc0, 0x00, 0x19, 0x00, 0x89, 0x27, 0xc0, + 0x01, 0x89, 0x23, 0xc0, 0x0e, 0xe8, 0x12, 0x48, + 0x81, 0x1b, 0x15, 0xe8, 0xae, 0xc3, 0x66, 0x62, + 0xa0, 0x49, 0x04, 0xf0, 0x64, 0x71, 0xa3, 0xc0, + 0x02, 0x99, 0x02, 0xc0, 0x00, 0xb8, 0xd6, 0x07, + 0x13, 0xc4, 0x84, 0x98, 0x00, 0x1b, 0x86, 0x8b, + 0x86, 0x73, 0xbf, 0x49, 0xfe, 0xf1, 0x80, 0x71, + 0x82, 0x72, 0x80, 0xff, 0x09, 0xc4, 0x84, 0x98, + 0x80, 0x99, 0x82, 0x9a, 0x86, 0x8b, 0x86, 0x73, + 0xbf, 0x49, 0xfe, 0xf1, 0x80, 0xff, 0x08, 0xea, + 0x30, 0xd4, 0x10, 0xc0, 0x12, 0xe8, 0x8a, 0xd3, + 0x00, 0xd8, 0x02, 0xc6, 0x00, 0xbe, 0xe0, 0x08 }; static u16 r8153_pla_patch_c_bp[] = { 0xfc26, 0x8000, 0xfc28, 0x1306, 0xfc2a, 0x17ca, 0xfc2c, 0x171e, 0xfc2e, 0x0000, 0xfc30, 0x0000, 0xfc32, 0x01b4, 0xfc34, 0x07d4, - 0xfc36, 0x0894, 0xfc38, 0x00e7 }; + 0xfc36, 0x0894, 0xfc38, 0x00e6 }; static u16 r8153_ram_code_bc[] = { 0xB436, 0xB820, 0xB438, 0x0290, 0xB436, 0xA012, 0xB438, 0x0000, @@ -560,7 +529,7 @@ static u16 r8153_usb_patch_b_bp[] = { static u8 r8153_pla_patch_b[] = { 0x08, 0xe0, 0xea, 0xe0, 0xf2, 0xe0, 0x04, 0xe1, - 0x09, 0xe1, 0x0e, 0xe1, 0x46, 0xe1, 0xf3, 0xe1, + 0x09, 0xe1, 0x0e, 0xe1, 0x46, 0xe1, 0xf7, 0xe1, 0x14, 0xc2, 0x40, 0x73, 0xba, 0x48, 0x40, 0x9b, 0x11, 0xc2, 0x40, 0x73, 0xb0, 0x49, 0x17, 0xf0, 0xbf, 0x49, 0x03, 0xf1, 0x09, 0xc5, 0x00, 0xbd, @@ -642,51 +611,51 @@ static u8 r8153_pla_patch_b[] = { 0x0b, 0xc5, 0x20, 0x1e, 0xa0, 0x9e, 0xe5, 0x48, 0xa0, 0x9e, 0xf0, 0xe7, 0xbc, 0xc0, 0xc8, 0xd2, 0xcc, 0xd2, 0x28, 0xe4, 0xe6, 0x01, 0xf0, 0xc0, - 0x18, 0x89, 0x00, 0x1d, 0x3c, 0xc3, 0x60, 0x71, + 0x18, 0x89, 0x00, 0x1d, 0x3c, 0xc3, 0x64, 0x71, 0x3c, 0xc0, 0x02, 0x99, 0x00, 0x61, 0x67, 0x11, 0x3c, 0xf1, 0x69, 0x33, 0x35, 0xc0, 0x28, 0x40, 0xf6, 0xf1, 0x34, 0xc0, 0x00, 0x19, 0x81, 0x1b, - 0x8c, 0xe8, 0x31, 0xc0, 0x04, 0x1a, 0x84, 0x1b, - 0x88, 0xe8, 0x7d, 0xe8, 0xa3, 0x49, 0xfe, 0xf0, - 0x2b, 0xc0, 0x79, 0xe8, 0xa1, 0x48, 0x28, 0xc0, - 0x84, 0x1b, 0x7f, 0xe8, 0x00, 0x1d, 0x69, 0x33, + 0x91, 0xe8, 0x31, 0xc0, 0x04, 0x1a, 0x84, 0x1b, + 0x8d, 0xe8, 0x82, 0xe8, 0xa3, 0x49, 0xfe, 0xf0, + 0x2b, 0xc0, 0x7e, 0xe8, 0xa1, 0x48, 0x28, 0xc0, + 0x84, 0x1b, 0x84, 0xe8, 0x00, 0x1d, 0x69, 0x33, 0x00, 0x1e, 0x01, 0x06, 0xff, 0x18, 0x30, 0x40, - 0xfd, 0xf1, 0x18, 0xc0, 0x00, 0x76, 0x2e, 0x40, + 0xfd, 0xf1, 0x19, 0xc0, 0x00, 0x76, 0x2e, 0x40, 0xf7, 0xf1, 0x21, 0x48, 0x19, 0xc0, 0x84, 0x1b, - 0x70, 0xe8, 0x79, 0xc0, 0x64, 0xe8, 0xa1, 0x49, + 0x75, 0xe8, 0x10, 0xc0, 0x69, 0xe8, 0xa1, 0x49, 0xfd, 0xf0, 0x11, 0xc0, 0x00, 0x1a, 0x84, 0x1b, - 0x68, 0xe8, 0x5d, 0xe8, 0xa5, 0x49, 0xfe, 0xf0, - 0x09, 0xc0, 0x01, 0x19, 0x81, 0x1b, 0x61, 0xe8, - 0x4f, 0xe0, 0x88, 0xd3, 0x8c, 0xd3, 0xb8, 0x0b, + 0x6d, 0xe8, 0x62, 0xe8, 0xa5, 0x49, 0xfe, 0xf0, + 0x09, 0xc0, 0x01, 0x19, 0x81, 0x1b, 0x66, 0xe8, + 0x54, 0xe0, 0x10, 0xd4, 0x88, 0xd3, 0xb8, 0x0b, 0x50, 0xe8, 0x20, 0xb4, 0x10, 0xd8, 0x84, 0xd4, - 0xfc, 0xc0, 0x00, 0x61, 0x9c, 0x20, 0x9c, 0x24, - 0x06, 0x11, 0x06, 0xf1, 0x60, 0xc0, 0x00, 0x61, - 0x11, 0x48, 0x00, 0x89, 0x3d, 0xe0, 0x00, 0x11, - 0x02, 0xf1, 0x03, 0xe0, 0x04, 0x11, 0x06, 0xf1, - 0x56, 0xc0, 0x00, 0x61, 0x92, 0x48, 0x00, 0x89, - 0x33, 0xe0, 0x05, 0x11, 0x08, 0xf1, 0x4f, 0xc0, - 0x00, 0x61, 0x91, 0x49, 0x04, 0xf0, 0x91, 0x48, - 0x00, 0x89, 0x11, 0xe0, 0xde, 0xc0, 0x00, 0x61, - 0x98, 0x20, 0x98, 0x24, 0x25, 0x11, 0x24, 0xf1, - 0x45, 0xc0, 0x29, 0xe8, 0x95, 0x49, 0x20, 0xf0, - 0xd4, 0xc0, 0x00, 0x61, 0x98, 0x20, 0x98, 0x24, - 0x25, 0x11, 0x1a, 0xf1, 0x38, 0xc0, 0x00, 0x61, - 0x92, 0x49, 0x16, 0xf1, 0x12, 0x48, 0x00, 0x89, - 0x30, 0xc0, 0x00, 0x19, 0x00, 0x89, 0x2e, 0xc0, - 0x01, 0x89, 0x2e, 0xc0, 0x04, 0x19, 0x81, 0x1b, - 0x1c, 0xe8, 0x2b, 0xc0, 0x14, 0x19, 0x81, 0x1b, - 0x18, 0xe8, 0x22, 0xc0, 0x0c, 0xe8, 0x20, 0xc0, - 0x12, 0x48, 0x81, 0x1b, 0x12, 0xe8, 0xb3, 0xc3, - 0x62, 0x71, 0xb3, 0xc0, 0x02, 0x99, 0x02, 0xc0, - 0x00, 0xb8, 0x96, 0x07, 0x13, 0xc4, 0x84, 0x98, - 0x00, 0x1b, 0x86, 0x8b, 0x86, 0x73, 0xbf, 0x49, - 0xfe, 0xf1, 0x80, 0x71, 0x82, 0x72, 0x80, 0xff, - 0x09, 0xc4, 0x84, 0x98, 0x80, 0x99, 0x82, 0x9a, - 0x86, 0x8b, 0x86, 0x73, 0xbf, 0x49, 0xfe, 0xf1, - 0x80, 0xff, 0x08, 0xea, 0x10, 0xd4, 0x30, 0xd4, + 0xfd, 0xc0, 0x52, 0xe8, 0x48, 0x33, 0xf9, 0xc0, + 0x00, 0x61, 0x9c, 0x20, 0x9c, 0x24, 0xd0, 0x49, + 0x04, 0xf0, 0x04, 0x11, 0x02, 0xf1, 0x03, 0xe0, + 0x00, 0x11, 0x06, 0xf1, 0x5c, 0xc0, 0x00, 0x61, + 0x92, 0x48, 0x00, 0x89, 0x3a, 0xe0, 0x06, 0x11, + 0x06, 0xf1, 0x55, 0xc0, 0x00, 0x61, 0x11, 0x48, + 0x00, 0x89, 0x33, 0xe0, 0x05, 0x11, 0x08, 0xf1, + 0x4e, 0xc0, 0x00, 0x61, 0x91, 0x49, 0x04, 0xf0, + 0x91, 0x48, 0x00, 0x89, 0x11, 0xe0, 0xd9, 0xc0, + 0x00, 0x61, 0x98, 0x20, 0x98, 0x24, 0x25, 0x11, + 0x24, 0xf1, 0x44, 0xc0, 0x29, 0xe8, 0x95, 0x49, + 0x20, 0xf0, 0xcf, 0xc0, 0x00, 0x61, 0x98, 0x20, + 0x98, 0x24, 0x25, 0x11, 0x1a, 0xf1, 0x37, 0xc0, + 0x00, 0x61, 0x92, 0x49, 0x16, 0xf1, 0x12, 0x48, + 0x00, 0x89, 0x2f, 0xc0, 0x00, 0x19, 0x00, 0x89, + 0x2d, 0xc0, 0x01, 0x89, 0x2d, 0xc0, 0x04, 0x19, + 0x81, 0x1b, 0x1c, 0xe8, 0x2a, 0xc0, 0x14, 0x19, + 0x81, 0x1b, 0x18, 0xe8, 0x21, 0xc0, 0x0c, 0xe8, + 0x1f, 0xc0, 0x12, 0x48, 0x81, 0x1b, 0x12, 0xe8, + 0xae, 0xc3, 0x66, 0x71, 0xae, 0xc0, 0x02, 0x99, + 0x02, 0xc0, 0x00, 0xb8, 0x96, 0x07, 0x13, 0xc4, + 0x84, 0x98, 0x00, 0x1b, 0x86, 0x8b, 0x86, 0x73, + 0xbf, 0x49, 0xfe, 0xf1, 0x80, 0x71, 0x82, 0x72, + 0x80, 0xff, 0x09, 0xc4, 0x84, 0x98, 0x80, 0x99, + 0x82, 0x9a, 0x86, 0x8b, 0x86, 0x73, 0xbf, 0x49, + 0xfe, 0xf1, 0x80, 0xff, 0x08, 0xea, 0x30, 0xd4, 0x10, 0xc0, 0x12, 0xe8, 0x8a, 0xd3, 0x28, 0xe4, - 0x2c, 0xe4, 0x00, 0xd8, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + 0x2c, 0xe4, 0x00, 0xd8, 0x00, 0x00, 0x00, 0x00 }; static u16 r8153_pla_patch_b_bp[] = { 0xfc26, 0x8000, 0xfc28, 0x1154, 0xfc2a, 0x1606, 0xfc2c, 0x155a, @@ -694,33 +663,71 @@ static u16 r8153_pla_patch_b_bp[] = { 0xfc36, 0x0000, 0xfc38, 0x007f }; static u16 r8153_ram_code_d[] = { - 0xa436, 0xb820, 0xa438, 0x0290, 0xa436, 0xa012, 0xa438, 0x0000, - 0xa436, 0xa014, 0xa438, 0x2c04, 0xb438, 0x2c07, 0xb438, 0x2c07, - 0xb438, 0x2c07, 0xb438, 0xa240, 0xb438, 0xa104, 0xb438, 0x2944, - 0xa436, 0xa01a, 0xa438, 0x0000, 0xa436, 0xa006, 0xa438, 0x0fff, - 0xa436, 0xa004, 0xa438, 0x0fff, 0xa436, 0xa002, 0xa438, 0x0fff, - 0xa436, 0xa000, 0xa438, 0x1943, 0xa436, 0xb820, 0xa438, 0x0210 }; + 0xB436, 0xB820, 0xB438, 0x0290, 0xB436, 0xA012, 0xB438, 0x0000, + 0xB436, 0xA014, 0xB438, 0x2c04, 0xB438, 0x2c07, 0xB438, 0x2c07, + 0xB438, 0x2c07, 0xB438, 0xa240, 0xB438, 0xa104, 0xB438, 0x2944, + 0xB436, 0xA01A, 0xB438, 0x0000, 0xB436, 0xA006, 0xB438, 0x0fff, + 0xB436, 0xA004, 0xB438, 0x0fff, 0xB436, 0xA002, 0xB438, 0x0fff, + 0xB436, 0xA000, 0xB438, 0x1943, 0xB436, 0xB820, 0xB438, 0x0210 }; static u8 usb_patch_d[] = { - 0x08, 0xe0, 0x0a, 0xe0, 0x0c, 0xe0, 0x1f, 0xe0, - 0x28, 0xe0, 0x2a, 0xe0, 0x2c, 0xe0, 0x2e, 0xe0, - 0x02, 0xc5, 0x00, 0xbd, 0x00, 0x00, 0x02, 0xc3, - 0x00, 0xbb, 0x00, 0x00, 0x30, 0x18, 0x11, 0xc1, - 0x05, 0xe8, 0x10, 0xc6, 0x02, 0xc2, 0x00, 0xba, - 0x94, 0x17, 0x02, 0xb4, 0x09, 0xc2, 0x40, 0x99, - 0x0e, 0x48, 0x42, 0x98, 0x42, 0x70, 0x8e, 0x49, - 0xfe, 0xf1, 0x02, 0xb0, 0x80, 0xff, 0xc0, 0xd4, - 0xe4, 0x40, 0x20, 0xd4, 0xb0, 0x49, 0x04, 0xf0, - 0x30, 0x18, 0x06, 0xc1, 0xef, 0xef, 0xfa, 0xc7, - 0x02, 0xc0, 0x00, 0xb8, 0x38, 0x12, 0xe4, 0x4b, - 0x02, 0xc3, 0x00, 0xbb, 0x00, 0x00, 0x02, 0xc5, - 0x00, 0xbd, 0x00, 0x00, 0x02, 0xc1, 0x00, 0xb9, - 0x00, 0x00, 0x02, 0xc1, 0x00, 0xb9, 0x00, 0x00 }; + 0x08, 0xe0, 0x0e, 0xe0, 0x11, 0xe0, 0x24, 0xe0, + 0x2b, 0xe0, 0x33, 0xe0, 0x3a, 0xe0, 0x3c, 0xe0, + 0x1e, 0xc3, 0x70, 0x61, 0x12, 0x48, 0x70, 0x89, + 0x02, 0xc3, 0x00, 0xbb, 0x02, 0x17, 0x32, 0x19, + 0x02, 0xc3, 0x00, 0xbb, 0x44, 0x14, 0x30, 0x18, + 0x11, 0xc1, 0x05, 0xe8, 0x10, 0xc6, 0x02, 0xc2, + 0x00, 0xba, 0x94, 0x17, 0x02, 0xb4, 0x09, 0xc2, + 0x40, 0x99, 0x0e, 0x48, 0x42, 0x98, 0x42, 0x70, + 0x8e, 0x49, 0xfe, 0xf1, 0x02, 0xb0, 0x80, 0xff, + 0xc0, 0xd4, 0xe4, 0x40, 0x20, 0xd4, 0x30, 0x18, + 0x06, 0xc1, 0xf1, 0xef, 0xfc, 0xc7, 0x02, 0xc0, + 0x00, 0xb8, 0x38, 0x12, 0xe4, 0x4b, 0x0c, 0x61, + 0x92, 0x48, 0x93, 0x48, 0x95, 0x48, 0x96, 0x48, + 0x0c, 0x89, 0x02, 0xc0, 0x00, 0xb8, 0x0e, 0x06, + 0x30, 0x18, 0xf5, 0xc1, 0xe0, 0xef, 0x04, 0xc5, + 0x02, 0xc4, 0x00, 0xbc, 0x76, 0x3c, 0x1e, 0xfc, + 0x02, 0xc6, 0x00, 0xbe, 0x00, 0x00, 0x02, 0xc6, + 0x00, 0xbe, 0x00, 0x00 }; static u16 r8153_usb_patch_d_bp[] = { - 0xfc26, 0xa000, 0xfc28, 0x0000, 0xfc2a, 0x0000, 0xfc2c, 0x1792, - 0xfc2e, 0x1236, 0xfc30, 0x0000, 0xfc32, 0x0000, 0xfc34, 0x0000, - 0xfc36, 0x0000, 0xfc38, 0x000c }; + 0xfc26, 0xa000, 0xfc28, 0x16de, 0xfc2a, 0x1442, 0xfc2c, 0x1792, + 0xfc2e, 0x1236, 0xfc30, 0x0606, 0xfc32, 0x3c74, 0xfc34, 0x0000, + 0xfc36, 0x0000, 0xfc38, 0x003e }; + +static u8 pla_patch_d[] = { + 0x03, 0xe0, 0x16, 0xe0, 0x30, 0xe0, 0x12, 0xc2, + 0x40, 0x73, 0xb0, 0x49, 0x08, 0xf0, 0xb8, 0x49, + 0x06, 0xf0, 0xb8, 0x48, 0x40, 0x9b, 0x0b, 0xc2, + 0x40, 0x76, 0x05, 0xe0, 0x02, 0x61, 0x02, 0xc3, + 0x00, 0xbb, 0x54, 0x08, 0x02, 0xc3, 0x00, 0xbb, + 0x64, 0x08, 0x98, 0xd3, 0x1e, 0xfc, 0xfe, 0xc0, + 0x02, 0x62, 0xa0, 0x48, 0x02, 0x8a, 0x00, 0x72, + 0xa0, 0x49, 0x11, 0xf0, 0x13, 0xc1, 0x20, 0x62, + 0x2e, 0x21, 0x2f, 0x25, 0x00, 0x71, 0x9f, 0x24, + 0x0a, 0x40, 0x09, 0xf0, 0x00, 0x71, 0x18, 0x48, + 0xa0, 0x49, 0x03, 0xf1, 0x9f, 0x48, 0x02, 0xe0, + 0x1f, 0x48, 0x00, 0x99, 0x02, 0xc2, 0x00, 0xba, + 0xac, 0x0c, 0x08, 0xe9, 0x36, 0xc0, 0x00, 0x61, + 0x9c, 0x20, 0x9c, 0x24, 0x33, 0xc0, 0x07, 0x11, + 0x05, 0xf1, 0x00, 0x61, 0x17, 0x48, 0x00, 0x89, + 0x0d, 0xe0, 0x04, 0x11, 0x0b, 0xf1, 0x00, 0x61, + 0x97, 0x49, 0x08, 0xf0, 0x97, 0x48, 0x00, 0x89, + 0x23, 0xc0, 0x0e, 0xe8, 0x12, 0x48, 0x81, 0x1b, + 0x15, 0xe8, 0x1f, 0xc0, 0x00, 0x61, 0x67, 0x11, + 0x04, 0xf0, 0x02, 0xc0, 0x00, 0xb8, 0x42, 0x09, + 0x02, 0xc0, 0x00, 0xb8, 0x90, 0x08, 0x13, 0xc4, + 0x84, 0x98, 0x00, 0x1b, 0x86, 0x8b, 0x86, 0x73, + 0xbf, 0x49, 0xfe, 0xf1, 0x80, 0x71, 0x82, 0x72, + 0x80, 0xff, 0x09, 0xc4, 0x84, 0x98, 0x80, 0x99, + 0x82, 0x9a, 0x86, 0x8b, 0x86, 0x73, 0xbf, 0x49, + 0xfe, 0xf1, 0x80, 0xff, 0x08, 0xea, 0x30, 0xd4, + 0x50, 0xe8, 0x8a, 0xd3 }; + +static u16 r8153_pla_patch_d_bp[] = { + 0xfc26, 0x8000, 0xfc28, 0x0852, 0xfc2a, 0x0c92, 0xfc2c, 0x088c, + 0xfc2e, 0x0000, 0xfc30, 0x0000, 0xfc32, 0x0000, 0xfc34, 0x0000, + 0xfc36, 0x0000, 0xfc38, 0x0007 }; static void rtl_clear_bp(struct r8152 *tp) { @@ -956,10 +963,19 @@ void r8153_firmware(struct r8152 *tp) ocp_write_word(tp, MCU_TYPE_PLA, 0xd388, 0x08ca); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, + U3P3_CHECK_EN | 4); + ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xcfca); ocp_data |= 0x4000; ocp_write_word(tp, MCU_TYPE_USB, 0xcfca, ocp_data); + + ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_USB2PHY); + ocp_data |= USB2PHY_L1 | USB2PHY_SUSPEND; + ocp_write_byte(tp, MCU_TYPE_USB, USB_USB2PHY, ocp_data); } else if (tp->version == RTL_VER_06) { + u32 ocp_data; + r8153_pre_ram_code(tp, 0x7002); for (i = 0; i < ARRAY_SIZE(r8153_ram_code_d); i += 2) @@ -979,5 +995,22 @@ void r8153_firmware(struct r8152 *tp) ocp_write_word(tp, MCU_TYPE_USB, r8153_usb_patch_d_bp[i], r8153_usb_patch_d_bp[i+1]); + + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, 0x0000); + generic_ocp_write(tp, 0xf800, 0xff, sizeof(pla_patch_d), + pla_patch_d, MCU_TYPE_PLA); + + for (i = 0; i < ARRAY_SIZE(r8153_pla_patch_d_bp); i += 2) + ocp_write_word(tp, MCU_TYPE_PLA, + r8153_pla_patch_d_bp[i], + r8153_pla_patch_d_bp[i + 1]); + + ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_USB2PHY); + ocp_data |= USB2PHY_L1 | USB2PHY_SUSPEND; + ocp_write_byte(tp, MCU_TYPE_USB, USB_USB2PHY, ocp_data); + + ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN1); + ocp_data |= FW_IP_RESET_EN; + ocp_write_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN1, ocp_data); } } |