summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pci/pcie_dw_mvebu.c37
-rw-r--r--drivers/spi/kirkwood_spi.c67
-rw-r--r--drivers/usb/dwc3/dwc3-generic.c3
-rw-r--r--drivers/usb/musb-new/Kconfig10
-rw-r--r--drivers/usb/musb-new/musb_regs.h3
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, &reg->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