diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/pci/pcie_dw_mvebu.c | 37 | ||||
-rw-r--r-- | drivers/spi/kirkwood_spi.c | 67 | ||||
-rw-r--r-- | drivers/usb/dwc3/dwc3-generic.c | 3 | ||||
-rw-r--r-- | drivers/usb/musb-new/Kconfig | 10 | ||||
-rw-r--r-- | drivers/usb/musb-new/musb_regs.h | 3 |
5 files changed, 100 insertions, 20 deletions
diff --git a/drivers/pci/pcie_dw_mvebu.c b/drivers/pci/pcie_dw_mvebu.c index 93e57cf0cf1..0490fd33770 100644 --- a/drivers/pci/pcie_dw_mvebu.c +++ b/drivers/pci/pcie_dw_mvebu.c @@ -115,6 +115,7 @@ struct pcie_dw_mvebu { int first_busno; /* IO and MEM PCI regions */ + int region_count; struct pci_region io; struct pci_region mem; }; @@ -267,9 +268,10 @@ static int pcie_dw_mvebu_read_config(const struct udevice *bus, pci_dev_t bdf, debug("(addr,val)=(0x%04x, 0x%08lx)\n", offset, value); *valuep = pci_conv_32_to_size(value, offset, size); - pcie_dw_prog_outbound_atu(pcie, PCIE_ATU_REGION_INDEX0, - PCIE_ATU_TYPE_IO, pcie->io.phys_start, - pcie->io.bus_start, pcie->io.size); + if (pcie->region_count > 1) + pcie_dw_prog_outbound_atu(pcie, PCIE_ATU_REGION_INDEX0, + PCIE_ATU_TYPE_IO, pcie->io.phys_start, + pcie->io.bus_start, pcie->io.size); return 0; } @@ -312,9 +314,10 @@ static int pcie_dw_mvebu_write_config(struct udevice *bus, pci_dev_t bdf, value = pci_conv_size_to_32(old, value, offset, size); writel(value, va_address); - pcie_dw_prog_outbound_atu(pcie, PCIE_ATU_REGION_INDEX0, - PCIE_ATU_TYPE_IO, pcie->io.phys_start, - pcie->io.bus_start, pcie->io.size); + if (pcie->region_count > 1) + pcie_dw_prog_outbound_atu(pcie, PCIE_ATU_REGION_INDEX0, + PCIE_ATU_TYPE_IO, pcie->io.phys_start, + pcie->io.bus_start, pcie->io.size); return 0; } @@ -513,14 +516,24 @@ static int pcie_dw_mvebu_probe(struct udevice *dev) hose->first_busno); } + pcie->region_count = hose->region_count - CONFIG_NR_DRAM_BANKS; + /* Store the IO and MEM windows settings for future use by the ATU */ - pcie->io.phys_start = hose->regions[0].phys_start; /* IO base */ - pcie->io.bus_start = hose->regions[0].bus_start; /* IO_bus_addr */ - pcie->io.size = hose->regions[0].size; /* IO size */ + if (pcie->region_count > 1) { + /* IO base */ + pcie->io.phys_start = hose->regions[0].phys_start; + /* IO_bus_addr */ + pcie->io.bus_start = hose->regions[0].bus_start; + /* IO size */ + pcie->io.size = hose->regions[0].size; + } - pcie->mem.phys_start = hose->regions[1].phys_start; /* MEM base */ - pcie->mem.bus_start = hose->regions[1].bus_start; /* MEM_bus_addr */ - pcie->mem.size = hose->regions[1].size; /* MEM size */ + /* MEM base */ + pcie->mem.phys_start = hose->regions[pcie->region_count - 1].phys_start; + /* MEM_bus_addr */ + pcie->mem.bus_start = hose->regions[pcie->region_count - 1].bus_start; + /* MEM size */ + pcie->mem.size = hose->regions[pcie->region_count - 1].size; pcie_dw_prog_outbound_atu(pcie, PCIE_ATU_REGION_INDEX1, PCIE_ATU_TYPE_MEM, pcie->mem.phys_start, diff --git a/drivers/spi/kirkwood_spi.c b/drivers/spi/kirkwood_spi.c index 43812da0ebb..bc5da0a1e6e 100644 --- a/drivers/spi/kirkwood_spi.c +++ b/drivers/spi/kirkwood_spi.c @@ -110,13 +110,70 @@ static int _spi_xfer(struct kwspi_registers *reg, unsigned int bitlen, static int mvebu_spi_set_speed(struct udevice *bus, uint hz) { struct mvebu_spi_plat *plat = dev_get_plat(bus); + struct dm_spi_bus *spi = dev_get_uclass_priv(bus); struct kwspi_registers *reg = plat->spireg; - u32 data; + u32 data, divider; + unsigned int spr, sppr; + + if (spi->max_hz && (hz > spi->max_hz)) { + debug("%s: limit speed to the max_hz of the bus %d\n", + __func__, spi->max_hz); + hz = spi->max_hz; + } + + /* + * Calculate spi clock prescaller using max_hz. + * SPPR is SPI Baud Rate Pre-selection, it holds bits 5 and 7:6 in + * SPI Interface Configuration Register; + * SPR is SPI Baud Rate Selection, it holds bits 3:0 in SPI Interface + * Configuration Register. + * The SPR together with the SPPR define the SPI CLK frequency as + * follows: + * SPI actual frequency = core_clk / (SPR * (2 ^ SPPR)) + */ + divider = DIV_ROUND_UP(CONFIG_SYS_TCLK, hz); + if (divider < 16) { + /* This is the easy case, divider is less than 16 */ + spr = divider; + sppr = 0; + + } else { + unsigned int two_pow_sppr; + /* + * Find the highest bit set in divider. This and the + * three next bits define SPR (apart from rounding). + * SPPR is then the number of zero bits that must be + * appended: + */ + sppr = fls(divider) - 4; + + /* + * As SPR only has 4 bits, we have to round divider up + * to the next multiple of 2 ** sppr. + */ + two_pow_sppr = 1 << sppr; + divider = (divider + two_pow_sppr - 1) & -two_pow_sppr; + + /* + * recalculate sppr as rounding up divider might have + * increased it enough to change the position of the + * highest set bit. In this case the bit that now + * doesn't make it into SPR is 0, so there is no need to + * round again. + */ + sppr = fls(divider) - 4; + spr = divider >> sppr; + + /* + * Now do range checking. SPR is constructed to have a + * width of 4 bits, so this is fine for sure. So we + * still need to check for sppr to fit into 3 bits: + */ + if (sppr > 7) + return -EINVAL; + } - /* calculate spi clock prescaller using max_hz */ - data = ((CONFIG_SYS_TCLK / 2) / hz) + 0x10; - data = data < KWSPI_CLKPRESCL_MIN ? KWSPI_CLKPRESCL_MIN : data; - data = data > KWSPI_CLKPRESCL_MASK ? KWSPI_CLKPRESCL_MASK : data; + data = ((sppr & 0x6) << 5) | ((sppr & 0x1) << 4) | spr; /* program spi clock prescaler using max_hz */ writel(KWSPI_ADRLEN_3BYTE | data, ®->cfg); diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c index 30f835e1e3d..c8bf4ae851f 100644 --- a/drivers/usb/dwc3/dwc3-generic.c +++ b/drivers/usb/dwc3/dwc3-generic.c @@ -163,7 +163,8 @@ U_BOOT_DRIVER(dwc3_generic_peripheral) = { }; #endif -#if defined(CONFIG_SPL_USB_HOST_SUPPORT) || !defined(CONFIG_SPL_BUILD) +#if defined(CONFIG_SPL_USB_HOST_SUPPORT) || \ + !defined(CONFIG_SPL_BUILD) && defined(CONFIG_USB_HOST) static int dwc3_generic_host_probe(struct udevice *dev) { struct xhci_hcor *hcor; diff --git a/drivers/usb/musb-new/Kconfig b/drivers/usb/musb-new/Kconfig index 6cf8a2b60b6..fd6f4109b0e 100644 --- a/drivers/usb/musb-new/Kconfig +++ b/drivers/usb/musb-new/Kconfig @@ -89,3 +89,13 @@ config USB_MUSB_PIO_ONLY help All data is copied between memory and FIFO by the CPU. DMA controllers are ignored. + +config USB_MUSB_FIXED_CONFIGDATA + bool "Hardcode MUSB CONFIGDATA register" + depends on USB_MUSB_SUNXI + default n if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I || MACH_SUN7I || MACH_SUN8I_A23 + default y + help + Newer Allwinner SoCs do not implement the MUSB_CONFIGDATA register, + so it always reads 0. Select this option to override this and + return a hardcoded value instead. diff --git a/drivers/usb/musb-new/musb_regs.h b/drivers/usb/musb-new/musb_regs.h index c4d7203b851..e9362f6def3 100644 --- a/drivers/usb/musb-new/musb_regs.h +++ b/drivers/usb/musb-new/musb_regs.h @@ -431,8 +431,7 @@ static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase) static inline u8 musb_read_configdata(void __iomem *mbase) { -#if defined CONFIG_MACH_SUN8I_A33 || defined CONFIG_MACH_SUN8I_A83T || \ - defined CONFIG_MACH_SUNXI_H3_H5 || defined CONFIG_MACH_SUN50I +#ifdef CONFIG_USB_MUSB_FIXED_CONFIGDATA /* <Sigh> allwinner saves a reg, and we need to hardcode this */ return 0xde; #else |