From: Tom Rini Date: Tue, 5 Jan 2021 21:20:26 +0000 (-0500) Subject: Merge tag 'v2021.01-rc5' into next X-Git-Url: http://git.dujemihanovic.xyz/img/sics.gif?a=commitdiff_plain;h=720620e6916ba40b9a173bb07706d2c73f3c23e7;p=u-boot.git Merge tag 'v2021.01-rc5' into next Prepare v2021.01-rc5 Signed-off-by: Tom Rini --- 720620e6916ba40b9a173bb07706d2c73f3c23e7 diff --cc drivers/i2c/mxc_i2c.c index cbc2bbf5d3,d486dab043..0362ec6763 --- a/drivers/i2c/mxc_i2c.c +++ b/drivers/i2c/mxc_i2c.c @@@ -954,8 -954,8 +954,8 @@@ static int mxc_i2c_probe(struct udevic !dm_gpio_is_valid(&i2c_bus->scl_gpio) || ret || ret2) { dev_err(bus, - "i2c bus %d at %lu, fail to request scl/sda gpio\n", + "i2c bus %d at 0x%2lx, fail to request scl/sda gpio\n", - bus->seq, i2c_bus->base); + dev_seq(bus), i2c_bus->base); return -EINVAL; } } diff --cc drivers/spi/designware_spi.c index 4fa4585fc3,ce74ac0abc..88e638c950 --- a/drivers/spi/designware_spi.c +++ b/drivers/spi/designware_spi.c @@@ -153,11 -228,13 +228,13 @@@ static int request_gpio_cs(struct udevi return 0; } -static int dw_spi_ofdata_to_platdata(struct udevice *bus) +static int dw_spi_of_to_plat(struct udevice *bus) { - struct dw_spi_platdata *plat = bus->platdata; + struct dw_spi_plat *plat = bus->plat; plat->regs = dev_read_addr_ptr(bus); + if (!plat->regs) + return -EINVAL; /* Use 500KHz as a suitable default */ plat->frequency = dev_read_u32_default(bus, "spi-max-frequency", @@@ -261,11 -337,15 +337,15 @@@ static int dw_spi_reset(struct udevice return 0; } + typedef int (*dw_spi_init_t)(struct udevice *bus, struct dw_spi_priv *priv); + static int dw_spi_probe(struct udevice *bus) { + dw_spi_init_t init = (dw_spi_init_t)dev_get_driver_data(bus); - struct dw_spi_platdata *plat = dev_get_platdata(bus); + struct dw_spi_plat *plat = dev_get_plat(bus); struct dw_spi_priv *priv = dev_get_priv(bus); int ret; + u32 version; priv->regs = plat->regs; priv->freq = plat->frequency; @@@ -476,9 -562,110 +562,110 @@@ static int dw_spi_xfer(struct udevice * return ret; } + /* + * This function is necessary for reading SPI flash with the native CS + * c.f. https://lkml.org/lkml/2015/12/23/132 + */ + static int dw_spi_exec_op(struct spi_slave *slave, const struct spi_mem_op *op) + { + bool read = op->data.dir == SPI_MEM_DATA_IN; + int pos, i, ret = 0; + struct udevice *bus = slave->dev->parent; + struct dw_spi_priv *priv = dev_get_priv(bus); + u8 op_len = sizeof(op->cmd.opcode) + op->addr.nbytes + op->dummy.nbytes; + u8 op_buf[op_len]; + u32 cr0; + + if (read) + priv->tmode = CTRLR0_TMOD_EPROMREAD; + else + priv->tmode = CTRLR0_TMOD_TO; + + cr0 = priv->update_cr0(priv); + dev_dbg(bus, "cr0=%08x buf=%p len=%u [bytes]\n", cr0, op->data.buf.in, + op->data.nbytes); + + dw_write(priv, DW_SPI_SSIENR, 0); + dw_write(priv, DW_SPI_CTRLR0, cr0); + if (read) + dw_write(priv, DW_SPI_CTRLR1, op->data.nbytes - 1); + dw_write(priv, DW_SPI_SSIENR, 1); + + /* From spi_mem_exec_op */ + pos = 0; + op_buf[pos++] = op->cmd.opcode; + if (op->addr.nbytes) { + for (i = 0; i < op->addr.nbytes; i++) + op_buf[pos + i] = op->addr.val >> + (8 * (op->addr.nbytes - i - 1)); + + pos += op->addr.nbytes; + } + if (op->dummy.nbytes) + memset(op_buf + pos, 0xff, op->dummy.nbytes); + + external_cs_manage(slave->dev, false); + + priv->tx = &op_buf; + priv->tx_end = priv->tx + op_len; + priv->rx = NULL; + priv->rx_end = NULL; + while (priv->tx != priv->tx_end) + dw_writer(priv); + + /* + * XXX: The following are tight loops! Enabling debug messages may cause + * them to fail because we are not reading/writing the fifo fast enough. + */ + if (read) { + priv->rx = op->data.buf.in; + priv->rx_end = priv->rx + op->data.nbytes; + + dw_write(priv, DW_SPI_SER, 1 << spi_chip_select(slave->dev)); + while (priv->rx != priv->rx_end) + dw_reader(priv); + } else { + u32 val; + + priv->tx = op->data.buf.out; + priv->tx_end = priv->tx + op->data.nbytes; + + /* Fill up the write fifo before starting the transfer */ + dw_writer(priv); + dw_write(priv, DW_SPI_SER, 1 << spi_chip_select(slave->dev)); + while (priv->tx != priv->tx_end) + dw_writer(priv); + + if (readl_poll_timeout(priv->regs + DW_SPI_SR, val, + (val & SR_TF_EMPT) && !(val & SR_BUSY), + RX_TIMEOUT * 1000)) { + ret = -ETIMEDOUT; + } + } + + dw_write(priv, DW_SPI_SER, 0); + external_cs_manage(slave->dev, true); + + dev_dbg(bus, "%u bytes xfered\n", op->data.nbytes); + return ret; + } + + /* The size of ctrl1 limits data transfers to 64K */ + static int dw_spi_adjust_op_size(struct spi_slave *slave, struct spi_mem_op *op) + { + op->data.nbytes = min(op->data.nbytes, (unsigned int)SZ_64K); + + return 0; + } + + static const struct spi_controller_mem_ops dw_spi_mem_ops = { + .exec_op = dw_spi_exec_op, + .adjust_op_size = dw_spi_adjust_op_size, + }; + static int dw_spi_set_speed(struct udevice *bus, uint speed) { - struct dw_spi_platdata *plat = dev_get_platdata(bus); + struct dw_spi_plat *plat = bus->plat; struct dw_spi_priv *priv = dev_get_priv(bus); u16 clk_div; diff --cc drivers/spi/spi-uclass.c index a392a93aa1,d5a1e3a676..5d801fa54b --- a/drivers/spi/spi-uclass.c +++ b/drivers/spi/spi-uclass.c @@@ -259,10 -259,10 +264,10 @@@ int spi_find_chip_select(struct udevic for (device_find_first_child(bus, &dev); dev; device_find_next_child(&dev)) { - struct dm_spi_slave_platdata *plat; + struct dm_spi_slave_plat *plat; - plat = dev_get_parent_platdata(dev); + plat = dev_get_parent_plat(dev); - debug("%s: plat=%p, cs=%d\n", __func__, plat, plat->cs); + dev_dbg(bus, "%s: plat=%p, cs=%d\n", __func__, plat, plat->cs); if (plat->cs == cs) { *devp = dev; return 0; @@@ -278,9 -278,9 +283,9 @@@ int spi_cs_is_valid(unsigned int busnum struct udevice *bus; int ret; - ret = uclass_find_device_by_seq(UCLASS_SPI, busnum, false, &bus); + ret = uclass_find_device_by_seq(UCLASS_SPI, busnum, &bus); if (ret) { - debug("%s: No bus %d\n", __func__, busnum); + log_debug("%s: No bus %d\n", __func__, busnum); return ret; } @@@ -307,9 -307,9 +312,9 @@@ int spi_find_bus_and_cs(int busnum, in struct udevice *bus, *dev; int ret; - ret = uclass_find_device_by_seq(UCLASS_SPI, busnum, false, &bus); + ret = uclass_find_device_by_seq(UCLASS_SPI, busnum, &bus); if (ret) { - debug("%s: No bus %d\n", __func__, busnum); + log_debug("%s: No bus %d\n", __func__, busnum); return ret; } ret = spi_find_chip_select(bus, cs, &dev); @@@ -351,15 -350,15 +356,15 @@@ int spi_get_bus_and_cs(int busnum, int * SPI flash chip - we will bind to the correct driver. */ if (ret == -ENODEV && drv_name) { - debug("%s: Binding new device '%s', busnum=%d, cs=%d, driver=%s\n", - __func__, dev_name, busnum, cs, drv_name); + dev_dbg(bus, "%s: Binding new device '%s', busnum=%d, cs=%d, driver=%s\n", + __func__, dev_name, busnum, cs, drv_name); ret = device_bind_driver(bus, drv_name, dev_name, &dev); if (ret) { - debug("%s: Unable to bind driver (ret=%d)\n", __func__, - ret); + dev_dbg(bus, "%s: Unable to bind driver (ret=%d)\n", + __func__, ret); return ret; } - plat = dev_get_parent_platdata(dev); + plat = dev_get_parent_plat(dev); plat->cs = cs; if (speed) { plat->max_hz = speed; diff --cc include/spi.h index e81f799650,2d34e4af11..dc3b21132a --- a/include/spi.h +++ b/include/spi.h @@@ -58,13 -45,13 +58,13 @@@ struct dm_spi_bus }; /** - * struct dm_spi_platdata - platform data for all SPI slaves + * struct dm_spi_plat - platform data for all SPI slaves * * This describes a SPI slave, a child device of the SPI bus. To obtain this - * struct from a spi_slave, use dev_get_parent_platdata(dev) or - * dev_get_parent_platdata(slave->dev). + * struct from a spi_slave, use dev_get_parent_plat(dev) or + * dev_get_parent_plat(slave->dev). * - * This data is immuatable. Each time the device is probed, @max_hz and @mode + * This data is immutable. Each time the device is probed, @max_hz and @mode * will be copied to struct spi_slave. * * @cs: Chip select number (0..n-1)