X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=drivers%2Fspi%2Fti_qspi.c;h=bea3aff943196bd3dd8415bd4addb3960534d617;hb=f72b96ec8f7a7b2e2952333c00d907cf0fd726a3;hp=52520dff6325ff3e298502c0bb09a0eb2f9a3171;hpb=cbe7706ab8aab06c18edaa9b120371f9c8012728;p=oweals%2Fu-boot.git diff --git a/drivers/spi/ti_qspi.c b/drivers/spi/ti_qspi.c index 52520dff63..bea3aff943 100644 --- a/drivers/spi/ti_qspi.c +++ b/drivers/spi/ti_qspi.c @@ -16,6 +16,9 @@ #include #include #include +#include +#include +#include DECLARE_GLOBAL_DATA_PTR; @@ -118,21 +121,18 @@ static void ti_spi_set_speed(struct ti_qspi_priv *priv, uint hz) if (!hz) clk_div = 0; else - clk_div = (priv->fclk / hz) - 1; + clk_div = DIV_ROUND_UP(priv->fclk, hz) - 1; + + /* truncate clk_div value to QSPI_CLK_DIV_MAX */ + if (clk_div > QSPI_CLK_DIV_MAX) + clk_div = QSPI_CLK_DIV_MAX; debug("ti_spi_set_speed: hz: %d, clock divider %d\n", hz, clk_div); /* disable SCLK */ writel(readl(&priv->base->clk_ctrl) & ~QSPI_CLK_EN, &priv->base->clk_ctrl); - - /* assign clk_div values */ - if (clk_div < 0) - clk_div = 0; - else if (clk_div > QSPI_CLK_DIV_MAX) - clk_div = QSPI_CLK_DIV_MAX; - - /* enable SCLK */ + /* enable SCLK and program the clk divider */ writel(QSPI_CLK_EN | clk_div, &priv->base->clk_ctrl); } @@ -385,7 +385,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, priv->base = (struct ti_qspi_regs *)QSPI_BASE; priv->mode = mode; -#if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX) +#if defined(CONFIG_DRA7XX) priv->ctrl_mod_mmap = (void *)CORE_CTRL_IO; priv->slave.memory_map = (void *)MMAP_START_ADDR_DRA; priv->fclk = QSPI_DRA7XX_FCLK; @@ -551,21 +551,56 @@ static int ti_qspi_probe(struct udevice *bus) return 0; } +static void *map_syscon_chipselects(struct udevice *bus) +{ +#if CONFIG_IS_ENABLED(SYSCON) + struct udevice *syscon; + struct regmap *regmap; + const fdt32_t *cell; + int len, err; + + err = uclass_get_device_by_phandle(UCLASS_SYSCON, bus, + "syscon-chipselects", &syscon); + if (err) { + debug("%s: unable to find syscon device (%d)\n", __func__, + err); + return NULL; + } + + regmap = syscon_get_regmap(syscon); + if (IS_ERR(regmap)) { + debug("%s: unable to find regmap (%ld)\n", __func__, + PTR_ERR(regmap)); + return NULL; + } + + cell = fdt_getprop(gd->fdt_blob, dev_of_offset(bus), + "syscon-chipselects", &len); + if (len < 2*sizeof(fdt32_t)) { + debug("%s: offset not available\n", __func__); + return NULL; + } + + return fdtdec_get_number(cell + 1, 1) + regmap_get_range(regmap, 0); +#else + fdt_addr_t addr; + addr = devfdt_get_addr_index(bus, 2); + return (addr == FDT_ADDR_T_NONE) ? NULL : + map_physmem(addr, 0, MAP_NOCACHE); +#endif +} + static int ti_qspi_ofdata_to_platdata(struct udevice *bus) { struct ti_qspi_priv *priv = dev_get_priv(bus); const void *blob = gd->fdt_blob; - int node = bus->of_offset; - fdt_addr_t addr; - void *mmap; + int node = dev_of_offset(bus); - priv->base = map_physmem(dev_get_addr(bus), sizeof(struct ti_qspi_regs), - MAP_NOCACHE); - priv->memory_map = map_physmem(dev_get_addr_index(bus, 1), 0, + priv->ctrl_mod_mmap = map_syscon_chipselects(bus); + priv->base = map_physmem(devfdt_get_addr(bus), + sizeof(struct ti_qspi_regs), MAP_NOCACHE); + priv->memory_map = map_physmem(devfdt_get_addr_index(bus, 1), 0, MAP_NOCACHE); - addr = dev_get_addr_index(bus, 2); - mmap = map_physmem(dev_get_addr_index(bus, 2), 0, MAP_NOCACHE); - priv->ctrl_mod_mmap = (addr == FDT_ADDR_T_NONE) ? NULL : mmap; priv->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", -1); if (priv->max_hz < 0) {