<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>LayerscapeのトピックLS1043A using QSPI to access FPGA</title>
    <link>https://community.nxp.com/t5/Layerscape/LS1043A-using-QSPI-to-access-FPGA/m-p/1279313#M8029</link>
    <description>&lt;P&gt;We develop a custom board based on LS1043A. We want to use QSPIA interface to access the FPGA and the chip select is QSPIA-CS1. I wrote the driver code refer to fsl_qspi.c in u-boot (version 2019.04). But it doesn't work at all. Since i issue the IP command to read data from FPGA, there is nothing output from QSPIA_CLK and QSPIA_CS1. I have already programed&amp;nbsp;&amp;nbsp;the QSPI_SFAR register and written&amp;nbsp;the QSPI_IPCR[SEQID] field to trigger the execution of a new IP Command that prepared in LUT table.&lt;/P&gt;&lt;P&gt;Following is demo driver code:&lt;/P&gt;&lt;P&gt;static void casco_qspi_set_lut(void)&lt;BR /&gt;{&lt;BR /&gt;struct fsl_qspi_regs *regs = casco_qspi_regs;&lt;BR /&gt;u32 lut_base;&lt;/P&gt;&lt;P&gt;/* Unlock the LUT */&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;lutkey, LUT_KEY_VALUE);&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;lckcr, QSPI_LCKCR_UNLOCK);&lt;/P&gt;&lt;P&gt;/* read from FPGA */&lt;BR /&gt;lut_base = SEQID_RDFPGA * 4;&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;lut[lut_base],&lt;BR /&gt;OPRND0(0xEB) | PAD0(LUT_PAD1) |&lt;BR /&gt;INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) |&lt;BR /&gt;PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;lut[lut_base + 1],&lt;BR /&gt;OPRND0(10) | PAD0(LUT_PAD1) | INSTR0(LUT_DUMMY) |&lt;BR /&gt;OPRND1(4) | PAD1(LUT_PAD1) |&lt;BR /&gt;INSTR1(LUT_READ));&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;lut[lut_base + 2], 0);&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;lut[lut_base + 3], 0);&lt;/P&gt;&lt;P&gt;/* write to FPGA */&lt;BR /&gt;lut_base = SEQID_WRFPGA * 4;&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;lut[lut_base],&lt;BR /&gt;OPRND0(0x32) | PAD0(LUT_PAD1) |&lt;BR /&gt;INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) |&lt;BR /&gt;PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;lut[lut_base + 1],&lt;BR /&gt;OPRND0(4) | PAD0(LUT_PAD1) | INSTR0(LUT_WRITE));&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;lut[lut_base + 2], 0);&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;lut[lut_base + 3], 0);&lt;/P&gt;&lt;P&gt;/* Lock the LUT */&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;lutkey, LUT_KEY_VALUE);&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;lckcr, QSPI_LCKCR_LOCK);&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;void casco_qspi_op_read(u32 offset, u32 *rxbuf, u32 len)&lt;BR /&gt;{&lt;BR /&gt;u32 mcr_reg, data;&lt;BR /&gt;int i, size;&lt;BR /&gt;u32 to_or_from;&lt;BR /&gt;u32 seqid;&lt;BR /&gt;struct fsl_qspi_regs *regs = casco_qspi_regs;&lt;BR /&gt;u32 temp = 0;&lt;/P&gt;&lt;P&gt;seqid = SEQID_RDFPGA;&lt;/P&gt;&lt;P&gt;mcr_reg = casco_qspi_read32(casco_qspi_flags, &amp;amp;regs-&amp;gt;mcr);&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;mcr,&lt;BR /&gt;QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |&lt;BR /&gt;QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;rbct, QSPI_RBCT_RXBRD_USEIPS);&lt;/P&gt;&lt;P&gt;to_or_from = casco_qspi_ctrl-&amp;gt;amba_base[0]+offset;&lt;BR /&gt;printf("%s: access address 0x%x\n", __func__, to_or_from);&lt;BR /&gt;if(len &amp;gt; 0x40)&lt;BR /&gt;{&lt;BR /&gt;len = 0x40;&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;while (len &amp;gt; 0) {&lt;/P&gt;&lt;P&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;sfar, to_or_from);&lt;BR /&gt;temp = casco_qspi_read32(casco_qspi_flags, &amp;amp;regs-&amp;gt;sfar);&lt;BR /&gt;printf("%s: reg sfar read 0x%x\n", __func__, temp);&lt;BR /&gt;temp = casco_qspi_read32(casco_qspi_flags, &amp;amp;regs-&amp;gt;sfa1ad);&lt;BR /&gt;printf("%s: reg sfa1ad read 0x%x\n", __func__, temp);&lt;BR /&gt;temp = casco_qspi_read32(casco_qspi_flags, &amp;amp;regs-&amp;gt;sfa2ad);&lt;BR /&gt;printf("%s: reg sfa2ad read 0x%x\n", __func__, temp);&lt;BR /&gt;temp = casco_qspi_read32(casco_qspi_flags, &amp;amp;regs-&amp;gt;sfb1ad);&lt;BR /&gt;printf("%s: reg sfb1ad read 0x%x\n", __func__, temp);&lt;BR /&gt;temp = casco_qspi_read32(casco_qspi_flags, &amp;amp;regs-&amp;gt;sfb2ad);&lt;BR /&gt;printf("%s: reg sfb2ad read 0x%x\n", __func__, temp);&lt;/P&gt;&lt;P&gt;size = (len &amp;gt; RX_BUFFER_SIZE) ?&lt;BR /&gt;RX_BUFFER_SIZE : len;&lt;/P&gt;&lt;P&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;ipcr,&lt;BR /&gt;(seqid &amp;lt;&amp;lt; QSPI_IPCR_SEQID_SHIFT) |&lt;BR /&gt;size);&lt;/P&gt;&lt;P&gt;temp = casco_qspi_read32(casco_qspi_flags, &amp;amp;regs-&amp;gt;lut[seqid &amp;lt;&amp;lt; 2]);&lt;BR /&gt;printf("%s: reg lut[%d] read 0x%x\n", __func__, seqid &amp;lt;&amp;lt; 2, temp);&lt;/P&gt;&lt;P&gt;temp = casco_qspi_read32(casco_qspi_flags, &amp;amp;regs-&amp;gt;fr);&lt;BR /&gt;printf("%s: reg fr read 0x%x\n", __func__, temp);&lt;/P&gt;&lt;P&gt;while (casco_qspi_read32(casco_qspi_flags, &amp;amp;regs-&amp;gt;sr) &amp;amp; QSPI_SR_BUSY_MASK)&lt;BR /&gt;;&lt;BR /&gt;temp = casco_qspi_read32(casco_qspi_flags, &amp;amp;regs-&amp;gt;fr);&lt;BR /&gt;printf("%s: reg fr read 0x%x\n", __func__, temp);&lt;/P&gt;&lt;P&gt;to_or_from += size;&lt;BR /&gt;len -= size;&lt;/P&gt;&lt;P&gt;i = 0;&lt;BR /&gt;while ((RX_BUFFER_SIZE &amp;gt;= size) &amp;amp;&amp;amp; (size &amp;gt; 0)) {&lt;BR /&gt;data = casco_qspi_read32(casco_qspi_flags, &amp;amp;regs-&amp;gt;rbdr[i]);&lt;BR /&gt;data = casco_qspi_endian_xchg(data);&lt;BR /&gt;if (size &amp;lt; 4)&lt;BR /&gt;memcpy(rxbuf, &amp;amp;data, size);&lt;BR /&gt;else&lt;BR /&gt;memcpy(rxbuf, &amp;amp;data, 4);&lt;BR /&gt;rxbuf++;&lt;BR /&gt;size -= 4;&lt;BR /&gt;i++;&lt;BR /&gt;}&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;mcr,&lt;BR /&gt;casco_qspi_read32(casco_qspi_flags, &amp;amp;regs-&amp;gt;mcr) |&lt;BR /&gt;QSPI_MCR_CLR_RXF_MASK);&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;mcr, mcr_reg);&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;int casco_qspi_init(void)&lt;BR /&gt;{&lt;BR /&gt;u32 mcr_val;&lt;BR /&gt;u32 amba_size_per_chip;&lt;/P&gt;&lt;P&gt;int i, ret;&lt;/P&gt;&lt;P&gt;caso_qspi_plat = (struct casco_qspi_platdata *)malloc(sizeof(struct casco_qspi_platdata));&lt;BR /&gt;memset(caso_qspi_plat, 0, sizeof(struct casco_qspi_platdata));&lt;BR /&gt;caso_qspi_plat-&amp;gt;flags |= QSPI_FLAG_REGMAP_ENDIAN_BIG;&lt;BR /&gt;casco_qspi_flags |= caso_qspi_plat-&amp;gt;flags;&lt;BR /&gt;caso_qspi_plat-&amp;gt;speed_hz = 6250000;&lt;BR /&gt;caso_qspi_plat-&amp;gt;num_chipselect = 4;&lt;BR /&gt;caso_qspi_plat-&amp;gt;reg_base = 0x1550000;&lt;BR /&gt;caso_qspi_plat-&amp;gt;amba_base = 0x40000000;&lt;BR /&gt;caso_qspi_plat-&amp;gt;amba_total_size = 0x20000000;&lt;/P&gt;&lt;P&gt;casco_qspi_ctrl = (struct casco_qspi_priv *)malloc(sizeof(struct casco_qspi_priv));&lt;BR /&gt;memset(casco_qspi_ctrl, 0, sizeof(struct casco_qspi_priv));&lt;/P&gt;&lt;P&gt;casco_qspi_regs = (struct fsl_qspi_regs *)malloc(sizeof(struct fsl_qspi_regs));&lt;BR /&gt;memset(casco_qspi_regs, 0, sizeof(struct fsl_qspi_regs));&lt;/P&gt;&lt;P&gt;casco_qspi_write32(casco_qspi_flags, 0x157015c, 0x00100000);/* CLK 6.25MHz */&lt;/P&gt;&lt;P&gt;casco_qspi_ctrl-&amp;gt;regs = (struct fsl_qspi_regs *)casco_qspi_regs;&lt;BR /&gt;casco_qspi_ctrl-&amp;gt;flags = caso_qspi_plat-&amp;gt;flags;&lt;/P&gt;&lt;P&gt;casco_qspi_ctrl-&amp;gt;speed_hz = caso_qspi_plat-&amp;gt;speed_hz;&lt;BR /&gt;/*&lt;BR /&gt;* QSPI SFADR width is 32bits, the max dest addr is 4GB-1.&lt;BR /&gt;* AMBA memory zone should be located on the 0~4GB space&lt;BR /&gt;* even on a 64bits cpu.&lt;BR /&gt;*/&lt;BR /&gt;casco_qspi_ctrl-&amp;gt;amba_base[0] = (u32)caso_qspi_plat-&amp;gt;amba_base;&lt;BR /&gt;casco_qspi_ctrl-&amp;gt;amba_total_size = (u32)caso_qspi_plat-&amp;gt;amba_total_size;&lt;BR /&gt;casco_qspi_ctrl-&amp;gt;flash_num = caso_qspi_plat-&amp;gt;flash_num;&lt;BR /&gt;casco_qspi_ctrl-&amp;gt;num_chipselect = caso_qspi_plat-&amp;gt;num_chipselect;&lt;/P&gt;&lt;P&gt;/* make sure controller is not busy anywhere */&lt;BR /&gt;ret = is_controller_busy(casco_qspi_ctrl);&lt;/P&gt;&lt;P&gt;if (ret) {&lt;BR /&gt;printf("ERROR : The controller is busy\n");&lt;BR /&gt;return ret;&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;mcr_val = casco_qspi_read32(casco_qspi_ctrl-&amp;gt;flags, &amp;amp;casco_qspi_ctrl-&amp;gt;regs-&amp;gt;mcr);&lt;/P&gt;&lt;P&gt;casco_qspi_write32(casco_qspi_ctrl-&amp;gt;flags, &amp;amp;casco_qspi_ctrl-&amp;gt;regs-&amp;gt;mcr,&lt;BR /&gt;QSPI_MCR_RESERVED_MASK | QSPI_MCR_MDIS_MASK |&lt;BR /&gt;(mcr_val &amp;amp; QSPI_MCR_END_CFD_MASK));&lt;/P&gt;&lt;P&gt;qspi_cfg_smpr(casco_qspi_ctrl, ~(QSPI_SMPR_FSDLY_MASK | QSPI_SMPR_DDRSMP_MASK |&lt;BR /&gt;QSPI_SMPR_FSPHS_MASK | QSPI_SMPR_HSENA_MASK), 0);&lt;/P&gt;&lt;P&gt;/*&lt;BR /&gt;* Assign AMBA memory zone for every chipselect&lt;BR /&gt;* QuadSPI has two channels, every channel has two chipselects.&lt;BR /&gt;* If the property 'num-cs' in dts is 2, the AMBA memory will be divided&lt;BR /&gt;* into two parts and assign to every channel. This indicate that every&lt;BR /&gt;* channel only has one valid chipselect.&lt;BR /&gt;* If the property 'num-cs' in dts is 4, the AMBA memory will be divided&lt;BR /&gt;* into four parts and assign to every chipselect.&lt;BR /&gt;* Every channel will has two valid chipselects.&lt;BR /&gt;*/&lt;BR /&gt;amba_size_per_chip = casco_qspi_ctrl-&amp;gt;amba_total_size &amp;gt;&amp;gt;&lt;BR /&gt;(casco_qspi_ctrl-&amp;gt;num_chipselect &amp;gt;&amp;gt; 1);&lt;BR /&gt;for (i = 1 ; i &amp;lt; casco_qspi_ctrl-&amp;gt;num_chipselect ; i++)&lt;BR /&gt;casco_qspi_ctrl-&amp;gt;amba_base[i] =&lt;BR /&gt;amba_size_per_chip + casco_qspi_ctrl-&amp;gt;amba_base[i - 1];&lt;/P&gt;&lt;P&gt;/*&lt;BR /&gt;* Any read access to non-implemented addresses will provide&lt;BR /&gt;* undefined results.&lt;BR /&gt;*&lt;BR /&gt;* In case single die flash devices, TOP_ADDR_MEMA2 and&lt;BR /&gt;* TOP_ADDR_MEMB2 should be initialized/programmed to&lt;BR /&gt;* TOP_ADDR_MEMA1 and TOP_ADDR_MEMB1 respectively - in effect,&lt;BR /&gt;* setting the size of these devices to 0. This would ensure&lt;BR /&gt;* that the complete memory map is assigned to only one flash device.&lt;BR /&gt;*/&lt;BR /&gt;casco_qspi_write32(casco_qspi_ctrl-&amp;gt;flags, &amp;amp;casco_qspi_ctrl-&amp;gt;regs-&amp;gt;sfa1ad,&lt;BR /&gt;casco_qspi_ctrl-&amp;gt;amba_base[0] + amba_size_per_chip);&lt;BR /&gt;switch (casco_qspi_ctrl-&amp;gt;num_chipselect) {&lt;BR /&gt;case 1:&lt;BR /&gt;break;&lt;BR /&gt;case 2:&lt;BR /&gt;casco_qspi_write32(casco_qspi_ctrl-&amp;gt;flags, &amp;amp;casco_qspi_ctrl-&amp;gt;regs-&amp;gt;sfa2ad,&lt;BR /&gt;casco_qspi_ctrl-&amp;gt;amba_base[1]);&lt;BR /&gt;casco_qspi_write32(casco_qspi_ctrl-&amp;gt;flags, &amp;amp;casco_qspi_ctrl-&amp;gt;regs-&amp;gt;sfb1ad,&lt;BR /&gt;casco_qspi_ctrl-&amp;gt;amba_base[1] + amba_size_per_chip);&lt;BR /&gt;casco_qspi_write32(casco_qspi_ctrl-&amp;gt;flags, &amp;amp;casco_qspi_ctrl-&amp;gt;regs-&amp;gt;sfb2ad,&lt;BR /&gt;casco_qspi_ctrl-&amp;gt;amba_base[1] + amba_size_per_chip);&lt;BR /&gt;break;&lt;BR /&gt;case 4:&lt;BR /&gt;casco_qspi_write32(casco_qspi_ctrl-&amp;gt;flags, &amp;amp;casco_qspi_ctrl-&amp;gt;regs-&amp;gt;sfa2ad,&lt;BR /&gt;casco_qspi_ctrl-&amp;gt;amba_base[2]);&lt;BR /&gt;casco_qspi_write32(casco_qspi_ctrl-&amp;gt;flags, &amp;amp;casco_qspi_ctrl-&amp;gt;regs-&amp;gt;sfb1ad,&lt;BR /&gt;casco_qspi_ctrl-&amp;gt;amba_base[3]);&lt;BR /&gt;casco_qspi_write32(casco_qspi_ctrl-&amp;gt;flags, &amp;amp;casco_qspi_ctrl-&amp;gt;regs-&amp;gt;sfb2ad,&lt;BR /&gt;casco_qspi_ctrl-&amp;gt;amba_base[3] + amba_size_per_chip);&lt;BR /&gt;break;&lt;BR /&gt;default:&lt;BR /&gt;printf("Error: Unsupported chipselect number %u!\n",&lt;BR /&gt;casco_qspi_ctrl-&amp;gt;num_chipselect);&lt;BR /&gt;qspi_module_disable(casco_qspi_ctrl, 1);&lt;BR /&gt;return -EINVAL;&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;/*qspi_set_lut(priv);*/&lt;BR /&gt;casco_qspi_set_lut();&lt;/P&gt;&lt;P&gt;qspi_module_disable(casco_qspi_ctrl, 0);&lt;/P&gt;&lt;P&gt;return 0;&lt;BR /&gt;}&lt;/P&gt;</description>
    <pubDate>Thu, 20 May 2021 01:12:57 GMT</pubDate>
    <dc:creator>dinghui</dc:creator>
    <dc:date>2021-05-20T01:12:57Z</dc:date>
    <item>
      <title>LS1043A using QSPI to access FPGA</title>
      <link>https://community.nxp.com/t5/Layerscape/LS1043A-using-QSPI-to-access-FPGA/m-p/1279313#M8029</link>
      <description>&lt;P&gt;We develop a custom board based on LS1043A. We want to use QSPIA interface to access the FPGA and the chip select is QSPIA-CS1. I wrote the driver code refer to fsl_qspi.c in u-boot (version 2019.04). But it doesn't work at all. Since i issue the IP command to read data from FPGA, there is nothing output from QSPIA_CLK and QSPIA_CS1. I have already programed&amp;nbsp;&amp;nbsp;the QSPI_SFAR register and written&amp;nbsp;the QSPI_IPCR[SEQID] field to trigger the execution of a new IP Command that prepared in LUT table.&lt;/P&gt;&lt;P&gt;Following is demo driver code:&lt;/P&gt;&lt;P&gt;static void casco_qspi_set_lut(void)&lt;BR /&gt;{&lt;BR /&gt;struct fsl_qspi_regs *regs = casco_qspi_regs;&lt;BR /&gt;u32 lut_base;&lt;/P&gt;&lt;P&gt;/* Unlock the LUT */&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;lutkey, LUT_KEY_VALUE);&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;lckcr, QSPI_LCKCR_UNLOCK);&lt;/P&gt;&lt;P&gt;/* read from FPGA */&lt;BR /&gt;lut_base = SEQID_RDFPGA * 4;&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;lut[lut_base],&lt;BR /&gt;OPRND0(0xEB) | PAD0(LUT_PAD1) |&lt;BR /&gt;INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) |&lt;BR /&gt;PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;lut[lut_base + 1],&lt;BR /&gt;OPRND0(10) | PAD0(LUT_PAD1) | INSTR0(LUT_DUMMY) |&lt;BR /&gt;OPRND1(4) | PAD1(LUT_PAD1) |&lt;BR /&gt;INSTR1(LUT_READ));&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;lut[lut_base + 2], 0);&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;lut[lut_base + 3], 0);&lt;/P&gt;&lt;P&gt;/* write to FPGA */&lt;BR /&gt;lut_base = SEQID_WRFPGA * 4;&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;lut[lut_base],&lt;BR /&gt;OPRND0(0x32) | PAD0(LUT_PAD1) |&lt;BR /&gt;INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) |&lt;BR /&gt;PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;lut[lut_base + 1],&lt;BR /&gt;OPRND0(4) | PAD0(LUT_PAD1) | INSTR0(LUT_WRITE));&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;lut[lut_base + 2], 0);&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;lut[lut_base + 3], 0);&lt;/P&gt;&lt;P&gt;/* Lock the LUT */&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;lutkey, LUT_KEY_VALUE);&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;lckcr, QSPI_LCKCR_LOCK);&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;void casco_qspi_op_read(u32 offset, u32 *rxbuf, u32 len)&lt;BR /&gt;{&lt;BR /&gt;u32 mcr_reg, data;&lt;BR /&gt;int i, size;&lt;BR /&gt;u32 to_or_from;&lt;BR /&gt;u32 seqid;&lt;BR /&gt;struct fsl_qspi_regs *regs = casco_qspi_regs;&lt;BR /&gt;u32 temp = 0;&lt;/P&gt;&lt;P&gt;seqid = SEQID_RDFPGA;&lt;/P&gt;&lt;P&gt;mcr_reg = casco_qspi_read32(casco_qspi_flags, &amp;amp;regs-&amp;gt;mcr);&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;mcr,&lt;BR /&gt;QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |&lt;BR /&gt;QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;rbct, QSPI_RBCT_RXBRD_USEIPS);&lt;/P&gt;&lt;P&gt;to_or_from = casco_qspi_ctrl-&amp;gt;amba_base[0]+offset;&lt;BR /&gt;printf("%s: access address 0x%x\n", __func__, to_or_from);&lt;BR /&gt;if(len &amp;gt; 0x40)&lt;BR /&gt;{&lt;BR /&gt;len = 0x40;&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;while (len &amp;gt; 0) {&lt;/P&gt;&lt;P&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;sfar, to_or_from);&lt;BR /&gt;temp = casco_qspi_read32(casco_qspi_flags, &amp;amp;regs-&amp;gt;sfar);&lt;BR /&gt;printf("%s: reg sfar read 0x%x\n", __func__, temp);&lt;BR /&gt;temp = casco_qspi_read32(casco_qspi_flags, &amp;amp;regs-&amp;gt;sfa1ad);&lt;BR /&gt;printf("%s: reg sfa1ad read 0x%x\n", __func__, temp);&lt;BR /&gt;temp = casco_qspi_read32(casco_qspi_flags, &amp;amp;regs-&amp;gt;sfa2ad);&lt;BR /&gt;printf("%s: reg sfa2ad read 0x%x\n", __func__, temp);&lt;BR /&gt;temp = casco_qspi_read32(casco_qspi_flags, &amp;amp;regs-&amp;gt;sfb1ad);&lt;BR /&gt;printf("%s: reg sfb1ad read 0x%x\n", __func__, temp);&lt;BR /&gt;temp = casco_qspi_read32(casco_qspi_flags, &amp;amp;regs-&amp;gt;sfb2ad);&lt;BR /&gt;printf("%s: reg sfb2ad read 0x%x\n", __func__, temp);&lt;/P&gt;&lt;P&gt;size = (len &amp;gt; RX_BUFFER_SIZE) ?&lt;BR /&gt;RX_BUFFER_SIZE : len;&lt;/P&gt;&lt;P&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;ipcr,&lt;BR /&gt;(seqid &amp;lt;&amp;lt; QSPI_IPCR_SEQID_SHIFT) |&lt;BR /&gt;size);&lt;/P&gt;&lt;P&gt;temp = casco_qspi_read32(casco_qspi_flags, &amp;amp;regs-&amp;gt;lut[seqid &amp;lt;&amp;lt; 2]);&lt;BR /&gt;printf("%s: reg lut[%d] read 0x%x\n", __func__, seqid &amp;lt;&amp;lt; 2, temp);&lt;/P&gt;&lt;P&gt;temp = casco_qspi_read32(casco_qspi_flags, &amp;amp;regs-&amp;gt;fr);&lt;BR /&gt;printf("%s: reg fr read 0x%x\n", __func__, temp);&lt;/P&gt;&lt;P&gt;while (casco_qspi_read32(casco_qspi_flags, &amp;amp;regs-&amp;gt;sr) &amp;amp; QSPI_SR_BUSY_MASK)&lt;BR /&gt;;&lt;BR /&gt;temp = casco_qspi_read32(casco_qspi_flags, &amp;amp;regs-&amp;gt;fr);&lt;BR /&gt;printf("%s: reg fr read 0x%x\n", __func__, temp);&lt;/P&gt;&lt;P&gt;to_or_from += size;&lt;BR /&gt;len -= size;&lt;/P&gt;&lt;P&gt;i = 0;&lt;BR /&gt;while ((RX_BUFFER_SIZE &amp;gt;= size) &amp;amp;&amp;amp; (size &amp;gt; 0)) {&lt;BR /&gt;data = casco_qspi_read32(casco_qspi_flags, &amp;amp;regs-&amp;gt;rbdr[i]);&lt;BR /&gt;data = casco_qspi_endian_xchg(data);&lt;BR /&gt;if (size &amp;lt; 4)&lt;BR /&gt;memcpy(rxbuf, &amp;amp;data, size);&lt;BR /&gt;else&lt;BR /&gt;memcpy(rxbuf, &amp;amp;data, 4);&lt;BR /&gt;rxbuf++;&lt;BR /&gt;size -= 4;&lt;BR /&gt;i++;&lt;BR /&gt;}&lt;BR /&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;mcr,&lt;BR /&gt;casco_qspi_read32(casco_qspi_flags, &amp;amp;regs-&amp;gt;mcr) |&lt;BR /&gt;QSPI_MCR_CLR_RXF_MASK);&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;casco_qspi_write32(casco_qspi_flags, &amp;amp;regs-&amp;gt;mcr, mcr_reg);&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;int casco_qspi_init(void)&lt;BR /&gt;{&lt;BR /&gt;u32 mcr_val;&lt;BR /&gt;u32 amba_size_per_chip;&lt;/P&gt;&lt;P&gt;int i, ret;&lt;/P&gt;&lt;P&gt;caso_qspi_plat = (struct casco_qspi_platdata *)malloc(sizeof(struct casco_qspi_platdata));&lt;BR /&gt;memset(caso_qspi_plat, 0, sizeof(struct casco_qspi_platdata));&lt;BR /&gt;caso_qspi_plat-&amp;gt;flags |= QSPI_FLAG_REGMAP_ENDIAN_BIG;&lt;BR /&gt;casco_qspi_flags |= caso_qspi_plat-&amp;gt;flags;&lt;BR /&gt;caso_qspi_plat-&amp;gt;speed_hz = 6250000;&lt;BR /&gt;caso_qspi_plat-&amp;gt;num_chipselect = 4;&lt;BR /&gt;caso_qspi_plat-&amp;gt;reg_base = 0x1550000;&lt;BR /&gt;caso_qspi_plat-&amp;gt;amba_base = 0x40000000;&lt;BR /&gt;caso_qspi_plat-&amp;gt;amba_total_size = 0x20000000;&lt;/P&gt;&lt;P&gt;casco_qspi_ctrl = (struct casco_qspi_priv *)malloc(sizeof(struct casco_qspi_priv));&lt;BR /&gt;memset(casco_qspi_ctrl, 0, sizeof(struct casco_qspi_priv));&lt;/P&gt;&lt;P&gt;casco_qspi_regs = (struct fsl_qspi_regs *)malloc(sizeof(struct fsl_qspi_regs));&lt;BR /&gt;memset(casco_qspi_regs, 0, sizeof(struct fsl_qspi_regs));&lt;/P&gt;&lt;P&gt;casco_qspi_write32(casco_qspi_flags, 0x157015c, 0x00100000);/* CLK 6.25MHz */&lt;/P&gt;&lt;P&gt;casco_qspi_ctrl-&amp;gt;regs = (struct fsl_qspi_regs *)casco_qspi_regs;&lt;BR /&gt;casco_qspi_ctrl-&amp;gt;flags = caso_qspi_plat-&amp;gt;flags;&lt;/P&gt;&lt;P&gt;casco_qspi_ctrl-&amp;gt;speed_hz = caso_qspi_plat-&amp;gt;speed_hz;&lt;BR /&gt;/*&lt;BR /&gt;* QSPI SFADR width is 32bits, the max dest addr is 4GB-1.&lt;BR /&gt;* AMBA memory zone should be located on the 0~4GB space&lt;BR /&gt;* even on a 64bits cpu.&lt;BR /&gt;*/&lt;BR /&gt;casco_qspi_ctrl-&amp;gt;amba_base[0] = (u32)caso_qspi_plat-&amp;gt;amba_base;&lt;BR /&gt;casco_qspi_ctrl-&amp;gt;amba_total_size = (u32)caso_qspi_plat-&amp;gt;amba_total_size;&lt;BR /&gt;casco_qspi_ctrl-&amp;gt;flash_num = caso_qspi_plat-&amp;gt;flash_num;&lt;BR /&gt;casco_qspi_ctrl-&amp;gt;num_chipselect = caso_qspi_plat-&amp;gt;num_chipselect;&lt;/P&gt;&lt;P&gt;/* make sure controller is not busy anywhere */&lt;BR /&gt;ret = is_controller_busy(casco_qspi_ctrl);&lt;/P&gt;&lt;P&gt;if (ret) {&lt;BR /&gt;printf("ERROR : The controller is busy\n");&lt;BR /&gt;return ret;&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;mcr_val = casco_qspi_read32(casco_qspi_ctrl-&amp;gt;flags, &amp;amp;casco_qspi_ctrl-&amp;gt;regs-&amp;gt;mcr);&lt;/P&gt;&lt;P&gt;casco_qspi_write32(casco_qspi_ctrl-&amp;gt;flags, &amp;amp;casco_qspi_ctrl-&amp;gt;regs-&amp;gt;mcr,&lt;BR /&gt;QSPI_MCR_RESERVED_MASK | QSPI_MCR_MDIS_MASK |&lt;BR /&gt;(mcr_val &amp;amp; QSPI_MCR_END_CFD_MASK));&lt;/P&gt;&lt;P&gt;qspi_cfg_smpr(casco_qspi_ctrl, ~(QSPI_SMPR_FSDLY_MASK | QSPI_SMPR_DDRSMP_MASK |&lt;BR /&gt;QSPI_SMPR_FSPHS_MASK | QSPI_SMPR_HSENA_MASK), 0);&lt;/P&gt;&lt;P&gt;/*&lt;BR /&gt;* Assign AMBA memory zone for every chipselect&lt;BR /&gt;* QuadSPI has two channels, every channel has two chipselects.&lt;BR /&gt;* If the property 'num-cs' in dts is 2, the AMBA memory will be divided&lt;BR /&gt;* into two parts and assign to every channel. This indicate that every&lt;BR /&gt;* channel only has one valid chipselect.&lt;BR /&gt;* If the property 'num-cs' in dts is 4, the AMBA memory will be divided&lt;BR /&gt;* into four parts and assign to every chipselect.&lt;BR /&gt;* Every channel will has two valid chipselects.&lt;BR /&gt;*/&lt;BR /&gt;amba_size_per_chip = casco_qspi_ctrl-&amp;gt;amba_total_size &amp;gt;&amp;gt;&lt;BR /&gt;(casco_qspi_ctrl-&amp;gt;num_chipselect &amp;gt;&amp;gt; 1);&lt;BR /&gt;for (i = 1 ; i &amp;lt; casco_qspi_ctrl-&amp;gt;num_chipselect ; i++)&lt;BR /&gt;casco_qspi_ctrl-&amp;gt;amba_base[i] =&lt;BR /&gt;amba_size_per_chip + casco_qspi_ctrl-&amp;gt;amba_base[i - 1];&lt;/P&gt;&lt;P&gt;/*&lt;BR /&gt;* Any read access to non-implemented addresses will provide&lt;BR /&gt;* undefined results.&lt;BR /&gt;*&lt;BR /&gt;* In case single die flash devices, TOP_ADDR_MEMA2 and&lt;BR /&gt;* TOP_ADDR_MEMB2 should be initialized/programmed to&lt;BR /&gt;* TOP_ADDR_MEMA1 and TOP_ADDR_MEMB1 respectively - in effect,&lt;BR /&gt;* setting the size of these devices to 0. This would ensure&lt;BR /&gt;* that the complete memory map is assigned to only one flash device.&lt;BR /&gt;*/&lt;BR /&gt;casco_qspi_write32(casco_qspi_ctrl-&amp;gt;flags, &amp;amp;casco_qspi_ctrl-&amp;gt;regs-&amp;gt;sfa1ad,&lt;BR /&gt;casco_qspi_ctrl-&amp;gt;amba_base[0] + amba_size_per_chip);&lt;BR /&gt;switch (casco_qspi_ctrl-&amp;gt;num_chipselect) {&lt;BR /&gt;case 1:&lt;BR /&gt;break;&lt;BR /&gt;case 2:&lt;BR /&gt;casco_qspi_write32(casco_qspi_ctrl-&amp;gt;flags, &amp;amp;casco_qspi_ctrl-&amp;gt;regs-&amp;gt;sfa2ad,&lt;BR /&gt;casco_qspi_ctrl-&amp;gt;amba_base[1]);&lt;BR /&gt;casco_qspi_write32(casco_qspi_ctrl-&amp;gt;flags, &amp;amp;casco_qspi_ctrl-&amp;gt;regs-&amp;gt;sfb1ad,&lt;BR /&gt;casco_qspi_ctrl-&amp;gt;amba_base[1] + amba_size_per_chip);&lt;BR /&gt;casco_qspi_write32(casco_qspi_ctrl-&amp;gt;flags, &amp;amp;casco_qspi_ctrl-&amp;gt;regs-&amp;gt;sfb2ad,&lt;BR /&gt;casco_qspi_ctrl-&amp;gt;amba_base[1] + amba_size_per_chip);&lt;BR /&gt;break;&lt;BR /&gt;case 4:&lt;BR /&gt;casco_qspi_write32(casco_qspi_ctrl-&amp;gt;flags, &amp;amp;casco_qspi_ctrl-&amp;gt;regs-&amp;gt;sfa2ad,&lt;BR /&gt;casco_qspi_ctrl-&amp;gt;amba_base[2]);&lt;BR /&gt;casco_qspi_write32(casco_qspi_ctrl-&amp;gt;flags, &amp;amp;casco_qspi_ctrl-&amp;gt;regs-&amp;gt;sfb1ad,&lt;BR /&gt;casco_qspi_ctrl-&amp;gt;amba_base[3]);&lt;BR /&gt;casco_qspi_write32(casco_qspi_ctrl-&amp;gt;flags, &amp;amp;casco_qspi_ctrl-&amp;gt;regs-&amp;gt;sfb2ad,&lt;BR /&gt;casco_qspi_ctrl-&amp;gt;amba_base[3] + amba_size_per_chip);&lt;BR /&gt;break;&lt;BR /&gt;default:&lt;BR /&gt;printf("Error: Unsupported chipselect number %u!\n",&lt;BR /&gt;casco_qspi_ctrl-&amp;gt;num_chipselect);&lt;BR /&gt;qspi_module_disable(casco_qspi_ctrl, 1);&lt;BR /&gt;return -EINVAL;&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;/*qspi_set_lut(priv);*/&lt;BR /&gt;casco_qspi_set_lut();&lt;/P&gt;&lt;P&gt;qspi_module_disable(casco_qspi_ctrl, 0);&lt;/P&gt;&lt;P&gt;return 0;&lt;BR /&gt;}&lt;/P&gt;</description>
      <pubDate>Thu, 20 May 2021 01:12:57 GMT</pubDate>
      <guid>https://community.nxp.com/t5/Layerscape/LS1043A-using-QSPI-to-access-FPGA/m-p/1279313#M8029</guid>
      <dc:creator>dinghui</dc:creator>
      <dc:date>2021-05-20T01:12:57Z</dc:date>
    </item>
    <item>
      <title>Re: LS1043A using QSPI to access FPGA</title>
      <link>https://community.nxp.com/t5/Layerscape/LS1043A-using-QSPI-to-access-FPGA/m-p/1279588#M8036</link>
      <description>&lt;P&gt;Found the problem:&lt;/P&gt;&lt;P&gt;the following code should be modified:&lt;/P&gt;&lt;P&gt;casco_qspi_regs = (struct fsl_qspi_regs *)malloc(sizeof(struct fsl_qspi_regs));&lt;BR /&gt;memset(casco_qspi_regs, 0, sizeof(struct fsl_qspi_regs));&lt;/P&gt;&lt;P&gt;After modified:&lt;/P&gt;&lt;P&gt;casco_qspi_regs = (struct fsl_qspi_regs *)(uintptr_t)0x1550000;&lt;/P&gt;</description>
      <pubDate>Thu, 20 May 2021 08:11:32 GMT</pubDate>
      <guid>https://community.nxp.com/t5/Layerscape/LS1043A-using-QSPI-to-access-FPGA/m-p/1279588#M8036</guid>
      <dc:creator>dinghui</dc:creator>
      <dc:date>2021-05-20T08:11:32Z</dc:date>
    </item>
  </channel>
</rss>

