From patchwork Tue Apr 16 16:02:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Raghavendra, Vignesh" X-Patchwork-Id: 1086403 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="X+upLskC"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 44k9Br6jbpz9s4Y for ; Wed, 17 Apr 2019 02:03:16 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 9A4ECC21DC1; Tue, 16 Apr 2019 16:02:59 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 48924C21E0F; Tue, 16 Apr 2019 16:02:45 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 172CBC21E07; Tue, 16 Apr 2019 16:02:29 +0000 (UTC) Received: from fllv0015.ext.ti.com (fllv0015.ext.ti.com [198.47.19.141]) by lists.denx.de (Postfix) with ESMTPS id 207A1C21E1B for ; Tue, 16 Apr 2019 16:02:24 +0000 (UTC) Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id x3GG2Bs0123139; Tue, 16 Apr 2019 11:02:11 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1555430531; bh=bQWMYQUAvcnnkp5MbcsMbOh/ekpeuKMW1u8T2FhnDvo=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=X+upLskCJr4DAfi2fjnr8OFp/5zkM5ksCXuzn4jjxQtdT0Wwl9sg9PyRRICDmr5PC QYAygtujWNhQ35aAyCV5qHR+i79JJtNqNPfsTm4jVE+t/ZbjIiaBQ+r94NRUM2Rdko C9MVamS3magulYRkVU3ZmMGmTbdPEKZFjIvFrw4w= Received: from DFLE105.ent.ti.com (dfle105.ent.ti.com [10.64.6.26]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id x3GG2BF4087053 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 16 Apr 2019 11:02:11 -0500 Received: from DFLE100.ent.ti.com (10.64.6.21) by DFLE105.ent.ti.com (10.64.6.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5; Tue, 16 Apr 2019 11:02:11 -0500 Received: from lelv0326.itg.ti.com (10.180.67.84) by DFLE100.ent.ti.com (10.64.6.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5 via Frontend Transport; Tue, 16 Apr 2019 11:02:11 -0500 Received: from a0132425.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0326.itg.ti.com (8.15.2/8.15.2) with ESMTP id x3GG21A6075038; Tue, 16 Apr 2019 11:02:08 -0500 From: Vignesh Raghavendra To: Jagan Teki , Lokesh Vutla , Nikita Kiryanov Date: Tue, 16 Apr 2019 21:32:00 +0530 Message-ID: <20190416160200.6262-3-vigneshr@ti.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190416160200.6262-1-vigneshr@ti.com> References: <20190416160200.6262-1-vigneshr@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: Tom Rini , u-boot@lists.denx.de Subject: [U-Boot] [RESEND PATCH v2 2/2] spi: ti_qspi: Convert to spi-mem ops X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Convert driver to use spi-mem ops in order to support accelerated MMIO flash interface in generic way and for better performance. Signed-off-by: Vignesh Raghavendra Reviewed-by: Tom Rini --- drivers/spi/ti_qspi.c | 132 ++++++++++++++++++++++-------------------- 1 file changed, 68 insertions(+), 64 deletions(-) diff --git a/drivers/spi/ti_qspi.c b/drivers/spi/ti_qspi.c index 731fb23022d2..77fa17ee8ab1 100644 --- a/drivers/spi/ti_qspi.c +++ b/drivers/spi/ti_qspi.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -40,7 +41,6 @@ DECLARE_GLOBAL_DATA_PTR; #define QSPI_INVAL (4 << 16) #define QSPI_RD_QUAD (7 << 16) /* device control */ -#define QSPI_DD(m, n) (m << (3 + n*8)) #define QSPI_CKPHA(n) (1 << (2 + n*8)) #define QSPI_CSPOL(n) (1 << (1 + n*8)) #define QSPI_CKPOL(n) (1 << (n*8)) @@ -53,18 +53,11 @@ DECLARE_GLOBAL_DATA_PTR; #define MEM_CS(cs) ((cs + 1) << 8) #define MEM_CS_UNSELECT 0xfffff8ff -#define QSPI_CMD_READ (0x3 << 0) -#define QSPI_CMD_READ_DUAL (0x6b << 0) -#define QSPI_CMD_READ_QUAD (0x6c << 0) -#define QSPI_CMD_READ_FAST (0x0b << 0) -#define QSPI_SETUP0_NUM_A_BYTES (0x3 << 8) -#define QSPI_SETUP0_NUM_D_BYTES_NO_BITS (0x0 << 10) -#define QSPI_SETUP0_NUM_D_BYTES_8_BITS (0x1 << 10) #define QSPI_SETUP0_READ_NORMAL (0x0 << 12) #define QSPI_SETUP0_READ_DUAL (0x1 << 12) #define QSPI_SETUP0_READ_QUAD (0x3 << 12) -#define QSPI_CMD_WRITE (0x12 << 16) -#define QSPI_NUM_DUMMY_BITS (0x0 << 24) +#define QSPI_SETUP0_ADDR_SHIFT (8) +#define QSPI_SETUP0_DBITS_SHIFT (10) /* ti qspi register set */ struct ti_qspi_regs { @@ -96,6 +89,7 @@ struct ti_qspi_regs { /* ti qspi priv */ struct ti_qspi_priv { void *memory_map; + size_t mmap_size; uint max_hz; u32 num_cs; struct ti_qspi_regs *base; @@ -171,19 +165,6 @@ static int ti_qspi_xfer(struct udevice *dev, unsigned int bitlen, return -EINVAL; } - /* Setup mmap flags */ - if (flags & SPI_XFER_MMAP) { - writel(MM_SWITCH, &priv->base->memswitch); - if (priv->ctrl_mod_mmap) - ti_qspi_ctrl_mode_mmap(priv->ctrl_mod_mmap, cs, true); - return 0; - } else if (flags & SPI_XFER_MMAP_END) { - writel(~MM_SWITCH, &priv->base->memswitch); - if (priv->ctrl_mod_mmap) - ti_qspi_ctrl_mode_mmap(priv->ctrl_mod_mmap, cs, false); - return 0; - } - if (bitlen == 0) return -1; @@ -269,9 +250,9 @@ static int ti_qspi_xfer(struct udevice *dev, unsigned int bitlen, } /* TODO: control from sf layer to here through dm-spi */ -#if defined(CONFIG_TI_EDMA3) && !defined(CONFIG_DMA) -void spi_flash_copy_mmap(void *data, void *offset, size_t len) +static void ti_qspi_copy_mmap(void *data, void *offset, size_t len) { +#if defined(CONFIG_TI_EDMA3) && !defined(CONFIG_DMA) unsigned int addr = (unsigned int) (data); unsigned int edma_slot_num = 1; @@ -286,44 +267,34 @@ void spi_flash_copy_mmap(void *data, void *offset, size_t len) /* disable edma3 clocks */ disable_edma3_clocks(); +#else + memcpy_fromio(data, offset, len); +#endif *((unsigned int *)offset) += len; } -#endif -static void __ti_qspi_setup_memorymap(struct ti_qspi_priv *priv, - struct spi_slave *slave, - bool enable) +static void ti_qspi_setup_mmap_read(struct ti_qspi_priv *priv, u8 opcode, + u8 data_nbits, u8 addr_width, + u8 dummy_bytes) { - u32 memval; - u32 mode = slave->mode & (SPI_RX_QUAD | SPI_RX_DUAL); + u32 memval = opcode; - if (!enable) { - writel(0, &priv->base->setup0); - return; - } - - memval = QSPI_SETUP0_NUM_A_BYTES | QSPI_CMD_WRITE | QSPI_NUM_DUMMY_BITS; - - switch (mode) { - case SPI_RX_QUAD: - memval |= QSPI_CMD_READ_QUAD; - memval |= QSPI_SETUP0_NUM_D_BYTES_8_BITS; + switch (data_nbits) { + case 4: memval |= QSPI_SETUP0_READ_QUAD; - slave->mode |= SPI_RX_QUAD; break; - case SPI_RX_DUAL: - memval |= QSPI_CMD_READ_DUAL; - memval |= QSPI_SETUP0_NUM_D_BYTES_8_BITS; + case 2: memval |= QSPI_SETUP0_READ_DUAL; break; default: - memval |= QSPI_CMD_READ; - memval |= QSPI_SETUP0_NUM_D_BYTES_NO_BITS; memval |= QSPI_SETUP0_READ_NORMAL; break; } + memval |= ((addr_width - 1) << QSPI_SETUP0_ADDR_SHIFT | + dummy_bytes << QSPI_SETUP0_DBITS_SHIFT); + writel(memval, &priv->base->setup0); } @@ -342,10 +313,39 @@ static int ti_qspi_set_mode(struct udevice *bus, uint mode) return 0; } +static int ti_qspi_exec_mem_op(struct spi_slave *slave, + const struct spi_mem_op *op) +{ + struct ti_qspi_priv *priv; + struct udevice *bus; + + bus = slave->dev->parent; + priv = dev_get_priv(bus); + u32 from = 0; + int ret = 0; + + /* Only optimize read path. */ + if (!op->data.nbytes || op->data.dir != SPI_MEM_DATA_IN || + !op->addr.nbytes || op->addr.nbytes > 4) + return -ENOTSUPP; + + /* Address exceeds MMIO window size, fall back to regular mode. */ + from = op->addr.val; + if (from + op->data.nbytes > priv->mmap_size) + return -ENOTSUPP; + + ti_qspi_setup_mmap_read(priv, op->cmd.opcode, op->data.buswidth, + op->addr.nbytes, op->dummy.nbytes); + + ti_qspi_copy_mmap((void *)op->data.buf.in, + (void *)priv->memory_map + from, op->data.nbytes); + + return ret; +} + static int ti_qspi_claim_bus(struct udevice *dev) { struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); - struct spi_slave *slave = dev_get_parent_priv(dev); struct ti_qspi_priv *priv; struct udevice *bus; @@ -357,7 +357,10 @@ static int ti_qspi_claim_bus(struct udevice *dev) return -EINVAL; } - __ti_qspi_setup_memorymap(priv, slave, true); + writel(MM_SWITCH, &priv->base->memswitch); + if (priv->ctrl_mod_mmap) + ti_qspi_ctrl_mode_mmap(priv->ctrl_mod_mmap, + slave_plat->cs, true); writel(priv->dc, &priv->base->dc); writel(0, &priv->base->cmd); @@ -371,18 +374,22 @@ static int ti_qspi_claim_bus(struct udevice *dev) static int ti_qspi_release_bus(struct udevice *dev) { - struct spi_slave *slave = dev_get_parent_priv(dev); + struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); struct ti_qspi_priv *priv; struct udevice *bus; bus = dev->parent; priv = dev_get_priv(bus); - __ti_qspi_setup_memorymap(priv, slave, false); + writel(~MM_SWITCH, &priv->base->memswitch); + if (priv->ctrl_mod_mmap) + ti_qspi_ctrl_mode_mmap(priv->ctrl_mod_mmap, + slave_plat->cs, false); writel(0, &priv->base->dc); writel(0, &priv->base->cmd); writel(0, &priv->base->data); + writel(0, &priv->base->setup0); return 0; } @@ -440,12 +447,15 @@ 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 = dev_of_offset(bus); + fdt_addr_t mmap_addr; + fdt_addr_t mmap_size; 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); + mmap_addr = devfdt_get_addr_size_index(bus, 1, &mmap_size); + priv->memory_map = map_physmem(mmap_addr, mmap_size, MAP_NOCACHE); + priv->mmap_size = mmap_size; priv->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", -1); if (priv->max_hz < 0) { @@ -460,15 +470,9 @@ static int ti_qspi_ofdata_to_platdata(struct udevice *bus) return 0; } -static int ti_qspi_child_pre_probe(struct udevice *dev) -{ - struct spi_slave *slave = dev_get_parent_priv(dev); - struct udevice *bus = dev_get_parent(dev); - struct ti_qspi_priv *priv = dev_get_priv(bus); - - slave->memory_map = priv->memory_map; - return 0; -} +static const struct spi_controller_mem_ops ti_qspi_mem_ops = { + .exec_op = ti_qspi_exec_mem_op, +}; static const struct dm_spi_ops ti_qspi_ops = { .claim_bus = ti_qspi_claim_bus, @@ -476,6 +480,7 @@ static const struct dm_spi_ops ti_qspi_ops = { .xfer = ti_qspi_xfer, .set_speed = ti_qspi_set_speed, .set_mode = ti_qspi_set_mode, + .mem_ops = &ti_qspi_mem_ops, }; static const struct udevice_id ti_qspi_ids[] = { @@ -492,5 +497,4 @@ U_BOOT_DRIVER(ti_qspi) = { .ofdata_to_platdata = ti_qspi_ofdata_to_platdata, .priv_auto_alloc_size = sizeof(struct ti_qspi_priv), .probe = ti_qspi_probe, - .child_pre_probe = ti_qspi_child_pre_probe, };