This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM6442: Want to set the QSPI bus width to 4 bits

Part Number: AM6442

Hi,

We've received a inquiry from my customer. Could you please help them to solve this issue. 

FRAM (cy15x116q: QSPI) and Uboot Flash (s28hs512t: OSPI) are connected to OSPI I/F on the customer's board, but FRAM doesn’t work as QSPI.

 

If qspi (TX=4bit RX=4bit) is set for fram in the device tree settings shown below, an error "spi spi0.1: setup: ignoring unsupported mode bits 200" occurs when starting Linux. Driver can't start.

Is it possible to set the QSPI bus width to 4 bits? 

 

They’re thinking there may be a problem in the driver because it looks like the above setting is allowed according to the hardware specifications.

 

Could you please give them any comment, and please help to solve this ?

 

 

< Device Tree >

 

&ospi0

              pinctrl-names = "default";

              pinctrl-0 = <&ospi0_pins_default>;

 

              reg = <0x00 0x0fc40000 0x00 0x100>,

                    <0x00 0x60000000 0x00 0x04000000>,

                    <0x00 0x64000000 0x00 0x01000000>;

              cs-gpios =         <0>, <0>;                        /* 2 Native CS0,1 */

 

              flash@0{

                            compatible = "jedec,spi-nor";

                            reg = <0x0>;

                            spi-tx-bus-width = <8>;

                            spi-rx-bus-width = <8>;

                            spi-max-frequency = <25000000>;

                            cdns,tshsl-ns = <60>;

                            cdns,tsd2d-ns = <60>;

                            cdns,tchsh-ns = <60>;

                            cdns,tslch-ns = <60>;

                            cdns,read-delay = <4>;

                            cdns,phy-mode;

                            #address-cells = <1>;

                            #size-cells = <1>;

              };

 

              fram@1{

                            compatible = "jedec,spi-nor";

                            reg = <0x1>;

                            spi-tx-bus-width = <4>;    <=== if this is set as “4”, Error occurrs.

                            spi-rx-bus-width = <4>;

                            spi-max-frequency = <25000000>;

                            cdns,tshsl-ns = <60>;

                            cdns,tsd2d-ns = <60>;

                            cdns,tchsh-ns = <60>;

                            cdns,tslch-ns = <60>;

                            cdns,read-delay = <4>;

 

                            cdns,phy-mode;

                            #address-cells = <1>;

                            #size-cells = <1>;

 

              };

 

 

< Output on Linux >

 

[    0.531995] spi-nor spi0.0: s28hs512t (65536 Kbytes)

[    0.532070] 7 fixed-partitions partitions found on MTD device fc40000.spi.0

[    0.532077] Creating 7 MTD partitions on "fc40000.spi.0":

[    0.532087] 0x000000000000-0x000000100000 : "tiboot3"

[    0.558550] 0x000000100000-0x000000300000 : "tispl"

[    0.586275] 0x000000300000-0x000000700000 : "u-boot"

[    0.613095] 0x000000700000-0x000000740000 : "u-boot-env"

[    0.632373] 0x000000740000-0x000000780000 : "u-boot-env.backup"

[    0.644044] 0x000000800000-0x000004000000 : "file-system"

[    0.653294] 0x000003fc0000-0x000004000000 : "phypattern"

[    0.655033] spi spi0.1: setup: ignoring unsupported mode bits 200

[    0.655875] spi-nor spi0.1: cy15x116q (2048 Kbytes)

 

Regards,

Hideaki

  • Hi Hideaki-san,

    it looks like 4-wire SPI TX support is not advertised by the driver, although I think it should be supported. Can you please try the below Linux kernel modification, to see if this improves the behavior and report back:

    $ git diff
    diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
    index 957c1a4561ad..d0a398a074aa 100644
    --- a/drivers/spi/spi-cadence-quadspi.c
    +++ b/drivers/spi/spi-cadence-quadspi.c
    @@ -2405,7 +2405,7 @@ static int cqspi_probe(struct platform_device *pdev)
                    dev_err(&pdev->dev, "spi_alloc_master failed\n");
                    return -ENOMEM;
            }
    -       master->mode_bits = SPI_RX_QUAD | SPI_RX_DUAL;
    +       master->mode_bits = SPI_RX_QUAD | SPI_RX_DUAL | SPI_TX_QUAD | SPI_TX_DUAL;
            master->mem_ops = &cqspi_mem_ops;
            master->mem_caps = &cqspi_mem_caps;
            master->dev.of_node = pdev->dev.of_node;

    Regards, Andreas

  • Hi Andreas,

    Thank you so much for your advice. The customer is now trying the Linux kernel modification which you provided.

    They want to set the Dummy Read Clock Cycles in the following register. Could you tell them what the parameter name in the device tree below is ?

    They confirmed that it is not cdns,read-delay = <4>;.

    --------------------

    Table 12-3093. OSPI_DEV_INSTR_RD_CONFIG_REG

    FSS0_OSPI0_CTRL

    0FC4 0004h   Bit28-24

    Field

    DUMMY_RD_CLK_CYCLES_FLD

    Description

    Dummy Read Clock Cycles.Number of dummy clock cycles required by device for read instruction.

    ---------------------

    Also, could you tell them how to know a parameter name easily when they need to set other registers ?

     

    < Device Tree >

    &ospi0 {

                  pinctrl-names = "default";

                  pinctrl-0 = <&ospi0_pins_default>;

     

                  reg = <0x00 0x0fc40000 0x00 0x100>,

                        <0x00 0x60000000 0x00 0x04000000>,

                        <0x00 0x64000000 0x00 0x01000000>;

                  cs-gpios =         <0>, <0>;                        /* 2 Native CS0,1 */

     

                  flash@0{

                                compatible = "jedec,spi-nor";

                                reg = <0x0>;

                                spi-tx-bus-width = <8>;

                                spi-rx-bus-width = <8>;

                                spi-max-frequency = <25000000>;

                                cdns,tshsl-ns = <60>;

                                cdns,tsd2d-ns = <60>;

                                cdns,tchsh-ns = <60>;

                                cdns,tslch-ns = <60>;

                                cdns,read-delay = <4>;

                                cdns,phy-mode;

    * They would like to add the value of 0FC4 0004h<Bit28-24>.

     

                                #address-cells = <1>;

                                #size-cells = <1>;

                  };

     

                  fram@1{

                                compatible = "jedec,spi-nor";

                                reg = <0x1>;

                                spi-tx-bus-width = <4>;

                                spi-rx-bus-width = <4>;

                                spi-max-frequency = <25000000>;

                                cdns,tshsl-ns = <60>;

                                cdns,tsd2d-ns = <60>;

                                cdns,tchsh-ns = <60>;

                                cdns,tslch-ns = <60>;

                                cdns,read-delay = <4>;

    * They would like to add the value of 0FC4 0004h<Bit28-24>.

                                cdns,phy-mode;

                                #address-cells = <1>;

                                #size-cells = <1>;

     

                  };

     

    Thanks and regards,

    Hideaki

  • Also, could you tell them how to know a parameter name easily when they need to set other registers ?

    Hi Matsumoto-san,

    I'm researching this, will get back to you soon, probably this weekend. Stay tuned.

    Regards, Andreas

  • They want to set the Dummy Read Clock Cycles in the following register. Could you tell them what the parameter name in the device tree below is ?

    They confirmed that it is not cdns,read-delay = <4>;.

    --------------------

    Table 12-3093. OSPI_DEV_INSTR_RD_CONFIG_REG

    FSS0_OSPI0_CTRL

    0FC4 0004h   Bit28-24

    Field

    DUMMY_RD_CLK_CYCLES_FLD

    Description

    Dummy Read Clock Cycles.Number of dummy clock cycles required by device for read instruction.

    The value written to this register field is automatically calculated by the driver's cqspi_calc_dummy() function and then written into that register/bit-field as part of the cqspi_read_setup() function. There is no device tree parameter that can be set for this. If you want to override the default you should be able to modify the cqspi_calc_dummy() function to return a certain fixed value, or use a different algorithm to determine the value. At a minimum, this approach could be used for bench testing purposes to see if changing this value makes an impact, for a given external QSPI device you are interfacing with.

    What is the reason we need something custom here that's not already supported by the driver? Do you need to use certain different/fixed values for the two devices on the bus? Did you test/confirm the values calculated by cqspi_calc_dummy() are not usable? I'd like to better understand the need here to see if a driver update may be needed or not.

    Also, could you tell them how to know a parameter name easily when they need to set other registers ?

    The best/most reliable way is really by looking at the spi-cadence-quadspi.c driver source code in the kernel tree. One can also look at the  associated device tree bindings document in the kernel tree, which should always be sync with the driver, see cdns,qspi-nor-peripheral-props.yaml and cdns,qspi-nor.yaml.

    Regards, Andreas

  • Hi Andreas,

    Thank you so much for your support on this. Since it’ll take some time to modify the Linux kernel and verify it on the customer’s board, I’ll let you know once we received their feedback.

    They have one more question regarding this OSPI clock. Could you provide any advice to them ?

    When they reconfirmed the clock settings, they found that the default setting for OSPI reference clock is 200MHz.

    They think that it’s possible to set 100MHz half of 200MHz. How about a little faster clock such like 133.33MHz ? Is it possible to set it ?

    The reason why they’re asking this is that there is 133.33MHz reference clock on another PLL but they don’t understand if 133.33MHz can be set.

    In general, is it normal to set it automatically using PHY Data Training?

     

    What is the reason we need something custom here that's not already supported by the driver? Do you need to use certain different/fixed values for the two devices on the bus?

    They want to use QSPI FRAM (CY15x116Q) at SDR @10MHz and OSPI Flash (S28HS512T) at DDR @133.3MHz with DQS.

     

     

    Thanks and regards,

    Hideaki

  • When they reconfirmed the clock settings, they found that the default setting for OSPI reference clock is 200MHz.

    They think that it’s possible to set 100MHz half of 200MHz. How about a little faster clock such like 133.33MHz ? Is it possible to set it ?

    There's an E2E thread here that discusses OSPI reference clock settings in detail and how it's done via DTS ("assigned-clock-parents" and "assigned-clock-rates" properties). There's also a command line tool called "k3conf" running on the AM64x that can be used to check if the frequency setting was successful, see https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1223290/am625-set-ospi0-clock-setting-to-160mhz/4746677

    In general, talking to some team members from the hardware team here they think it is unlikely to work at higher clock frequencies with multiple devices connected to the OSPI bus as it was not designed/tested/timing-closed that way. So to maximize your chances of getting at least something working I would suggest using clock rates as slow as possible (perhaps 10MHz, or even lower) for everything. A better approach might actually be to connect the QSPI FRAM (CY15x116Q) device to a dedicated SPI peripheral (McSPI) rather than the OSPI bus, and keep that one dedicated for Linux rootfs etc.

    In general, is it normal to set it automatically using PHY Data Training?

    You need to configure the reference clock to be used during PHY mode using the device tree. It gets "activated" and used as needed, but the frequency that will be used is not configured by the module itself. It is the user's responsibility to set this up.

    Regards, Andreas