Support for Cadence xSPI Marvell modifications
Subsystems (2)
cover Support for Cadence xSPI Marvell modifications
This patch series is adding support for additional Marvell HW overlay build on top of Cadence xSPI IP It includes:
- Clock and PHY configuration
- ACPI support
- Additional MRVL HW overlay to support tranfer operations
Piyush Malgujar (1):
driver: spi: cadence: Add ACPI support
Witold Sadowski (4):
spi: cadence: Add new bindings documentation for Cadence XSPI
spi: cadence: Add Marvell IP modification changes
spi: cadence: Force single modebyte
cadence-xspi: Add xfer capabilities
.../devicetree/bindings/spi/cdns,xspi.yaml | 84 ++- drivers/spi/spi-cadence-xspi.c | 675 +++++++++++++++++- 2 files changed, 738 insertions(+), 21 deletions(-)
Signature · 1 line
2.17.1
PATCH 1/5 spi: cadence: Add new bindings documentation for Cadence XSPI
Add new bindings:
- mrvl,xspi-nor compatible string
Compatible string to enable Marvell XSPI modification
- Multiple PHY configuration registers
- base for xfer register set
--- .../devicetree/bindings/spi/cdns,xspi.yaml | 84 ++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-)
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +83 -1
@@ -20,23 +20,74 @@ allOf: properties: compatible: - const: cdns,xspi-nor + - const: cdns,xspi-nor + - const: mrvl,xspi-nor reg: items: - description: address and length of the controller register set - description: address and length of the Slave DMA data port - description: address and length of the auxiliary registers + - description: address and length of the xfer registers reg-names: items: - const: io - const: sdma - const: aux + - const: xferbase interrupts: maxItems: 1 + cdns,dll-phy-control: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x707 + + cdns,rfile-phy-control: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x40000 + + cdns,rfile-phy-tsel: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0 + + cdns,phy-dq-timing: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x101 + + cdns,phy-dqs-timing: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x700404 + + cdns,phy-gate-lpbk-ctrl: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x200030 + + cdns,phy-dll-master-ctrl: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x00800000 + + cdns,phy-dll-slave-ctrl: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x0000ff01 + required: - compatible - reg
@@ -68,6 +119,37 @@ examples: reg = <0>; }; + flash@1 { + compatible = "jedec,spi-nor"; + spi-max-frequency = <75000000>; + reg = <1>; + }; + }; + }; + - | + #include <dt-bindings/interrupt-controller/irq.h> + bus { + #address-cells = <2>; + #size-cells = <2>; + + xspi: spi@a0010000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "mrvl,xspi-nor"; + reg = <0x0 0xa0010000 0x0 0x1040>, + <0x0 0xb0000000 0x0 0x1000>, + <0x0 0xa0020000 0x0 0x100>; + <0x0 0xa0090000 0x0 0x100>; + reg-names = "io", "sdma", "aux", "xferbase"; + interrupts = <0 90 IRQ_TYPE_LEVEL_HIGH>; + interrupt-parent = <&gic>; + + flash@0 { + compatible = "jedec,spi-nor"; + spi-max-frequency = <75000000>; + reg = <0>; + }; + flash@1 { compatible = "jedec,spi-nor"; spi-max-frequency = <75000000>;
Signature · 1 line
2.17.1
Rob Herring
maintainerRe: [PATCH 1/5] spi: cadence: Add new bindings documentation for Cadence XSPI
Quoted 11 lines · Witold Sadowski
Add new bindings:
- mrvl,xspi-nor compatible string
Compatible string to enable Marvell XSPI modification
- Multiple PHY configuration registers
- base for xfer register setSigned-off-by Witold Sadowski <[email protected]>--- .../devicetree/bindings/spi/cdns,xspi.yaml | 84 ++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-)
My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check' on your patch (DT_CHECKER_FLAGS is new in v5.13):
yamllint warnings/errors:
dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/spi/cdns,xspi.yaml: properties:compatible: [{'const': 'cdns,xspi-nor'}, {'const': 'mrvl,xspi-nor'}] is not of type 'object', 'boolean'
from schema $id: http://json-schema.org/draft-07/schema#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/spi/cdns,xspi.yaml: properties:compatible: [{'const': 'cdns,xspi-nor'}, {'const': 'mrvl,xspi-nor'}] is not of type 'object', 'boolean'
from schema $id: http://devicetree.org/meta-schemas/keywords.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/spi/cdns,xspi.yaml: ignoring, error in schema: properties: compatible
Error: Documentation/devicetree/bindings/spi/cdns,xspi.example.dts:88.23-24 syntax error
FATAL ERROR: Unable to parse input tree
make[2]: *** [scripts/Makefile.lib:427: Documentation/devicetree/bindings/spi/cdns,xspi.example.dtb] Error 1
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [/builds/robherring/dt-review-ci/linux/Makefile:1430: dt_binding_check] Error 2
make: *** [Makefile:240: __sub-make] Error 2
doc reference errors (make refcheckdocs):
See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/[email protected]
The base for the series is generally the latest rc1. A different dependency should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above error(s), then make sure 'yamllint' is installed and dt-schema is up to date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note that DT_SCHEMA_FILES can be set to your schema file to speed up checking your schema. However, it must be unset to test all examples with your schema.
Re: [PATCH 1/5] spi: cadence: Add new bindings documentation for Cadence XSPI
In reply to Witold SadowskiQuoted 7 lines · Witold Sadowski
Add new bindings:
- mrvl,xspi-nor compatible string
Compatible string to enable Marvell XSPI modification
- Multiple PHY configuration registers
- base for xfer register setSigned-off-by Witold Sadowski <[email protected]>
Please use subject prefixes matching the subsystem. You can get them for example with git log --oneline -- DIRECTORY_OR_FILE on the directory your patch is touching.
Quoted 9 lines
--- .../devicetree/bindings/spi/cdns,xspi.yaml | 84 ++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-)Documentation/devicetree/bindings/spi/cdns,xspi.yaml +0
-0
Documentation/devicetree/bindings/spi/cdns,xspi.yaml allOf: · line 24
Quoted 6 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +2
-1@@ -20,23 +20,74 @@ allOf: properties: compatible: - const: cdns,xspi-nor + - const: cdns,xspi-nor + - const: mrvl,xspi-nor
It does not look like you tested the bindings, at least after quick look. Please run make dt_binding_check (see Documentation/devicetree/bindings/writing-schema.rst for instructions). Maybe you need to update your dtschema and yamllint.
There is a lot of things happening here, but I won't perform review if the code was never tested. Sorry, please test before sending.
Best regards,
Krzysztof
Re: [PATCH 1/5] spi: cadence: Add new bindings documentation for Cadence XSPI
On 30/03/2024 12:32, Krzysztof Kozlowski wrote:
...
Quoted 7 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml allOf: · line 24
Quoted 6 lines
properties:
compatible:Documentation/devicetree/bindings/spi/cdns,xspi.yaml +2
-1- const: cdns,xspi-nor + - const: cdns,xspi-nor + - const: mrvl,xspi-nor
Quoted 7 lines
It does not look like you tested the bindings, at least after quick look. Please run
make dt_binding_check(seeDocumentation/devicetree/bindings/writing-schema.rstfor instructions). Maybe you need to update your dtschema and yamllint.There is a lot of things happening here, but I won't perform review if the code was never tested. Sorry, please test before sending.
Hi,
You did not address any of the comments and build issues neither here nor in previous mailings. Starting from 2022, all previous comments look ignored and then after some time you send another v1 expecting us to do review of the same code with the same issues.
I gave it 1 month for some sort of response from you. None came.
Therefore let's be clear: I will automatically NAK any further version you send, based on assumption you ignored entire existing feedback. Before sending any new patches for this XSPI, please first respond to numerous emails you already got (from the last two years). That's way we will know that reviewer's feedback is being addressed.
Thank you for understanding.
Best regards,
Krzysztof
kernel test robot
build botRe: [PATCH 1/5] spi: cadence: Add new bindings documentation for Cadence XSPI
In reply to Witold Sadowskikernel test robot noticed the following build warnings:
Hi Witold,
kernel test robot noticed the following build warnings:
[auto build test WARNING on broonie-spi/for-next]
[also build test WARNING on linus/master v6.9-rc1 next-20240328] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Witold-Sadowski/spi-cadence-Add-new-bindings-documentation-for-Cadence-XSPI/20240330-035124 base: https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next patch link: https://lore.kernel.org/r/20240329194849.25554-2-wsadowski%40marvell.com patch subject: [PATCH 1/5] spi: cadence: Add new bindings documentation for Cadence XSPI compiler: loongarch64-linux-gcc (GCC) 13.2.0 reproduce: (https://download.01.org/0day-ci/archive/20240331/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
dtcheck warnings: (new ones prefixed by >>)
>> Documentation/devicetree/bindings/spi/cdns,xspi.yaml: properties:compatible: [{'const': 'cdns,xspi-nor'}, {'const': 'mrvl,xspi-nor'}] is not of type 'object', 'boolean'
from schema $id: http://json-schema.org/draft-07/schema#
>> Documentation/devicetree/bindings/spi/cdns,xspi.yaml: properties:compatible: [{'const': 'cdns,xspi-nor'}, {'const': 'mrvl,xspi-nor'}] is not of type 'object', 'boolean'
from schema $id: http://devicetree.org/meta-schemas/keywords.yaml#
--
>> Documentation/devicetree/bindings/spi/cdns,xspi.yaml: ignoring, error in schema: properties: compatible Documentation/devicetree/bindings/net/snps,dwmac.yaml: mac-mode: missing type definition
Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
PATCH 2/5 spi: cadence: Add Marvell IP modification changes
In reply to Witold SadowskiAdd support for Marvell IP modification - clock divider, and PHY config, and IRQ clearing.
Clock divider block is build into Cadence XSPI controller and is connected directly to 800MHz clock.
As PHY config is not set directly in IP block, driver can load custom PHY configuration values.
To correctly clear interrupt in Marvell implementation MSI-X must be cleared too.
--- drivers/spi/spi-cadence-xspi.c | 311 ++++++++++++++++++++++++++++++++- 1 file changed, 306 insertions(+), 5 deletions(-)
drivers/spi/spi-cadence-xspi.c +306 -5
@@ -189,6 +189,43 @@ ((op)->data.dir == SPI_MEM_DATA_IN) ? \ CDNS_XSPI_STIG_CMD_DIR_READ : CDNS_XSPI_STIG_CMD_DIR_WRITE)) +/*PHY default values*/ +#define REGS_DLL_PHY_CTRL 0x00000707 +#define CTB_RFILE_PHY_CTRL 0x00004000 +#define RFILE_PHY_TSEL 0x00000000 +#define RFILE_PHY_DQ_TIMING 0x00000101 +#define RFILE_PHY_DQS_TIMING 0x00700404 +#define RFILE_PHY_GATE_LPBK_CTRL 0x00200030 +#define RFILE_PHY_DLL_MASTER_CTRL 0x00800000 +#define RFILE_PHY_DLL_SLAVE_CTRL 0x0000ff01 + +/*PHY config rtegisters*/ +#define CDNS_XSPI_RF_MINICTRL_REGS_DLL_PHY_CTRL 0x1034 +#define CDNS_XSPI_PHY_CTB_RFILE_PHY_CTRL 0x0080 +#define CDNS_XSPI_PHY_CTB_RFILE_PHY_TSEL 0x0084 +#define CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DQ_TIMING 0x0000 +#define CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DQS_TIMING 0x0004 +#define CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_GATE_LPBK_CTRL 0x0008 +#define CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DLL_MASTER_CTRL 0x000c +#define CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DLL_SLAVE_CTRL 0x0010 +#define CDNS_XSPI_DATASLICE_RFILE_PHY_DLL_OBS_REG_0 0x001c + +#define CDNS_XSPI_DLL_RST_N BIT(24) +#define CDNS_XSPI_DLL_LOCK BIT(0) + +/* Marvell clock config register */ +#define CDNS_MRVL_XSPI_CLK_CTRL_AUX_REG 0x2020 +#define CDNS_MRVL_XSPI_CLK_ENABLE BIT(0) +#define CDNS_MRVL_XSPI_CLK_DIV GENMASK(4, 1) + +/* Marvell MSI-X clear interrupt register */ +#define CDNS_MRVL_XSPI_SPIX_INTR_AUX 0x2000 +#define CDNS_MRVL_MSIX_CLEAR_IRQ 0x01 + +/* Marvell clock macros */ +#define CDNS_MRVL_XSPI_CLOCK_IO_HZ 800000000 +#define CDNS_MRVL_XSPI_CLOCK_DIVIDED (div) ((CDNS_MRVL_XSPI_CLOCK_IO_HZ) / (div)) +enum cdns_xspi_stig_instr_type {CDNS_XSPI_STIG_INSTR_TYPE_0 ,CDNS_XSPI_STIG_INSTR_TYPE_1 ,
@@ -208,6 +245,7 @@ enum cdns_xspi_stig_cmd_dir {struct cdns_xspi_dev {struct platform_device *pdev;struct device *dev; +bool mrvl_hw_overlay;void __iomem *iobase;void __iomem *auxbase;
@@ -228,6 +266,157 @@ struct cdns_xspi_dev {u8 hw_num_banks; }; +#define MRVL_DEFAULT_CLK 25000000 + +const int cdns_mrvl_xspi_clk_div_list[] = { +4 ,//0x0 = Divide by 4. SPI clock is 200 MHz. +6 ,//0x1 = Divide by 6. SPI clock is 133.33 MHz. +8 ,//0x2 = Divide by 8. SPI clock is 100 MHz. +10 ,//0x3 = Divide by 10. SPI clock is 80 MHz. +12 ,//0x4 = Divide by 12. SPI clock is 66.666 MHz. +16 ,//0x5 = Divide by 16. SPI clock is 50 MHz. +18 ,//0x6 = Divide by 18. SPI clock is 44.44 MHz. +20 ,//0x7 = Divide by 20. SPI clock is 40 MHz. +24 ,//0x8 = Divide by 24. SPI clock is 33.33 MHz. +32 ,//0x9 = Divide by 32. SPI clock is 25 MHz. +40 ,//0xA = Divide by 40. SPI clock is 20 MHz. +50 ,//0xB = Divide by 50. SPI clock is 16 MHz. +64 ,//0xC = Divide by 64. SPI clock is 12.5 MHz. +128 ,//0xD = Divide by 128. SPI clock is 6.25 MHz. +-1 //End of list +}; + +static bool cdns_xspi_reset_dll (struct cdns_xspi_dev *cdns_xspi) +{ +u32 dll_cntrl =readl (cdns_xspi->iobase + +CDNS_XSPI_RF_MINICTRL_REGS_DLL_PHY_CTRL ); +u32 dll_lock; + +/*Reset DLL*/ + dll_cntrl |=CDNS_XSPI_DLL_RST_N ; +writel (dll_cntrl, cdns_xspi->iobase + +CDNS_XSPI_RF_MINICTRL_REGS_DLL_PHY_CTRL ); + +/*Wait for DLL lock*/ +return readl_relaxed_poll_timeout (cdns_xspi->iobase + +CDNS_XSPI_INTR_STATUS_REG , + dll_lock, ((dll_lock &CDNS_XSPI_DLL_LOCK ) ==1 ),10 ,10000 ); +} + +static void cdns_configure_phy_register_io (struct cdns_xspi_dev *cdns_xspi, +const char *prop_name, +u64 default_value,u64 offset) +{ +struct device_node *node_prop = cdns_xspi->pdev->dev.of_node; +u64 phy_cfg; + +if (of_property_read_u64 (node_prop, prop_name, &phy_cfg)) + phy_cfg = default_value; +writel (phy_cfg, + cdns_xspi->iobase + offset); +} + +static void cdns_configure_phy_register_aux (struct cdns_xspi_dev *cdns_xspi, +const char *prop_name, +u64 default_value,u64 offset) +{ +struct device_node *node_prop = cdns_xspi->pdev->dev.of_node; +u64 phy_cfg; + +if (of_property_read_u64 (node_prop,"cdns,dll-phy-control" , &phy_cfg)) + phy_cfg = default_value; +writel (phy_cfg, + cdns_xspi->auxbase + offset); +} + +//Static confiuration of PHY +static bool cdns_xspi_configure_phy (struct cdns_xspi_dev *cdns_xspi) +{ +cdns_configure_phy_register_io (cdns_xspi, +"cdns,dll-phy-control" , +REGS_DLL_PHY_CTRL , +CDNS_XSPI_RF_MINICTRL_REGS_DLL_PHY_CTRL ); +cdns_configure_phy_register_aux (cdns_xspi, +"cdns,rfile-phy-control" , +CTB_RFILE_PHY_CTRL , +CDNS_XSPI_PHY_CTB_RFILE_PHY_CTRL ); +cdns_configure_phy_register_aux (cdns_xspi, +"cdns,rfile-phy-tsel" , +RFILE_PHY_TSEL , +CDNS_XSPI_PHY_CTB_RFILE_PHY_TSEL ); +cdns_configure_phy_register_aux (cdns_xspi, +"cdns,phy-dq-timing" , +RFILE_PHY_DQ_TIMING , +CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DQ_TIMING ); +cdns_configure_phy_register_aux (cdns_xspi, +"cdns,phy-dqs-timing" , +RFILE_PHY_DQS_TIMING , +CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DQS_TIMING ); +cdns_configure_phy_register_aux (cdns_xspi, +"cdns,phy-gate-lpbk-ctrl" , +RFILE_PHY_GATE_LPBK_CTRL , +CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_GATE_LPBK_CTRL ); +cdns_configure_phy_register_aux (cdns_xspi, +"cdns,phy-dll-master-ctrl" , +RFILE_PHY_DLL_MASTER_CTRL , +CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_GATE_LPBK_CTRL ); +cdns_configure_phy_register_aux (cdns_xspi, +"cdns,phy-dll-slave-ctrl" , +RFILE_PHY_DLL_SLAVE_CTRL , +CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DLL_SLAVE_CTRL ); + +return cdns_xspi_reset_dll (cdns_xspi); +} + +// Find max avalible clock +static bool cdns_mrvl_xspi_setup_clock (struct cdns_xspi_dev *cdns_xspi, +int requested_clk) +{ +int i =0 ; +int clk_val; +u32 clk_reg; +bool update_clk = false; + +while (cdns_mrvl_xspi_clk_div_list[i] >0 ) { + clk_val =CDNS_MRVL_XSPI_CLOCK_DIVIDED ( + cdns_mrvl_xspi_clk_div_list[i]); +if (clk_val <= requested_clk) +break ; + i++; + } + +if (cdns_mrvl_xspi_clk_div_list[i] ==-1 ) { +dev_info (cdns_xspi->dev, +"Unable to find clk div for CLK: %d - using 6.25MHz\n" , + requested_clk); + i =0x0D ; + }else { +dev_dbg (cdns_xspi->dev,"Found clk div: %d, clk val: %d\n" , + cdns_mrvl_xspi_clk_div_list[i], +CDNS_MRVL_XSPI_CLOCK_DIVIDED ( + cdns_mrvl_xspi_clk_div_list[i])); + } + + clk_reg =readl (cdns_xspi->auxbase +CDNS_MRVL_XSPI_CLK_CTRL_AUX_REG ); + +if (FIELD_GET (CDNS_MRVL_XSPI_CLK_DIV , clk_reg) != i) { + clk_reg &= ~CDNS_MRVL_XSPI_CLK_ENABLE ; +writel (clk_reg, + cdns_xspi->auxbase +CDNS_MRVL_XSPI_CLK_CTRL_AUX_REG ); + clk_reg =FIELD_PREP (CDNS_MRVL_XSPI_CLK_DIV , i); + clk_reg &= ~CDNS_MRVL_XSPI_CLK_DIV ; + clk_reg |=FIELD_PREP (CDNS_MRVL_XSPI_CLK_DIV , i); + clk_reg |=CDNS_MRVL_XSPI_CLK_ENABLE ; + update_clk = true; + } + +if (update_clk) +writel (clk_reg, + cdns_xspi->auxbase +CDNS_MRVL_XSPI_CLK_CTRL_AUX_REG ); + +return update_clk; +} +static int cdns_xspi_wait_for_controller_idle (struct cdns_xspi_dev *cdns_xspi) {u32 ctrl_stat;
@@ -291,6 +480,10 @@ static void cdns_xspi_set_interrupts(struct cdns_xspi_dev *cdns_xspi, bool enabled) {u32 intr_enable; +u32 irq_status; + + irq_status =readl (cdns_xspi->iobase +CDNS_XSPI_INTR_STATUS_REG ); +writel (irq_status, cdns_xspi->iobase +CDNS_XSPI_INTR_STATUS_REG ); intr_enable =readl (cdns_xspi->iobase +CDNS_XSPI_INTR_ENABLE_REG );if (enabled)
@@ -315,6 +508,9 @@ static int cdns_xspi_controller_init(struct cdns_xspi_dev *cdns_xspi)return -EIO ; } +writel (FIELD_PREP (CDNS_XSPI_CTRL_WORK_MODE ,CDNS_XSPI_WORK_MODE_STIG ), + cdns_xspi->iobase +CDNS_XSPI_CTRL_CONFIG_REG ); + ctrl_features =readl (cdns_xspi->iobase +CDNS_XSPI_CTRL_FEATURES_REG ); cdns_xspi->hw_num_banks =FIELD_GET (CDNS_XSPI_NUM_BANKS , ctrl_features);cdns_xspi_set_interrupts (cdns_xspi, false);
@@ -322,6 +518,70 @@ static int cdns_xspi_controller_init(struct cdns_xspi_dev *cdns_xspi)return 0 ; } +static void mrvl_ioreadq (void __iomem *addr,void *buf,int len) +{ +int i =0 ; +int rcount = len /8 ; +int rcount_nf = len %8 ; +uint64_t tmp; +uint64_t *buf64 = (uint64_t *)buf; + +if (((uint64_t )buf %8 ) ==0 ) { +for (i =0 ; i < rcount; i++) + *buf64++ =readq (addr); + }else { +for (i =0 ; i < rcount; i++) { + tmp =readq (addr); +memcpy (buf+(i*8 ), &tmp,8 ); + } + } + +if (rcount_nf !=0 ) { + tmp =readq (addr); +memcpy (buf+(i*8 ), &tmp, rcount_nf); + } +} + +static void mrvl_iowriteq (void __iomem *addr,const void *buf,int len) +{ +int i =0 ; +int rcount = len /8 ; +int rcount_nf = len %8 ; +uint64_t tmp; +uint64_t *buf64 = (uint64_t *)buf; + +if (((uint64_t )buf %8 ) ==0 ) { +for (i =0 ; i < rcount; i++) +writeq (*buf64++, addr); + }else { +for (i =0 ; i < rcount; i++) { +memcpy (&tmp, buf+(i*8 ),8 ); +writeq (tmp, addr); + } + } + +if (rcount_nf !=0 ) { +memcpy (&tmp, buf+(i*8 ), rcount_nf); +writeq (tmp, addr); + } +} + +static void cdns_xspi_sdma_memread (struct cdns_xspi_dev *cdns_xspi,int len) +{ +if (cdns_xspi->mrvl_hw_overlay) +mrvl_ioreadq (cdns_xspi->sdmabase, cdns_xspi->in_buffer, len); +else +ioread8_rep (cdns_xspi->sdmabase, cdns_xspi->in_buffer, len); +} + +static void cdns_xspi_sdma_memwrite (struct cdns_xspi_dev *cdns_xspi,int len) +{ +if (cdns_xspi->mrvl_hw_overlay) +mrvl_iowriteq (cdns_xspi->sdmabase, cdns_xspi->out_buffer, len); +else +iowrite8_rep (cdns_xspi->sdmabase, cdns_xspi->out_buffer, len); +} +static void cdns_xspi_sdma_handle (struct cdns_xspi_dev *cdns_xspi) {u32 sdma_size, sdma_trd_info;
@@ -333,13 +593,11 @@ static void cdns_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi)switch (sdma_dir) {case CDNS_XSPI_SDMA_DIR_READ : -ioread8_rep (cdns_xspi->sdmabase, - cdns_xspi->in_buffer, sdma_size); +cdns_xspi_sdma_memread (cdns_xspi, sdma_size);break ;case CDNS_XSPI_SDMA_DIR_WRITE : -iowrite8_rep (cdns_xspi->sdmabase, - cdns_xspi->out_buffer, sdma_size); +cdns_xspi_sdma_memwrite (cdns_xspi, sdma_size);break ; } }
@@ -411,6 +669,9 @@ static int cdns_xspi_mem_op(struct cdns_xspi_dev *cdns_xspi,if (cdns_xspi->cur_cs !=spi_get_chipselect (mem->spi,0 )) cdns_xspi->cur_cs =spi_get_chipselect (mem->spi,0 ); +if (cdns_xspi->mrvl_hw_overlay) +cdns_mrvl_xspi_setup_clock (cdns_xspi, mem->spi->max_speed_hz); +return cdns_xspi_send_stig_command (cdns_xspi, op, (dir !=SPI_MEM_NO_DATA )); }
@@ -451,6 +712,10 @@ static irqreturn_t cdns_xspi_irq_handler(int this_irq, void *dev) irq_status =readl (cdns_xspi->iobase +CDNS_XSPI_INTR_STATUS_REG );writel (irq_status, cdns_xspi->iobase +CDNS_XSPI_INTR_STATUS_REG ); +if (cdns_xspi->mrvl_hw_overlay) +writel (CDNS_MRVL_MSIX_CLEAR_IRQ , + cdns_xspi->auxbase +CDNS_MRVL_XSPI_SPIX_INTR_AUX ); +if (irq_status & (CDNS_XSPI_SDMA_ERROR |CDNS_XSPI_SDMA_TRIGGER |CDNS_XSPI_STIG_DONE )) {
@@ -524,6 +789,27 @@ static void cdns_xspi_print_phy_config(struct cdns_xspi_dev *cdns_xspi) readl(cdns_xspi->auxbase + CDNS_XSPI_CCP_PHY_DLL_SLAVE_CTRL)); } +static int cdns_xspi_setup (struct spi_device *spi_dev) +{ +struct cdns_xspi_dev *cdns_xspi =spi_master_get_devdata (spi_dev->master); + +if (cdns_xspi->mrvl_hw_overlay) +cdns_mrvl_xspi_setup_clock (cdns_xspi, spi_dev->max_speed_hz); + +return 0 ; +} + +static bool cdns_xspi_get_hw_overlay (struct platform_device *pdev) +{ +int err; + + err =device_property_match_string (&pdev->dev, +"compatible" ,"mrvl,xspi-nor" ); + + +return (err >=0 ); +} +static int cdns_xspi_probe (struct platform_device *pdev) {struct device *dev = &pdev->dev;
@@ -531,6 +817,7 @@ static int cdns_xspi_probe(struct platform_device *pdev)struct cdns_xspi_dev *cdns_xspi =NULL ;struct resource *res;int ret; +bool hw_overlay; host =devm_spi_alloc_host (dev,sizeof (*cdns_xspi));if (!host)
@@ -540,10 +827,15 @@ static int cdns_xspi_probe(struct platform_device *pdev)SPI_RX_DUAL |SPI_RX_QUAD |SPI_TX_OCTAL |SPI_RX_OCTAL |SPI_MODE_0 |SPI_MODE_3 ; + hw_overlay =cdns_xspi_get_hw_overlay (pdev); + host->mem_ops = &cadence_xspi_mem_ops; host->dev.of_node = pdev->dev.of_node; host->bus_num =-1 ; +if (hw_overlay) + host->setup = cdns_xspi_setup; +platform_set_drvdata (pdev, host); cdns_xspi =spi_controller_get_devdata (host);
@@ -555,6 +847,8 @@ static int cdns_xspi_probe(struct platform_device *pdev)init_completion (&cdns_xspi->auto_cmd_complete);init_completion (&cdns_xspi->sdma_complete); + cdns_xspi->mrvl_hw_overlay = hw_overlay; + ret =cdns_xspi_of_get_plat_data (pdev);if (ret)return -ENODEV ;
@@ -588,8 +882,12 @@ static int cdns_xspi_probe(struct platform_device *pdev)return ret; } -cdns_xspi_print_phy_config (cdns_xspi); +if (hw_overlay) { +cdns_mrvl_xspi_setup_clock (cdns_xspi,MRVL_DEFAULT_CLK ); +cdns_xspi_configure_phy (cdns_xspi); + } +cdns_xspi_print_phy_config (cdns_xspi); ret =cdns_xspi_controller_init (cdns_xspi);if (ret) {dev_err (dev,"Failed to initialize controller\n" );
@@ -613,6 +911,9 @@ static const struct of_device_id cdns_xspi_of_match[] = { { .compatible = "cdns,xspi-nor", }, + { + .compatible = "mrvl,xspi-nor", + }, {/* end of table */ } };MODULE_DEVICE_TABLE (of, cdns_xspi_of_match);
Signature · 1 line
2.17.1
Re: [PATCH 2/5] spi: cadence: Add Marvell IP modification changes
Quoted 8 lines · Witold Sadowski
Add support for Marvell IP modification - clock divider, and PHY config, and IRQ clearing.
Clock divider block is build into Cadence XSPI controller and is connected directly to 800MHz clock.
As PHY config is not set directly in IP block, driver can load custom PHY configuration values.
To correctly clear interrupt in Marvell implementation MSI-X must be cleared too.
Please wrap commit message according to Linux coding style / submission process (neither too early nor over the limit):
https://elixir.bootlin.com/linux/v6.4-rc1/source/Documentation/process/submitting-patches.rst#L597
drivers/spi/spi-cadence-xspi.c static void cdns_xspi_print_phy_config(struct cdns_xspi_dev *cdns_xspi) · line 807
Quoted 12 lines
Signed-off-by Witold Sadowski <[email protected]>---
drivers/spi/spi-cadence-xspi.c +7
-0+ +static bool cdns_xspi_get_hw_overlay (struct platform_device *pdev) +{ +int err; + + err =device_property_match_string (&pdev->dev, +"compatible" ,"mrvl,xspi-nor" );
No, do not add matching in some random parts of the code, but use driver match/data from ID table.
....
drivers/spi/spi-cadence-xspi.c static const struct of_device_id cdns_xspi_of_match[] = { · line 915
Quoted 11 lines
drivers/spi/spi-cadence-xspi.c +3
-0+cdns_xspi_print_phy_config (cdns_xspi); ret =cdns_xspi_controller_init (cdns_xspi);if (ret) {dev_err (dev,"Failed to initialize controller\n" );@@ -613,6 +911,9 @@ static const struct of_device_id cdns_xspi_of_match[] = { { .compatible = "cdns,xspi-nor", }, + { + .compatible = "mrvl,xspi-nor",
This falsely suggest they are compatible :/
drivers/spi/spi-cadence-xspi.c static const struct of_device_id cdns_xspi_of_match[] = { · line 919
Quoted 4 lines
drivers/spi/spi-cadence-xspi.c +1
-0+ }, {/* end of table */ } };MODULE_DEVICE_TABLE (of, cdns_xspi_of_match);
Best regards,
Krzysztof
RE: [EXTERNAL] Re: [PATCH 2/5] spi: cadence: Add Marvell IP modification changes
Quoted 26 lines
----------------------------------------------------------------------
Quoted 8 lines · Witold Sadowski
Add support for Marvell IP modification - clock divider, and PHY config, and IRQ clearing.
Clock divider block is build into Cadence XSPI controller and is connected directly to 800MHz clock.
As PHY config is not set directly in IP block, driver can load custom PHY configuration values.
To correctly clear interrupt in Marvell implementation MSI-X must be cleared too.Please wrap commit message according to Linux coding style / submission process (neither too early nor over the limit):
https://urldefense.proofpoint.com/v2/url?u=https-
3A__elixir.bootlin.com_linux_v6.4- 2Drc1_source_Documentation_process_submitting-2Dpatches.rst- 23L597&d=DwICaQ&c=nKjWec2b6R0mOyPaz7xtfQ&r=GKgcn-g6ZX- JmCL3S2qKgVQhvhv7hu2n8En- dZbLTa8&m=jNf5MYEcexHML6io2koiqn18Pmkh2qqc0FL48zdCoojbFX06omzl2_Z0CpBeHn79 &s=B038dgBUB0Gvl63ExMDFoXuomZBSZPHLpScHOtTax0Q&e=Quoted 3 lines
Signed-off-by Witold Sadowski <[email protected]>---
Quoted 9 lines
drivers/spi/spi-cadence-xspi.c static void cdns_xspi_print_phy_config(struct cdns_xspi_dev *cdns_xspi) · line 807
Quoted 6 lines
drivers/spi/spi-cadence-xspi.c +6
-0+ +static bool cdns_xspi_get_hw_overlay (struct platform_device *pdev) { +int err; + + err =device_property_match_string (&pdev->dev, +"compatible" ,"mrvl,xspi-nor" );No, do not add matching in some random parts of the code, but use driver match/data from ID table.
Ok. As I have written in different mail, a little bit of manual matching Will be necessary to handle both ACPI and device-tree case.
Quoted 9 lines
....
drivers/spi/spi-cadence-xspi.c static int cdns_xspi_probe(struct platform_device *pdev)
Quoted 5 lines
drivers/spi/spi-cadence-xspi.c +1
-0+cdns_xspi_print_phy_config (cdns_xspi); ret =cdns_xspi_controller_init (cdns_xspi);if (ret) { dev_err(dev, "Failed to initialize controller\n"); @@ -613,6+911,9
Quoted 8 lines
drivers/spi/spi-cadence-xspi.c static const struct of_device_id cdns_xspi_of_match[] = { · line 915
Quoted 6 lines
@@ static const struct
of_device_idcdns_xspi_of_match[] = {drivers/spi/spi-cadence-xspi.c +2
-0{ .compatible = "cdns,xspi-nor", }, + { + .compatible = "mrvl,xspi-nor",This falsely suggest they are compatible :/
I'm not sure if I understand what do you mean.
cdns, xspi will be compatible with overlay, as it won't touch any additional HW. It possibly fail in second direction, as overlay handling code will not see expected values.
Quoted 8 lines
drivers/spi/spi-cadence-xspi.c static const struct of_device_id cdns_xspi_of_match[] = { · line 919
Quoted 5 lines
drivers/spi/spi-cadence-xspi.c +1
-0+ }, {/* end of table */ } };MODULE_DEVICE_TABLE (of, cdns_xspi_of_match);Best regards,
Krzysztof
Regards
Witek
Re: [EXTERNAL] Re: [PATCH 2/5] spi: cadence: Add Marvell IP modification changes
Quoted 11 lines · Witold Sadowski
Quoted 10 lines
drivers/spi/spi-cadence-xspi.c static void cdns_xspi_print_phy_config(struct cdns_xspi_dev *cdns_xspi) · line 807
Quoted 7 lines
drivers/spi/spi-cadence-xspi.c +6
-0+ +static bool cdns_xspi_get_hw_overlay (struct platform_device *pdev) { +int err; + + err =device_property_match_string (&pdev->dev, +"compatible" ,"mrvl,xspi-nor" );No, do not add matching in some random parts of the code, but use driver match/data from ID table.
Quoted 2 lines
Ok. As I have written in different mail, a little bit of manual matching Will be necessary to handle both ACPI and device-tree case.
ACPI also handle variants with match data.
Quoted 19 lines
Quoted 10 lines
....
drivers/spi/spi-cadence-xspi.c static int cdns_xspi_probe(struct platform_device *pdev)
Quoted 5 lines
drivers/spi/spi-cadence-xspi.c +1
-0+cdns_xspi_print_phy_config (cdns_xspi); ret =cdns_xspi_controller_init (cdns_xspi);if (ret) { dev_err(dev, "Failed to initialize controller\n"); @@ -613,6+911,9
Quoted 8 lines
drivers/spi/spi-cadence-xspi.c static const struct of_device_id cdns_xspi_of_match[] = { · line 915
Quoted 6 lines
@@ static const struct
of_device_idcdns_xspi_of_match[] = {drivers/spi/spi-cadence-xspi.c +2
-0{ .compatible = "cdns,xspi-nor", }, + { + .compatible = "mrvl,xspi-nor",This falsely suggest they are compatible :/
Quoted 4 lines
I'm not sure if I understand what do you mean.
cdns, xspi will be compatible with overlay, as it won't touch any additional HW. It possibly fail in second direction, as overlay handling code will not see expected values.
That's clear rule for almost every driver: if you do not have any match data, it suggests entry is redundant, because devices are compatible. There is no different treatment for SPI. As seen in other pieces of this code, devices are not compatible, so it points to missing match data to handle variants.
Best regards,
Krzysztof
kernel test robot
build botRe: [PATCH 2/5] spi: cadence: Add Marvell IP modification changes
In reply to Witold Sadowskikernel test robot noticed the following build errors:
Hi Witold,
kernel test robot noticed the following build errors:
[auto build test ERROR on broonie-spi/for-next]
[also build test ERROR on linus/master v6.9-rc1 next-20240328] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Witold-Sadowski/spi-cadence-Add-new-bindings-documentation-for-Cadence-XSPI/20240330-035124 base: https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next patch link: https://lore.kernel.org/r/20240329194849.25554-3-wsadowski%40marvell.com patch subject: [PATCH 2/5] spi: cadence: Add Marvell IP modification changes config: i386-randconfig-141-20240330 (https://download.01.org/0day-ci/archive/20240331/[email protected]/config) compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240331/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All errors (new ones prefixed by >>):
>> drivers/spi/spi-cadence-xspi.c:531:15: error: call to undeclared function 'readq'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
531 | *buf64++ = readq(addr);
| ^
drivers/spi/spi-cadence-xspi.c:534:10: error: call to undeclared function 'readq'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
534 | tmp = readq(addr);
| ^
drivers/spi/spi-cadence-xspi.c:540:9: error: call to undeclared function 'readq'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
540 | tmp = readq(addr);
| ^
>> drivers/spi/spi-cadence-xspi.c:555:4: error: call to undeclared function 'writeq'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
555 | writeq(*buf64++, addr);
| ^
drivers/spi/spi-cadence-xspi.c:559:4: error: call to undeclared function 'writeq'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
559 | writeq(tmp, addr);
| ^
drivers/spi/spi-cadence-xspi.c:565:3: error: call to undeclared function 'writeq'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
565 | writeq(tmp, addr);
| ^
>> drivers/spi/spi-cadence-xspi.c:794:36: error: call to undeclared function 'spi_master_get_devdata'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
794 | struct cdns_xspi_dev *cdns_xspi = spi_master_get_devdata(spi_dev->master);
| ^
drivers/spi/spi-cadence-xspi.c:794:36: note: did you mean 'spi_mem_get_drvdata'?
include/linux/spi/spi-mem.h:224:21: note: 'spi_mem_get_drvdata' declared here
224 | static inline void *spi_mem_get_drvdata(struct spi_mem *mem)
| ^
>> drivers/spi/spi-cadence-xspi.c:794:68: error: no member named 'master' in 'struct spi_device' 794 | struct cdns_xspi_dev *cdns_xspi = spi_master_get_devdata(spi_dev->master);
| ~~~~~~~ ^
8 errors generated.
vim +/readq +531 drivers/spi/spi-cadence-xspi.c
520
521 static void mrvl_ioreadq(void __iomem *addr, void *buf, int len)
522 {
523 int i = 0;
524 int rcount = len / 8;
525 int rcount_nf = len % 8;
526 uint64_t tmp;
527 uint64_t *buf64 = (uint64_t *)buf;
528
529 if (((uint64_t)buf % 8) == 0) {
530 for (i = 0; i < rcount; i++)
> 531 *buf64++ = readq(addr);
532 } else {
533 for (i = 0; i < rcount; i++) {
534 tmp = readq(addr);
535 memcpy(buf+(i*8), &tmp, 8);
536 }
537 }
538
539 if (rcount_nf != 0) {
540 tmp = readq(addr);
541 memcpy(buf+(i*8), &tmp, rcount_nf);
542 }
543 }
544
545 static void mrvl_iowriteq(void __iomem *addr, const void *buf, int len)
546 {
547 int i = 0;
548 int rcount = len / 8;
549 int rcount_nf = len % 8;
550 uint64_t tmp;
551 uint64_t *buf64 = (uint64_t *)buf;
552
553 if (((uint64_t)buf % 8) == 0) {
554 for (i = 0; i < rcount; i++)
> 555 writeq(*buf64++, addr); 556 } else {
557 for (i = 0; i < rcount; i++) {
558 memcpy(&tmp, buf+(i*8), 8);
559 writeq(tmp, addr);
560 }
561 }
562
563 if (rcount_nf != 0) {
564 memcpy(&tmp, buf+(i*8), rcount_nf);
565 writeq(tmp, addr);
566 }
567 }
568
Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
Re: [PATCH 2/5] spi: cadence: Add Marvell IP modification changes
In reply to Witold SadowskiQuoted 9 lines · Witold Sadowski
Add support for Marvell IP modification - clock divider, and PHY config, and IRQ clearing.
Clock divider block is build into Cadence XSPI controller and is connected directly to 800MHz clock.
As PHY config is not set directly in IP block, driver can load custom PHY configuration values.
To correctly clear interrupt in Marvell implementation MSI-X must be cleared too.
Quoted 3 lines
Signed-off-by Witold Sadowski <[email protected]>--- drivers/spi/spi-cadence-xspi.c | 311 ++++++++++++++++++++++++++++++++-
You already sent this patchset, so this is not v1. Please version your patches correctly. b4 does it automatically.
You also received last time feedback which it seems you just ignored. You did not respond to any of the feedback and I do not see it being addressed here.
That's not how collaboration in upstream projects work. Don't just ignore reviews you receive. Please carefully read:
https://elixir.bootlin.com/linux/v6.9-rc1/source/Documentation/process/submitting-patches.rst
There is also entire section about this particular issue - responding to reviewers.
Best regards,
Krzysztof
PATCH 3/5 spi: cadence: Force single modebyte
In reply to Witold SadowskiDuring dummy-cycles xSPI will switch GPIO into Hi-Z mode. To prevent unforeseen consequences of that behaviour, force send single modebyte(0x00).
Modebyte will be send only if number of dummy-cycles is not equal to 0. Code must also reduce dummycycle byte count by one - as one byte is send as modebyte.
--- drivers/spi/spi-cadence-xspi.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-)
drivers/spi/spi-cadence-xspi.c +15 -5
@@ -145,6 +145,9 @@#define CDNS_XSPI_STIG_DONE_FLAG BIT(0)#define CDNS_XSPI_TRD_STATUS 0x0104 +#define MODE_NO_OF_BYTES GENMASK(25, 24) +#define MODEBYTES_COUNT 1 +/* Helper macros for filling command registers */ #define CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_1 (op, data_phase) ( \ FIELD_PREP(CDNS_XSPI_CMD_INSTR_TYPE, (data_phase) ? \
@@ -157,9 +160,10 @@ FIELD_PREP(CDNS_XSPI_CMD_P1_R2_ADDR3, ((op)->addr.val >> 24) & 0xFF) | \ FIELD_PREP(CDNS_XSPI_CMD_P1_R2_ADDR4, ((op)->addr.val >> 32) & 0xFF)) -#define CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_3 (op) ( \ +#define CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_3 (op, modebytes) ( \ FIELD_PREP(CDNS_XSPI_CMD_P1_R3_ADDR5, ((op)->addr.val >> 40) & 0xFF) | \ FIELD_PREP(CDNS_XSPI_CMD_P1_R3_CMD, (op)->cmd.opcode) | \ + FIELD_PREP(MODE_NO_OF_BYTES, modebytes) | \ FIELD_PREP(CDNS_XSPI_CMD_P1_R3_NUM_ADDR_BYTES, (op)->addr.nbytes))#define CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_4 (op, chipsel) ( \
@@ -173,12 +177,12 @@#define CDNS_XSPI_CMD_FLD_DSEQ_CMD_2 (op) \ FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R2_DCNT_L, (op)->data.nbytes & 0xFFFF) -#define CDNS_XSPI_CMD_FLD_DSEQ_CMD_3 (op) ( \ +#define CDNS_XSPI_CMD_FLD_DSEQ_CMD_3 (op, dummybytes) ( \ FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R3_DCNT_H, \ ((op)->data.nbytes >> 16) & 0xffff) | \ FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R3_NUM_OF_DUMMY, \ (op)->dummy.buswidth != 0 ? \ - (((op)->dummy.nbytes * 8) / (op)->dummy.buswidth) : \ + (((dummybytes) * 8) / (op)->dummy.buswidth) : \ 0))#define CDNS_XSPI_CMD_FLD_DSEQ_CMD_4 (op, chipsel) ( \
@@ -609,6 +613,7 @@ static int cdns_xspi_send_stig_command(struct cdns_xspi_dev *cdns_xspi,u32 cmd_regs[6 ];u32 cmd_status;int ret; +int dummybytes = op->dummy.nbytes; ret =cdns_xspi_wait_for_controller_idle (cdns_xspi);if (ret <0 )
@@ -623,7 +628,12 @@ static int cdns_xspi_send_stig_command(struct cdns_xspi_dev *cdns_xspi,memset (cmd_regs,0 ,sizeof (cmd_regs)); cmd_regs[1 ] =CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_1 (op, data_phase); cmd_regs[2 ] =CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_2 (op); - cmd_regs[3 ] =CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_3 (op); +if (dummybytes !=0 ) { + cmd_regs[3 ] =CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_3 (op,1 ); + dummybytes--; + }else { + cmd_regs[3 ] =CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_3 (op,0 ); + } cmd_regs[4 ] =CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_4 (op, cdns_xspi->cur_cs);
@@ -633,7 +643,7 @@ static int cdns_xspi_send_stig_command(struct cdns_xspi_dev *cdns_xspi, cmd_regs[0 ] =CDNS_XSPI_STIG_DONE_FLAG ; cmd_regs[1 ] =CDNS_XSPI_CMD_FLD_DSEQ_CMD_1 (op); cmd_regs[2 ] =CDNS_XSPI_CMD_FLD_DSEQ_CMD_2 (op); - cmd_regs[3 ] =CDNS_XSPI_CMD_FLD_DSEQ_CMD_3 (op); + cmd_regs[3 ] =CDNS_XSPI_CMD_FLD_DSEQ_CMD_3 (op, dummybytes); cmd_regs[4 ] =CDNS_XSPI_CMD_FLD_DSEQ_CMD_4 (op, cdns_xspi->cur_cs);
Signature · 1 line
2.17.1
PATCH 4/5 driver: spi: cadence: Add ACPI support
In reply to Witold SadowskiFrom: Piyush Malgujar <[email protected]>
These changes enables to read the configs from ACPI tables as required for successful probing in ACPI uefi environment. In case of ACPI disabled/dts based environment, it will continue to read configs from dts as before.
--- drivers/spi/spi-cadence-xspi.c | 97 ++++++++++++++++++++++++++++++---- 1 file changed, 86 insertions(+), 11 deletions(-)
drivers/spi/spi-cadence-xspi.c +86 -11
@@ -2,6 +2,7 @@// Cadence XSPI flash controller driver // Copyright (C) 2020-21 Cadence +#include <linux/acpi.h> #include <linux/completion.h> #include <linux/delay.h> #include <linux/err.h>
@@ -14,6 +15,7 @@#include <linux/of.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> +#include <linux/property.h> #include <linux/spi/spi.h> #include <linux/spi/spi-mem.h> #include <linux/bitfield.h>
@@ -686,6 +688,67 @@ static int cdns_xspi_mem_op(struct cdns_xspi_dev *cdns_xspi, (dir != SPI_MEM_NO_DATA)); } +#ifdef CONFIG_ACPI +static bool cdns_xspi_supports_op (struct spi_mem *mem, +const struct spi_mem_op *op) +{ +struct spi_device *spi = mem->spi; +const union acpi_object *obj; +struct acpi_device *adev; + + adev =ACPI_COMPANION (&spi->dev); + +if (!acpi_dev_get_property (adev,"spi-tx-bus-width" ,ACPI_TYPE_INTEGER , + &obj)) { +switch (obj->integer.value) { +case 1 : +break ; +case 2 : + spi->mode |=SPI_TX_DUAL ; +break ; +case 4 : + spi->mode |=SPI_TX_QUAD ; +break ; +case 8 : + spi->mode |=SPI_TX_OCTAL ; +break ; +default : +dev_warn (&spi->dev, +"spi-tx-bus-width %lld not supported\n" , + obj->integer.value); +break ; + } + } + +if (!acpi_dev_get_property (adev,"spi-rx-bus-width" ,ACPI_TYPE_INTEGER , + &obj)) { +switch (obj->integer.value) { +case 1 : +break ; +case 2 : + spi->mode |=SPI_RX_DUAL ; +break ; +case 4 : + spi->mode |=SPI_RX_QUAD ; +break ; +case 8 : + spi->mode |=SPI_RX_OCTAL ; +break ; +default : +dev_warn (&spi->dev, +"spi-rx-bus-width %lld not supported\n" , + obj->integer.value); +break ; + } + } + +if (!spi_mem_default_supports_op (mem, op)) +return false; + +return true; +} +#endif +static int cdns_xspi_mem_op_execute (struct spi_mem *mem,const struct spi_mem_op *op) {
@@ -709,6 +772,9 @@ static int cdns_xspi_adjust_mem_op_size(struct spi_mem *mem, struct spi_mem_op * }static const struct spi_controller_mem_ops cadence_xspi_mem_ops = { +#ifdef CONFIG_ACPI + .supports_op = cdns_xspi_supports_op, +#endif .exec_op = cdns_xspi_mem_op_execute, .adjust_op_size = cdns_xspi_adjust_mem_op_size, };
@@ -760,21 +826,20 @@ static irqreturn_t cdns_xspi_irq_handler(int this_irq, void *dev)static int cdns_xspi_of_get_plat_data (struct platform_device *pdev) { -struct device_node *node_prop = pdev->dev.of_node; -struct device_node *node_child; +struct fwnode_handle *fwnode_child;unsigned int cs; -for_each_child_of_node (node_prop, node_child) { -if (!of_device_is_available (node_child)) +device_for_each_child_node (&pdev->dev, fwnode_child) { +if (!fwnode_device_is_available (fwnode_child))continue ; -if (of_property_read_u32 (node_child,"reg" , &cs)) { +if (fwnode_property_read_u32 (fwnode_child,"reg" , &cs)) {dev_err (&pdev->dev,"Couldn't get memory chip select\n" ); -of_node_put (node_child); +fwnode_handle_put (fwnode_child);return -ENXIO ; }else if (cs >=CDNS_XSPI_MAX_BANKS ) {dev_err (&pdev->dev,"reg (cs) parameter value too large\n" ); -of_node_put (node_child); +fwnode_handle_put (fwnode_child);return -ENXIO ; } }
@@ -816,7 +881,6 @@ static bool cdns_xspi_get_hw_overlay(struct platform_device *pdev) err =device_property_match_string (&pdev->dev,"compatible" ,"mrvl,xspi-nor" ); -return (err >=0 ); }
@@ -841,6 +905,7 @@ static int cdns_xspi_probe(struct platform_device *pdev) host->mem_ops = &cadence_xspi_mem_ops; host->dev.of_node = pdev->dev.of_node; + host->dev.fwnode = pdev->dev.fwnode; host->bus_num =-1 ;if (hw_overlay)
@@ -863,19 +928,21 @@ static int cdns_xspi_probe(struct platform_device *pdev)if (ret)return -ENODEV ; - cdns_xspi->iobase =devm_platform_ioremap_resource_byname (pdev,"io" ); + res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); + cdns_xspi->iobase =devm_ioremap_resource (dev, res);if (IS_ERR (cdns_xspi->iobase)) {dev_err (dev,"Failed to remap controller base address\n" );return PTR_ERR (cdns_xspi->iobase); } - res =platform_get_resource_byname (pdev,IORESOURCE_MEM ,"sdma" ); + res =platform_get_resource (pdev,IORESOURCE_MEM ,1 ); cdns_xspi->sdmabase =devm_ioremap_resource (dev, res);if (IS_ERR (cdns_xspi->sdmabase))return PTR_ERR (cdns_xspi->sdmabase); cdns_xspi->sdmasize =resource_size (res); - cdns_xspi->auxbase =devm_platform_ioremap_resource_byname (pdev,"aux" ); + res =platform_get_resource (pdev,IORESOURCE_MEM ,2 ); + cdns_xspi->auxbase =devm_ioremap_resource (dev, res);if (IS_ERR (cdns_xspi->auxbase)) {dev_err (dev,"Failed to remap AUX address\n" );return PTR_ERR (cdns_xspi->auxbase);
@@ -917,6 +984,13 @@ static int cdns_xspi_probe(struct platform_device *pdev)return 0 ; } +static const struct acpi_device_id cdns_xspi_acpi_match[] = { + {"cdns,xspi-nor" ,0 }, + {"mrvl,xspi-nor" ,0 }, + {}, +}; +MODULE_DEVICE_TABLE (acpi, cdns_xspi_acpi_match); +#ifdef CONFIG_OF static const struct of_device_id cdns_xspi_of_match[] = { { .compatible = "cdns,xspi-nor",
@@ -933,6 +1007,7 @@ static struct platform_driver cdns_xspi_platform_driver = { .driver = { .name = CDNS_XSPI_NAME, .of_match_table = cdns_xspi_of_match, + .acpi_match_table = cdns_xspi_acpi_match, }, };
Signature · 1 line
2.17.1
Re: [PATCH 4/5] driver: spi: cadence: Add ACPI support
Quoted 7 lines · Witold Sadowski
From: Piyush Malgujar <[email protected]>
These changes enables to read the configs from ACPI tables as required for successful probing in ACPI uefi environment. In case of ACPI disabled/dts based environment, it will continue to read configs from dts as before.
Random subjects... Please use subject prefixes matching the subsystem. You can get them for example with git log --oneline -- DIRECTORY_OR_FILE on the directory your patch is touching.
drivers/spi/spi-cadence-xspi.c static int cdns_xspi_probe(struct platform_device *pdev) · line 989
Quoted 5 lines
}
drivers/spi/spi-cadence-xspi.c +3
-0+static const struct acpi_device_id cdns_xspi_acpi_match[] = { + {"cdns,xspi-nor" ,0 }, + {"mrvl,xspi-nor" ,0 },
How is this ACPI?
drivers/spi/spi-cadence-xspi.c static int cdns_xspi_probe(struct platform_device *pdev) · line 993
Quoted 4 lines
drivers/spi/spi-cadence-xspi.c +4
-0+ {}, +}; +MODULE_DEVICE_TABLE (acpi, cdns_xspi_acpi_match); +#ifdef CONFIG_OF
This was never compiled. I could understand not testing bindings, because it is something relatively new - like 5 or 6 years. But not compiling code is less understandable.
Best regards,
Krzysztof
kernel test robot
build botRe: [PATCH 4/5] driver: spi: cadence: Add ACPI support
In reply to Witold Sadowskikernel test robot noticed the following build errors:
Hi Witold,
kernel test robot noticed the following build errors:
[auto build test ERROR on broonie-spi/for-next]
[also build test ERROR on linus/master v6.9-rc1 next-20240328] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Witold-Sadowski/spi-cadence-Add-new-bindings-documentation-for-Cadence-XSPI/20240330-035124 base: https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next patch link: https://lore.kernel.org/r/20240329194849.25554-5-wsadowski%40marvell.com patch subject: [PATCH 4/5] driver: spi: cadence: Add ACPI support config: m68k-allmodconfig (https://download.01.org/0day-ci/archive/20240331/[email protected]/config) compiler: m68k-linux-gcc (GCC) 13.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240331/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All errors (new ones prefixed by >>):
drivers/spi/spi-cadence-xspi.c: In function 'mrvl_ioreadq':
drivers/spi/spi-cadence-xspi.c:535:14: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
535 | if (((uint64_t)buf % 8) == 0) {
| ^
drivers/spi/spi-cadence-xspi.c:537:36: error: implicit declaration of function 'readq'; did you mean 'readb'? [-Werror=implicit-function-declaration]
537 | *buf64++ = readq(addr);
| ^~~~~
| readb
drivers/spi/spi-cadence-xspi.c: In function 'mrvl_iowriteq':
drivers/spi/spi-cadence-xspi.c:559:14: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
559 | if (((uint64_t)buf % 8) == 0) {
| ^
drivers/spi/spi-cadence-xspi.c:561:25: error: implicit declaration of function 'writeq'; did you mean 'writel'? [-Werror=implicit-function-declaration]
561 | writeq(*buf64++, addr);
| ^~~~~~
| writel
drivers/spi/spi-cadence-xspi.c: In function 'cdns_xspi_setup':
drivers/spi/spi-cadence-xspi.c:869:43: error: implicit declaration of function 'spi_master_get_devdata'; did you mean 'spi_mem_get_drvdata'? [-Werror=implicit-function-declaration]
869 | struct cdns_xspi_dev *cdns_xspi = spi_master_get_devdata(spi_dev->master);
| ^~~~~~~~~~~~~~~~~~~~~~
| spi_mem_get_drvdata
drivers/spi/spi-cadence-xspi.c:869:73: error: 'struct spi_device' has no member named 'master'
869 | struct cdns_xspi_dev *cdns_xspi = spi_master_get_devdata(spi_dev->master);
| ^~
drivers/spi/spi-cadence-xspi.c: At top level:
>> drivers/spi/spi-cadence-xspi.c:993: error: unterminated #ifdef
993 | #ifdef CONFIG_OF
| cc1: some warnings being treated as errors
vim +993 drivers/spi/spi-cadence-xspi.c
986
987 static const struct acpi_device_id cdns_xspi_acpi_match[] = {
988 {"cdns,xspi-nor", 0},
989 {"mrvl,xspi-nor", 0},
990 {},
991 };
992 MODULE_DEVICE_TABLE(acpi, cdns_xspi_acpi_match);
> 993 #ifdef CONFIG_OF
994 static const struct of_device_id cdns_xspi_of_match[] = {
995 {
996 .compatible = "cdns,xspi-nor",
997 },
998 {
999 .compatible = "mrvl,xspi-nor",
1000 },
1001 { /* end of table */}
1002 };
1003 MODULE_DEVICE_TABLE(of, cdns_xspi_of_match);
1004
Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
PATCH 5/5 cadence-xspi: Add xfer capabilities
In reply to Witold SadowskiAdd support for iMRVL xfer hw_overlay of Cadence xSPI block.
MRVL Xfer overlay extend xSPI capabilities, to support non-memory SPI operations.
With generic xSPI command it allows to create any required SPI transaction
--- drivers/spi/spi-cadence-xspi.c | 249 +++++++++++++++++++++++++++++++++ 1 file changed, 249 insertions(+)
drivers/spi/spi-cadence-xspi.c +249 -0
@@ -219,19 +219,38 @@#define CDNS_XSPI_DLL_RST_N BIT(24)#define CDNS_XSPI_DLL_LOCK BIT(0) +#define CDNS_XSPI_POLL_TIMEOUT_US 1000 +#define CDNS_XSPI_POLL_DELAY_US 10 +/* Marvell clock config register */ #define CDNS_MRVL_XSPI_CLK_CTRL_AUX_REG 0x2020#define CDNS_MRVL_XSPI_CLK_ENABLE BIT(0)#define CDNS_MRVL_XSPI_CLK_DIV GENMASK(4, 1) +/* Marvell MSI-X clear interrupt register */ #define CDNS_MRVL_XSPI_SPIX_INTR_AUX 0x2000#define CDNS_MRVL_MSIX_CLEAR_IRQ 0x01 +#define SPIX_XFER_FUNC_CTRL 0x210 +#define SPIX_XFER_FUNC_CTRL_READ_DATA (i) (0x000 + 8 * (i)) +/* Marvell clock macros */ #define CDNS_MRVL_XSPI_CLOCK_IO_HZ 800000000#define CDNS_MRVL_XSPI_CLOCK_DIVIDED (div) ((CDNS_MRVL_XSPI_CLOCK_IO_HZ) / (div)) +/* Marvell XFER registers */ +#define XFER_SOFT_RESET BIT(11) +#define XFER_CS_N_HOLD GENMASK(9, 6) +#define XFER_RECEIVE_ENABLE BIT(4) +#define XFER_FUNC_ENABLE BIT(3) +#define XFER_CLK_CAPTURE_POL BIT(2) +#define XFER_CLK_DRIVE_POL BIT(1) +#define XFER_FUNC_START BIT(0) + +#define XFER_QWORD_COUNT 32 +#define XFER_QWORD_BYTECOUNT 8 +enum cdns_xspi_stig_instr_type {CDNS_XSPI_STIG_INSTR_TYPE_0 ,CDNS_XSPI_STIG_INSTR_TYPE_1 ,
@@ -256,6 +275,7 @@ struct cdns_xspi_dev {void __iomem *iobase;void __iomem *auxbase;void __iomem *sdmabase; +void __iomem *xferbase;int irq;int cur_cs;
@@ -270,6 +290,9 @@ struct cdns_xspi_dev {const void *out_buffer;u8 hw_num_banks; + +bool xfer_in_progress; +int current_xfer_qword; };#define MRVL_DEFAULT_CLK 25000000
@@ -884,6 +907,221 @@ static bool cdns_xspi_get_hw_overlay(struct platform_device *pdev)return (err >=0 ); } + +static int cdns_xspi_prepare_generic (int cs,const void *dout,int len,int glue,u32 *cmd_regs) +{ +u8 *data = (u8 *)dout; +int i; +int data_counter =0 ; + +memset (cmd_regs,0x00 ,6 *4 ); + +if (len >7 ) { +for (i = (len >=10 ?2 : len -8 ); i >=0 ; i--) + cmd_regs[3 ] |= data[data_counter++] << (8 *i); + } +if (len >3 ) { +for (i = (len >=7 ?3 : len -4 ); i >=0 ; i--) + cmd_regs[2 ] |= data[data_counter++] << (8 *i); + } +for (i = (len >=3 ?2 : len -1 ); i >=0 ; i--) + cmd_regs[1 ] |= data[data_counter++] << (8 +8 *i); + + cmd_regs[1 ] |=96 ; + cmd_regs[3 ] |= len <<24 ; + cmd_regs[4 ] |= cs <<12 ; + +if (glue ==1 ) + cmd_regs[4 ] |=1 <<28 ; + +return 0 ; +} + +unsigned char reverse_bits (unsigned char num) +{ +unsigned int count =sizeof (num) *8 -1 ; +unsigned int reverse_num = num; + + num >>=1 ; +while (num) { + reverse_num <<=1 ; + reverse_num |= num &1 ; + num >>=1 ; + count--; + } + reverse_num <<= count; +return reverse_num; +} + +static void cdns_xspi_read_single_qword (struct cdns_xspi_dev *cdns_xspi,u8 **buffer) +{ +u64 d =readq (cdns_xspi->xferbase + +SPIX_XFER_FUNC_CTRL_READ_DATA (cdns_xspi->current_xfer_qword)); +u8 *ptr = (u8 *)&d; +int k; + +for (k =0 ; k <8 ; k++) { +u8 val =reverse_bits ((ptr[k])); + **buffer = val; + *buffer = *buffer +1 ; + } + + cdns_xspi->current_xfer_qword++; + cdns_xspi->current_xfer_qword %=XFER_QWORD_COUNT ; +} + +static void cdns_xspi_finish_read (struct cdns_xspi_dev *cdns_xspi,u8 **buffer,u32 data_count) +{ +u64 d =readq (cdns_xspi->xferbase + +SPIX_XFER_FUNC_CTRL_READ_DATA (cdns_xspi->current_xfer_qword)); +u8 *ptr = (u8 *)&d; +int k; + +for (k =0 ; k < data_count %XFER_QWORD_BYTECOUNT ; k++) { +u8 val =reverse_bits ((ptr[k])); + **buffer = val; + *buffer = *buffer +1 ; + } + + cdns_xspi->current_xfer_qword++; + cdns_xspi->current_xfer_qword %=XFER_QWORD_COUNT ; +} + +static int cdns_xspi_prepare_transfer (int cs,int dir,int len,u32 *cmd_regs) +{ +memset (cmd_regs,0x00 ,6 *4 ); + + cmd_regs[1 ] |=127 ; + cmd_regs[2 ] |= len <<16 ; + cmd_regs[4 ] |= dir <<4 ;//dir = 0 read, dir =1 write + cmd_regs[4 ] |= cs <<12 ; + +return 0 ; +} + +bool cdns_xspi_stig_ready (struct cdns_xspi_dev *cdns_xspi,bool sleep) +{ +u32 ctrl_stat; + +return readl_relaxed_poll_timeout + (cdns_xspi->iobase +CDNS_XSPI_CTRL_STATUS_REG , + ctrl_stat, + ((ctrl_stat &BIT (3 )) ==0 ), + sleep ?CDNS_XSPI_POLL_DELAY_US :0 , + sleep ?CDNS_XSPI_POLL_TIMEOUT_US :0 ); +} + +bool cdns_xspi_sdma_ready (struct cdns_xspi_dev *cdns_xspi,bool sleep) +{ +u32 ctrl_stat; + +return readl_relaxed_poll_timeout + (cdns_xspi->iobase +CDNS_XSPI_INTR_STATUS_REG , + ctrl_stat, + (ctrl_stat &CDNS_XSPI_SDMA_TRIGGER ), + sleep ?CDNS_XSPI_POLL_DELAY_US :0 , + sleep ?CDNS_XSPI_POLL_TIMEOUT_US :0 ); +} + +int cdns_xspi_transfer_one_message_b0 (struct spi_controller *master, +struct spi_message *m) +{ +struct cdns_xspi_dev *cdns_xspi =spi_master_get_devdata (master); +struct spi_device *spi = m->spi; +struct spi_transfer *t =NULL ; + +const int max_len =XFER_QWORD_BYTECOUNT *XFER_QWORD_COUNT ; +int current_cycle_count; +int cs = spi->chip_select; +int cs_change =0 ; + +/* Enable xfer state machine */ +if (!cdns_xspi->xfer_in_progress) { +u32 xfer_control =readl (cdns_xspi->xferbase +SPIX_XFER_FUNC_CTRL ); + + cdns_xspi->current_xfer_qword =0 ; + cdns_xspi->xfer_in_progress = true; + xfer_control |= (XFER_RECEIVE_ENABLE | +XFER_CLK_CAPTURE_POL | +XFER_FUNC_START | +XFER_SOFT_RESET | +FIELD_PREP (XFER_CS_N_HOLD , (1 << cs))); + xfer_control &= ~(XFER_FUNC_ENABLE |XFER_CLK_DRIVE_POL ); +writel (xfer_control, cdns_xspi->xferbase +SPIX_XFER_FUNC_CTRL ); + } + +list_for_each_entry (t, &m->transfers, transfer_list) { +u8 *txd = (u8 *) t->tx_buf; +u8 *rxd = (u8 *) t->rx_buf; +u8 data[10 ]; +u32 cmd_regs[6 ]; + +if (!txd) + txd = data; + + cdns_xspi->in_buffer = txd +1 ; + cdns_xspi->out_buffer = txd +1 ; + +while (t->len) { + + current_cycle_count = t->len > max_len ? max_len : t->len; + +if (current_cycle_count <10 ) { +cdns_xspi_prepare_generic (cs, txd, current_cycle_count, + false, cmd_regs); +cdns_xspi_trigger_command (cdns_xspi, cmd_regs); +if (cdns_xspi_stig_ready (cdns_xspi, true)) +return -EIO ; + }else { +cdns_xspi_prepare_generic (cs, txd,1 , true, cmd_regs); +cdns_xspi_trigger_command (cdns_xspi, cmd_regs); +cdns_xspi_prepare_transfer (cs,1 , current_cycle_count -1 , + cmd_regs); +cdns_xspi_trigger_command (cdns_xspi, cmd_regs); +if (cdns_xspi_sdma_ready (cdns_xspi, true)) +return -EIO ; +cdns_xspi_sdma_handle (cdns_xspi); +if (cdns_xspi_stig_ready (cdns_xspi, true)) +return -EIO ; + + cdns_xspi->in_buffer += current_cycle_count; + cdns_xspi->out_buffer += current_cycle_count; + } + +if (rxd) { +int j; + +for (j =0 ; j < current_cycle_count /8 ; j++) +cdns_xspi_read_single_qword (cdns_xspi, &rxd); +cdns_xspi_finish_read (cdns_xspi, &rxd, current_cycle_count); + }else { + cdns_xspi->current_xfer_qword += current_cycle_count / +XFER_QWORD_BYTECOUNT ; +if (current_cycle_count %XFER_QWORD_BYTECOUNT ) + cdns_xspi->current_xfer_qword++; + + cdns_xspi->current_xfer_qword %=XFER_QWORD_COUNT ; + } + cs_change = t->cs_change; + t->len -= current_cycle_count; + } + } + +if (!cs_change) { +u32 xfer_control =readl (cdns_xspi->xferbase +SPIX_XFER_FUNC_CTRL ); + + xfer_control &= ~(XFER_RECEIVE_ENABLE | +XFER_SOFT_RESET ); +writel (xfer_control, cdns_xspi->xferbase +SPIX_XFER_FUNC_CTRL ); + cdns_xspi->xfer_in_progress = false; + } + + m->status =0 ; +spi_finalize_current_message (master); + +return 0 ; +} +static int cdns_xspi_probe (struct platform_device *pdev) {struct device *dev = &pdev->dev;
@@ -948,6 +1186,16 @@ static int cdns_xspi_probe(struct platform_device *pdev)return PTR_ERR (cdns_xspi->auxbase); } +if (hw_overlay) { + res =platform_get_resource (pdev,IORESOURCE_MEM ,3 ); + cdns_xspi->xferbase =devm_ioremap_resource (dev, res); +if (IS_ERR (cdns_xspi->xferbase)) { +dev_info (dev,"XFER register base not found, set it\n" ); +// For compatibility with older firmware + cdns_xspi->xferbase = cdns_xspi->iobase +0x8000 ; + } + } + cdns_xspi->irq =platform_get_irq (pdev,0 );if (cdns_xspi->irq <0 )return -ENXIO ;
@@ -962,6 +1210,7 @@ static int cdns_xspi_probe(struct platform_device *pdev)if (hw_overlay) {cdns_mrvl_xspi_setup_clock (cdns_xspi,MRVL_DEFAULT_CLK );cdns_xspi_configure_phy (cdns_xspi); + host->transfer_one_message = cdns_xspi_transfer_one_message_b0; }cdns_xspi_print_phy_config (cdns_xspi);
Signature · 1 line
2.17.1
Re: [PATCH 5/5] cadence-xspi: Add xfer capabilities
Quoted 6 lines · Witold Sadowski
Add support for iMRVL xfer
hw_overlayof Cadence xSPI block.
MRVL Xfer overlay extend xSPI capabilities, to support non-memory SPI operations.
With generic xSPI command it allows to create any required SPI transaction
Please use subject prefixes matching the subsystem. You can get them for example with git log --oneline -- DIRECTORY_OR_FILE on the directory your patch is touching.
Please wrap commit message according to Linux coding style / submission process (neither too early nor over the limit):
https://elixir.bootlin.com/linux/v6.4-rc1/source/Documentation/process/submitting-patches.rst#L597
... and build your code because this does not compile. :(
Best regards,
Krzysztof
kernel test robot
build botRe: [PATCH 5/5] cadence-xspi: Add xfer capabilities
In reply to Witold Sadowskikernel test robot noticed the following build warnings:
Hi Witold,
kernel test robot noticed the following build warnings:
[auto build test WARNING on broonie-spi/for-next]
[also build test WARNING on linus/master v6.9-rc1 next-20240328] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Witold-Sadowski/spi-cadence-Add-new-bindings-documentation-for-Cadence-XSPI/20240330-035124 base: https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next patch link: https://lore.kernel.org/r/20240329194849.25554-6-wsadowski%40marvell.com patch subject: [PATCH 5/5] cadence-xspi: Add xfer capabilities config: x86_64-randconfig-123-20240331 (https://download.01.org/0day-ci/archive/20240331/[email protected]/config) compiler: gcc-7 (Ubuntu 7.5.0-6ubuntu2) 7.5.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240331/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All warnings (new ones prefixed by >>):
drivers/spi/spi-cadence-xspi.c: In function 'cdns_xspi_setup':
drivers/spi/spi-cadence-xspi.c:892:36: error: implicit declaration of function 'spi_master_get_devdata'; did you mean 'spi_mem_get_drvdata'? [-Werror=implicit-function-declaration]
struct cdns_xspi_dev *cdns_xspi = spi_master_get_devdata(spi_dev->master);
^~~~~~~~~~~~~~~~~~~~~~
spi_mem_get_drvdata
drivers/spi/spi-cadence-xspi.c:892:66: error: 'struct spi_device' has no member named 'master'
struct cdns_xspi_dev *cdns_xspi = spi_master_get_devdata(spi_dev->master);
^~
drivers/spi/spi-cadence-xspi.c: In function 'cdns_xspi_transfer_one_message_b0':
>> drivers/spi/spi-cadence-xspi.c:1029:36: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
struct cdns_xspi_dev *cdns_xspi = spi_master_get_devdata(master);
^~~~~~~~~~~~~~~~~~~~~~
>> drivers/spi/spi-cadence-xspi.c:1035:11: warning: initialization makes integer from pointer without a cast [-Wint-conversion]
int cs = spi->chip_select;
^~~
drivers/spi/spi-cadence-xspi.c: At top level:
drivers/spi/spi-cadence-xspi.c:1242:0: error: unterminated #ifdef
#ifdef CONFIG_OFcc1: some warnings being treated as errors
vim +1029 drivers/spi/spi-cadence-xspi.c
1025
1026 int cdns_xspi_transfer_one_message_b0(struct spi_controller *master,
1027 struct spi_message *m)
1028 {
> 1029 struct cdns_xspi_dev *cdns_xspi = spi_master_get_devdata(master); 1030 struct spi_device *spi = m->spi; 1031 struct spi_transfer *t = NULL; 1032 1033 const int max_len = XFER_QWORD_BYTECOUNT * XFER_QWORD_COUNT; 1034 int current_cycle_count; > 1035 int cs = spi->chip_select;
1036 int cs_change = 0;
1037
1038 /* Enable xfer state machine */
1039 if (!cdns_xspi->xfer_in_progress) {
1040 u32 xfer_control = readl(cdns_xspi->xferbase + SPIX_XFER_FUNC_CTRL);
1041
1042 cdns_xspi->current_xfer_qword = 0;
1043 cdns_xspi->xfer_in_progress = true;
1044 xfer_control |= (XFER_RECEIVE_ENABLE |
1045 XFER_CLK_CAPTURE_POL |
1046 XFER_FUNC_START |
1047 XFER_SOFT_RESET |
1048 FIELD_PREP(XFER_CS_N_HOLD, (1 << cs)));
1049 xfer_control &= ~(XFER_FUNC_ENABLE | XFER_CLK_DRIVE_POL);
1050 writel(xfer_control, cdns_xspi->xferbase + SPIX_XFER_FUNC_CTRL);
1051 }
1052
1053 list_for_each_entry(t, &m->transfers, transfer_list) {
1054 u8 *txd = (u8 *) t->tx_buf;
1055 u8 *rxd = (u8 *) t->rx_buf;
1056 u8 data[10];
1057 u32 cmd_regs[6];
1058
1059 if (!txd)
1060 txd = data;
1061
1062 cdns_xspi->in_buffer = txd + 1;
1063 cdns_xspi->out_buffer = txd + 1;
1064
1065 while (t->len) {
1066
1067 current_cycle_count = t->len > max_len ? max_len : t->len;
1068
1069 if (current_cycle_count < 10) {
1070 cdns_xspi_prepare_generic(cs, txd, current_cycle_count,
1071 false, cmd_regs);
1072 cdns_xspi_trigger_command(cdns_xspi, cmd_regs);
1073 if (cdns_xspi_stig_ready(cdns_xspi, true))
1074 return -EIO;
1075 } else {
1076 cdns_xspi_prepare_generic(cs, txd, 1, true, cmd_regs);
1077 cdns_xspi_trigger_command(cdns_xspi, cmd_regs);
1078 cdns_xspi_prepare_transfer(cs, 1, current_cycle_count - 1,
1079 cmd_regs);
1080 cdns_xspi_trigger_command(cdns_xspi, cmd_regs);
1081 if (cdns_xspi_sdma_ready(cdns_xspi, true))
1082 return -EIO;
1083 cdns_xspi_sdma_handle(cdns_xspi);
1084 if (cdns_xspi_stig_ready(cdns_xspi, true))
1085 return -EIO;
1086
1087 cdns_xspi->in_buffer += current_cycle_count;
1088 cdns_xspi->out_buffer += current_cycle_count;
1089 }
1090
1091 if (rxd) {
1092 int j;
1093
1094 for (j = 0; j < current_cycle_count / 8; j++)
1095 cdns_xspi_read_single_qword(cdns_xspi, &rxd);
1096 cdns_xspi_finish_read(cdns_xspi, &rxd, current_cycle_count);
1097 } else {
1098 cdns_xspi->current_xfer_qword += current_cycle_count /
1099 XFER_QWORD_BYTECOUNT;
1100 if (current_cycle_count % XFER_QWORD_BYTECOUNT)
1101 cdns_xspi->current_xfer_qword++;
1102
1103 cdns_xspi->current_xfer_qword %= XFER_QWORD_COUNT;
1104 }
1105 cs_change = t->cs_change;
1106 t->len -= current_cycle_count;
1107 }
1108 }
1109
1110 if (!cs_change) {
1111 u32 xfer_control = readl(cdns_xspi->xferbase + SPIX_XFER_FUNC_CTRL);
1112
1113 xfer_control &= ~(XFER_RECEIVE_ENABLE |
1114 XFER_SOFT_RESET);
1115 writel(xfer_control, cdns_xspi->xferbase + SPIX_XFER_FUNC_CTRL);
1116 cdns_xspi->xfer_in_progress = false;
1117 }
1118
1119 m->status = 0;
1120 spi_finalize_current_message(master);
1121
1122 return 0;
1123 }
1124
Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
v3 cover Marvell HW overlay support for Cadence xSPI
In reply to Witold SadowskiThis patch series is adding support for second version of Marvell HW overlay for Cadence xSPI IP block.
Overlay extends xSPI features, with clock configuration, interrupt masking and full-duplex, variable length SPI operations. All that functionalites allows xSPI block to operate not only with memory devices, but also with simple SPI devices, or TPM devices.
Piyush Malgujar (1):
spi: cadence: Allow to read basic xSPI configuration from ACPI
Witold Sadowski (4):
spi: cadence: Ensure data lines set to low during dummy-cycle period
spi: cadence: Add MRVL overlay bindings documentation for Cadence XSPI
spi: cadence: Add Marvell xSPI IP overlay changes
spi: cadence: Add MRVL overlay xfer operation support
.../devicetree/bindings/spi/cdns,xspi.yaml | 92 ++- drivers/spi/spi-cadence-xspi.c | 691 +++++++++++++++++- 2 files changed, 762 insertions(+), 21 deletions(-)
Signature · 1 line
2.43.0
PATCH v3 1/5 spi: cadence: Ensure data lines set to low during dummy-cycle period
During dummy-cycles xSPI will switch GPIO into Hi-Z mode. In that dummy period voltage on data lines will slowly drop, what can cause unintentional modebyte transmission. Value send to SPI memory chip will depend on last address, and clock frequency.
To prevent unforeseen consequences of that behaviour, force send single modebyte(0x00).
Modebyte will be send only if number of dummy-cycles is not equal to 0. Code must also reduce dummycycle byte count by one - as one byte is send as modebyte.
--- drivers/spi/spi-cadence-xspi.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-)
drivers/spi/spi-cadence-xspi.c +15 -5
@@ -145,6 +145,9 @@#define CDNS_XSPI_STIG_DONE_FLAG BIT(0)#define CDNS_XSPI_TRD_STATUS 0x0104 +#define MODE_NO_OF_BYTES GENMASK(25, 24) +#define MODEBYTES_COUNT 1 +/* Helper macros for filling command registers */ #define CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_1 (op, data_phase) ( \ FIELD_PREP(CDNS_XSPI_CMD_INSTR_TYPE, (data_phase) ? \
@@ -157,9 +160,10 @@ FIELD_PREP(CDNS_XSPI_CMD_P1_R2_ADDR3, ((op)->addr.val >> 24) & 0xFF) | \ FIELD_PREP(CDNS_XSPI_CMD_P1_R2_ADDR4, ((op)->addr.val >> 32) & 0xFF)) -#define CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_3 (op) ( \ +#define CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_3 (op, modebytes) ( \ FIELD_PREP(CDNS_XSPI_CMD_P1_R3_ADDR5, ((op)->addr.val >> 40) & 0xFF) | \ FIELD_PREP(CDNS_XSPI_CMD_P1_R3_CMD, (op)->cmd.opcode) | \ + FIELD_PREP(MODE_NO_OF_BYTES, modebytes) | \ FIELD_PREP(CDNS_XSPI_CMD_P1_R3_NUM_ADDR_BYTES, (op)->addr.nbytes))#define CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_4 (op, chipsel) ( \
@@ -173,12 +177,12 @@#define CDNS_XSPI_CMD_FLD_DSEQ_CMD_2 (op) \ FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R2_DCNT_L, (op)->data.nbytes & 0xFFFF) -#define CDNS_XSPI_CMD_FLD_DSEQ_CMD_3 (op) ( \ +#define CDNS_XSPI_CMD_FLD_DSEQ_CMD_3 (op, dummybytes) ( \ FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R3_DCNT_H, \ ((op)->data.nbytes >> 16) & 0xffff) | \ FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R3_NUM_OF_DUMMY, \ (op)->dummy.buswidth != 0 ? \ - (((op)->dummy.nbytes * 8) / (op)->dummy.buswidth) : \ + (((dummybytes) * 8) / (op)->dummy.buswidth) : \ 0))#define CDNS_XSPI_CMD_FLD_DSEQ_CMD_4 (op, chipsel) ( \
@@ -351,6 +355,7 @@ static int cdns_xspi_send_stig_command(struct cdns_xspi_dev *cdns_xspi,u32 cmd_regs[6 ];u32 cmd_status;int ret; +int dummybytes = op->dummy.nbytes; ret =cdns_xspi_wait_for_controller_idle (cdns_xspi);if (ret <0 )
@@ -365,7 +370,12 @@ static int cdns_xspi_send_stig_command(struct cdns_xspi_dev *cdns_xspi,memset (cmd_regs,0 ,sizeof (cmd_regs)); cmd_regs[1 ] =CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_1 (op, data_phase); cmd_regs[2 ] =CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_2 (op); - cmd_regs[3 ] =CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_3 (op); +if (dummybytes !=0 ) { + cmd_regs[3 ] =CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_3 (op,1 ); + dummybytes--; + }else { + cmd_regs[3 ] =CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_3 (op,0 ); + } cmd_regs[4 ] =CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_4 (op, cdns_xspi->cur_cs);
@@ -375,7 +385,7 @@ static int cdns_xspi_send_stig_command(struct cdns_xspi_dev *cdns_xspi, cmd_regs[0 ] =CDNS_XSPI_STIG_DONE_FLAG ; cmd_regs[1 ] =CDNS_XSPI_CMD_FLD_DSEQ_CMD_1 (op); cmd_regs[2 ] =CDNS_XSPI_CMD_FLD_DSEQ_CMD_2 (op); - cmd_regs[3 ] =CDNS_XSPI_CMD_FLD_DSEQ_CMD_3 (op); + cmd_regs[3 ] =CDNS_XSPI_CMD_FLD_DSEQ_CMD_3 (op, dummybytes); cmd_regs[4 ] =CDNS_XSPI_CMD_FLD_DSEQ_CMD_4 (op, cdns_xspi->cur_cs);
Signature · 1 line
2.43.0
PATCH v3 2/5 spi: cadence: Add MRVL overlay bindings documentation for Cadence XSPI
In reply to Witold SadowskiAdd new bindings for v2 Marvell xSPI overlay:
mrvl,xspi-nor compatible string
New compatible string to distinguish between orginal and modified xSPI block
PHY configuration registers
Allow to change orginal xSPI PHY configuration values. If not set, and Marvell overlay is enabled, safe defaults will be written into xSPI PHY
Optional base for xfer register set
Additional reg field to allocate xSPI Marvell overlay XFER block
--- .../devicetree/bindings/spi/cdns,xspi.yaml | 92 ++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-)
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +91 -1
@@ -20,23 +20,82 @@ allOf: properties: compatible: - const: cdns,xspi-nor + oneOf: + - description: Vanilla Cadence xSPI controller + items: + - const: cdns,xspi-nor + - description: Cadence xSPI controller with v2 Marvell overlay + items: + - const: mrvl,xspi-nor + reg: + minItems: 3 items: - description: address and length of the controller register set - description: address and length of the Slave DMA data port - description: address and length of the auxiliary registers + - description: address and length of the xfer registers reg-names: + minItems: 3 items: - const: io - const: sdma - const: aux + - const: xferbase interrupts: maxItems: 1 + cdns,dll-phy-control: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x707 + + cdns,rfile-phy-control: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x40000 + + cdns,rfile-phy-tsel: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0 + + cdns,phy-dq-timing: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x101 + + cdns,phy-dqs-timing: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x700404 + + cdns,phy-gate-lpbk-ctrl: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x200030 + + cdns,phy-dll-master-ctrl: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x00800000 + + cdns,phy-dll-slave-ctrl: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x0000ff01 + required: - compatible - reg
@@ -68,6 +127,37 @@ examples: reg = <0>; }; + flash@1 { + compatible = "jedec,spi-nor"; + spi-max-frequency = <75000000>; + reg = <1>; + }; + }; + }; + - | + #include <dt-bindings/interrupt-controller/irq.h> + bus { + #address-cells = <2>; + #size-cells = <2>; + + mrvl_xspi: spi@d0010000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "mrvl,xspi-nor"; + reg = <0x0 0xa0010000 0x0 0x1040>, + <0x0 0xb0000000 0x0 0x1000>, + <0x0 0xa0020000 0x0 0x100>, + <0x0 0xa0090000 0x0 0x100>; + reg-names = "io", "sdma", "aux", "xferbase"; + interrupts = <0 90 IRQ_TYPE_LEVEL_HIGH>; + interrupt-parent = <&gic>; + + flash@0 { + compatible = "jedec,spi-nor"; + spi-max-frequency = <75000000>; + reg = <0>; + }; + flash@1 { compatible = "jedec,spi-nor"; spi-max-frequency = <75000000>;
Signature · 1 line
2.43.0
Re: [PATCH v3 2/5] spi: cadence: Add MRVL overlay bindings documentation for Cadence XSPI
Quoted 22 lines · Witold Sadowski
Add new bindings for v2 Marvell xSPI overlay:
mrvl,xspi-nor compatible string
New compatible string to distinguish between orginal and modified xSPI blockPHY configuration registers
Allow to change orginal xSPI PHY configuration values. If not set, and Marvell overlay is enabled, safe defaults will be written into xSPI PHYOptional base for xfer register set
Additional reg field to allocate xSPI Marvell overlay XFER blockSigned-off-by Witold Sadowski <[email protected]>--- .../devicetree/bindings/spi/cdns,xspi.yaml | 92 ++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-)Documentation/devicetree/bindings/spi/cdns,xspi.yaml +0
-0
Documentation/devicetree/bindings/spi/cdns,xspi.yaml allOf: · line 26
Quoted 8 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +4
-1@@ -20,23 +20,82 @@ allOf: properties: compatible: - const: cdns,xspi-nor + oneOf: + - description: Vanilla Cadence xSPI controller + items: + - const: cdns,xspi-nor
The "items: isn't required here is it? Can't you just have
oneOf:
- description: Vanilla Cadence xSPI controller
const: cdns,xspi-nor
- description: Cadence xSPI controller with v2 Marvell overlay
const: mrvl,xspi-nor
if you don't want to use an enum?
Documentation/devicetree/bindings/spi/cdns,xspi.yaml allOf: · line 29
Quoted 3 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +3
-0+ - description: Cadence xSPI controller with v2 Marvell overlay + items: + - const: mrvl,xspi-nor
"mrvl" is deprecated, please use "marvell". You're also missing a soc-specific compatible here, I doubt there's only going to be one device from marvell with an xspi controller ever.
Quoted 5 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +1
-0reg: + minItems: 3 items: - description: address and length of the controller register set - description: address and length of the Slave DMA data port
Documentation/devicetree/bindings/spi/cdns,xspi.yaml allOf: · line 46
Quoted 10 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +3
-0- description: address and length of the auxiliary registers + - description: address and length of the xfer registers reg-names: + minItems: 3 items: - const: io - const: sdma - const: aux + - const: xferbase
Please constrain the 4th reg to only the marvell device.
Documentation/devicetree/bindings/spi/cdns,xspi.yaml allOf: · line 53
Quoted 7 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +3
-0interrupts: maxItems: 1 + cdns,dll-phy-control: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor
Under what circumstances do you expect these things to change for a particular SoC? If it's fixed per SoC, you could deduce it from the compatible rather than needing properties.
None of these properties explain what they do and all appear to just set register values directly, which is not generally something that we permit in DT. Some explanation of how these values vary would help a lot...
Documentation/devicetree/bindings/spi/cdns,xspi.yaml allOf: · line 59
Quoted 6 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +6
-0+ $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x707 + + cdns,rfile-phy-control: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor
Please enforce constraints like which compatibles something is valid for in the binding, not in free-form text.
Quoted 50 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +43
-0+ $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x40000 + + cdns,rfile-phy-tsel: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0 + + cdns,phy-dq-timing: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x101 + + cdns,phy-dqs-timing: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x700404 + + cdns,phy-gate-lpbk-ctrl: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x200030 + + cdns,phy-dll-master-ctrl: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x00800000 + + cdns,phy-dll-slave-ctrl: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x0000ff01 + required: - compatible - reg@@ -68,6 +127,37 @@ examples: reg = <0>; }; + flash@1 { + compatible = "jedec,spi-nor"; + spi-max-frequency = <75000000>; + reg = <1>;
Documentation/devicetree/bindings/spi/cdns,xspi.yaml examples: · line 143
Quoted 10 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +10
-0+ }; + }; + }; + - | + #include <dt-bindings/interrupt-controller/irq.h> + bus { + #address-cells = <2>; + #size-cells = <2>; + + mrvl_xspi: spi@d0010000 {
Drop the node label here, nothing ever refers to it.
Thanks,
Conor.
Quoted 23 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +17
-0+ #address-cells = <1>; + #size-cells = <0>; + compatible = "mrvl,xspi-nor"; + reg = <0x0 0xa0010000 0x0 0x1040>, + <0x0 0xb0000000 0x0 0x1000>, + <0x0 0xa0020000 0x0 0x100>, + <0x0 0xa0090000 0x0 0x100>; + reg-names = "io", "sdma", "aux", "xferbase"; + interrupts = <0 90 IRQ_TYPE_LEVEL_HIGH>; + interrupt-parent = <&gic>; + + flash@0 { + compatible = "jedec,spi-nor"; + spi-max-frequency = <75000000>; + reg = <0>; + }; + flash@1 { compatible = "jedec,spi-nor"; spi-max-frequency = <75000000>;Signature · 1 line
2.43.0
RE: [EXTERNAL] Re: [PATCH v3 2/5] spi: cadence: Add MRVL overlay bindings documentation for Cadence XSPI
Quoted 27 lines
----------------------------------------------------------------------
Quoted 25 lines · Witold Sadowski
Add new bindings for v2 Marvell xSPI overlay:
mrvl,xspi-nor compatible string
New compatible string to distinguish between orginal and modified xSPI blockPHY configuration registers
Allow to change orginal xSPI PHY configuration values. If not set, and Marvell overlay is enabled, safe defaults will be written into xSPI PHYOptional base for xfer register set
Additional reg field to allocate xSPI Marvell overlay XFER blockSigned-off-by Witold Sadowski <[email protected]>--- .../devicetree/bindings/spi/cdns,xspi.yaml | 92 ++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-)Documentation/devicetree/bindings/spi/cdns,xspi.yaml +0
-0@@ -20,23 +20,82 @@ allOf:
Quoted 15 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml allOf: · line 26
Quoted 7 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +4
-1properties: compatible: - const: cdns,xspi-nor + oneOf: + - description: Vanilla Cadence xSPI controller + items: + - const: cdns,xspi-norThe "items: isn't required here is it? Can't you just have
oneOf:
- description: Vanilla Cadence xSPI controller
const: cdns,xspi-nor
- description: Cadence xSPI controller with v2 Marvell overlay
const: mrvl,xspi-nor
if you don't want to use an enum?
It works without items, but I will try also with enums.
Quoted 9 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml allOf: · line 29
Quoted 4 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +3
-0+ - description: Cadence xSPI controller with v2 Marvell overlay + items: + - const: mrvl,xspi-nor"mrvl" is deprecated, please use "marvell". You're also missing a soc- specific compatible here, I doubt there's only going to be one device from marvell with an xspi controller ever.
The intention is to add overlay on top of existing IP block to gain some More features from it. So if there will be different SoC with same xSPI IP, we can simply use that property, as internal SoC structure will be the same. On the other hand, if there will be used different IP to handle SPI operations It should use different driver. Also, I do not expect that new version of the Overlay will be developed to handle different IP.
Quoted 17 lines
Quoted 6 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +1
-0reg: + minItems: 3 items: - description: address and length of the controller register set - description: address and length of the Slave DMA data portDocumentation/devicetree/bindings/spi/cdns,xspi.yaml allOf: · line 46
Quoted 10 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +3
-0- description: address and length of the auxiliary registers + - description: address and length of the xfer registers reg-names: + minItems: 3 items: - const: io - const: sdma - const: aux + - const: xferbase
Quoted 1 line
Please constrain the 4th reg to only the marvell device.
Ok.
Quoted 9 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml allOf: · line 53
Quoted 8 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +3
-0interrupts: maxItems: 1 + cdns,dll-phy-control: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor
Quoted 7 lines
Under what circumstances do you expect these things to change for a particular SoC? If it's fixed per SoC, you could deduce it from the compatible rather than needing properties.
None of these properties explain what they do and all appear to just set register values directly, which is not generally something that we permit in DT. Some explanation of how these values vary would help a lot...
I will remove that PHY configuration block. That can be d in driver, based on SoC version/HW overlay version.
I believe to change that values or some internal clock should be changed, or whole internal structure, have to be changed. After few internal discussions, I don't think only changing the SoC will be enough to change that values.
Quoted 58 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml allOf: · line 59
Quoted 7 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +6
-0+ $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x707 + + cdns,rfile-phy-control: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-norPlease enforce constraints like which compatibles something is valid for in the binding, not in free-form text.
Quoted 46 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +39
-0+ $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x40000 + + cdns,rfile-phy-tsel: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0 + + cdns,phy-dq-timing: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x101 + + cdns,phy-dqs-timing: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x700404 + + cdns,phy-gate-lpbk-ctrl: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x200030 + + cdns,phy-dll-master-ctrl: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x00800000 + + cdns,phy-dll-slave-ctrl: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x0000ff01 + required: - compatible - reg@@ -68,6 +127,37 @@ examples: reg = <0>; };
Quoted 16 lines
Quoted 4 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +4
-0+ flash@1 { + compatible = "jedec,spi-nor"; + spi-max-frequency = <75000000>; + reg = <1>;Documentation/devicetree/bindings/spi/cdns,xspi.yaml examples: · line 143
Quoted 10 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +10
-0+ }; + }; + }; + - | + #include <dt-bindings/interrupt-controller/irq.h> + bus { + #address-cells = <2>; + #size-cells = <2>; + + mrvl_xspi: spi@d0010000 {Drop the node label here, nothing ever refers to it.
Ok.
Quoted 19 lines
Thanks,
Conor.Quoted 15 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +15
-0+ #address-cells = <1>; + #size-cells = <0>; + compatible = "mrvl,xspi-nor"; + reg = <0x0 0xa0010000 0x0 0x1040>, + <0x0 0xb0000000 0x0 0x1000>, + <0x0 0xa0020000 0x0 0x100>, + <0x0 0xa0090000 0x0 0x100>; + reg-names = "io", "sdma", "aux", "xferbase"; + interrupts = <0 90 IRQ_TYPE_LEVEL_HIGH>; + interrupt-parent = <&gic>; + + flash@0 { + compatible = "jedec,spi-nor"; + spi-max-frequency = <75000000>; + reg = <0>;
Quoted 8 lines
Quoted 8 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +2
-1+ }; + flash@1 { compatible = "jedec,spi-nor"; spi-max-frequency = <75000000>; --2.43.0
Regards
Witek
Re: [EXTERNAL] Re: [PATCH v3 2/5] spi: cadence: Add MRVL overlay bindings documentation for Cadence XSPI
Quoted 55 lines · Witold Sadowski
Quoted 27 lines
----------------------------------------------------------------------
Quoted 25 lines · Witold Sadowski
Add new bindings for v2 Marvell xSPI overlay:
mrvl,xspi-nor compatible string
New compatible string to distinguish between orginal and modified xSPI blockPHY configuration registers
Allow to change orginal xSPI PHY configuration values. If not set, and Marvell overlay is enabled, safe defaults will be written into xSPI PHYOptional base for xfer register set
Additional reg field to allocate xSPI Marvell overlay XFER blockSigned-off-by Witold Sadowski <[email protected]>--- .../devicetree/bindings/spi/cdns,xspi.yaml | 92 ++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-)Documentation/devicetree/bindings/spi/cdns,xspi.yaml +0
-0@@ -20,23 +20,82 @@ allOf:Quoted 15 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml allOf: · line 26
Quoted 7 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +4
-1properties: compatible: - const: cdns,xspi-nor + oneOf: + - description: Vanilla Cadence xSPI controller + items: + - const: cdns,xspi-norThe "items: isn't required here is it? Can't you just have
oneOf:
- description: Vanilla Cadence xSPI controller
const: cdns,xspi-nor
- description: Cadence xSPI controller with v2 Marvell overlay
const: mrvl,xspi-nor
if you don't want to use an enum?It works without items, but I will try also with enums.
Quoted 9 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml allOf: · line 29
Quoted 4 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +3
-0+ - description: Cadence xSPI controller with v2 Marvell overlay + items: + - const: mrvl,xspi-nor"mrvl" is deprecated, please use "marvell". You're also missing a soc- specific compatible here, I doubt there's only going to be one device from marvell with an xspi controller ever.
Quoted 6 lines
The intention is to add overlay on top of existing IP block to gain some More features from it. So if there will be different SoC with same xSPI IP, we can simply use that property, as internal SoC structure will be the same. On the other hand, if there will be used different IP to handle SPI operations It should use different driver. Also, I do not expect that new version of the Overlay will be developed to handle different IP.
I'm struggling to understand what you mean here by "overlay". Ordinarily I'd expect someone to meant a dt-overlay, but you're talking about IP blocks, so this sounds like hardware modifications.
I am also a bit confused by the claim that the "internal SoC structure will be the same". Usually different SoCs have different internal structures, even when they re-use IP cores. If they have the same internal structure then they're not really different SoCs, just different packages! I think what you're saying here is that you intend using the "mrvl,xspi-nor" compatible for multiple SoCs that all contain the same modified versions of the Cadence IP, not different packages for the same SoC?
Confusing wording aside, using the same generic compatible for different SoCs is what I trying to avoid. I don't mind there being a fallback compatible that's generic, but I want to see specific compatibles here for the individual SoCs.
If you did actually mean that only the packaging is different between the devices, then I don't think you need specific compatibles for each different package, but you should have one for the SoC itself IMO.
Cheers,
Conor.
RE: [EXTERNAL] Re: [PATCH v3 2/5] spi: cadence: Add MRVL overlay bindings documentation for Cadence XSPI
Quoted 66 lines · Witold Sadowski
Quoted 12 lines
Quoted 12 lines
--------------------------------------------------------------------
Quoted 10 lines · Witold Sadowski
Add new bindings for v2 Marvell xSPI overlay:
mrvl,xspi-nor compatible string
New compatible string to distinguish between orginal and modified xSPI blockPHY configuration registers
Allow to change orginal xSPI PHY configuration values. If not set, and Marvell overlay is enabled, safe defaults will be written into xSPI PHYQuoted 6 lines
Quoted 6 lines
Quoted 6 lines
Optional base for xfer register set Additional reg field to allocate xSPI Marvell overlay XFER block
Signed-off-by Witold Sadowski <[email protected]>--- .../devicetree/bindings/spi/cdns,xspi.yaml | 92++++++++++++++++++-
Quoted 25 lines
Quoted 9 lines
Quoted 9 lines
1 file changed, 91 insertions(+), 1 deletion(-)Documentation/devicetree/bindings/spi/cdns,xspi.yaml +0
-0@@ -20,23 +20,82 @@ allOf:Quoted 15 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml allOf: · line 26
Quoted 7 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +4
-1properties: compatible: - const: cdns,xspi-nor + oneOf: + - description: Vanilla Cadence xSPI controller + items: + - const: cdns,xspi-norThe "items: isn't required here is it? Can't you just have
oneOf:
- description: Vanilla Cadence xSPI controller
const: cdns,xspi-nor
- description: Cadence xSPI controller with v2 Marvell overlay
const: mrvl,xspi-nor
if you don't want to use an enum?Quoted 4 lines
It works without items, but I will try also with enums.
Quoted 2 lines
Quoted 2 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +1
-0+ - description: Cadence xSPI controller with v2 Marvelloverlay
Quoted 11 lines
Quoted 7 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml allOf: · line 29
Quoted 2 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +2
-0+ items: + - const: mrvl,xspi-nor"mrvl" is deprecated, please use "marvell". You're also missing a soc- specific compatible here, I doubt there's only going to be one device from marvell with an xspi controller ever.
The intention is to add overlay on top of existing IP block to gain some More features from it. So if there will be different SoC with same xSPI IP, we can simply use that property, as internal SoC structure
will be the same.
Quoted 3 lines
On the other hand, if there will be used different IP to handle SPI operations It should use different driver. Also, I do not expect that new version of the Overlay will be developed to handle different IP.
Quoted 10 lines
I'm struggling to understand what you mean here by "overlay". Ordinarily I'd expect someone to meant a dt-overlay, but you're talking about IP blocks, so this sounds like hardware modifications.
I am also a bit confused by the claim that the "internal SoC structure will be the same". Usually different SoCs have different internal structures, even when they re-use IP cores. If they have the same internal structure then they're not really different SoCs, just different packages! I think what you're saying here is that you intend using the "mrvl,xspi- nor" compatible for multiple SoCs that all contain the same modified versions of the Cadence IP, not different packages for the same SoC?
Yes, by HW overlay I meant actual HW modification. I called it overlay, as it is not modifying xSPI block itself, but it is rather build around it. As I don't have better word for it now, I will continue to use it. With that approach we can still have full functionality of xSPI block (like memory transfers), and additional features(like SPI full-duplex operations).
Regarding "internal SoC structure" - I meant physical parameters of silicon, Signal propagation times inside block etc. That won't be changed if we have Two different SoC, bud made in same technology.
Quoted 9 lines
Confusing wording aside, using the same generic compatible for different SoCs is what I trying to avoid. I don't mind there being a fallback compatible that's generic, but I want to see specific compatibles here for the individual SoCs.
If you did actually mean that only the packaging is different between the devices, then I don't think you need specific compatibles for each different package, but you should have one for the SoC itself IMO.
We can have SoC A, B with common xSPI block, and both of them can share Same dtb node with compatible property "marvell,cn10k,xspi-nor" for example. I don't think it will be beneficial to have different compatible name for each different SoC, for example "marvell,t98,xspi-nor", if all other parts will be the same. Or am I not correct?
Quoted 3 lines
Cheers,
Conor.
Regards
Witek
Re: [EXTERNAL] Re: [PATCH v3 2/5] spi: cadence: Add MRVL overlay bindings documentation for Cadence XSPI
Quoted 11 lines · Witold Sadowski
Quoted 10 lines
Confusing wording aside, using the same generic compatible for different SoCs is what I trying to avoid. I don't mind there being a fallback compatible that's generic, but I want to see specific compatibles here for the individual SoCs.
If you did actually mean that only the packaging is different between the devices, then I don't think you need specific compatibles for each different package, but you should have one for the SoC itself IMO.
Quoted 5 lines
We can have SoC A, B with common xSPI block, and both of them can share Same dtb node with compatible property "marvell,cn10k,xspi-nor" for example. I don't think it will be beneficial to have different compatible name for each different SoC, for example "marvell,t98,xspi-nor", if all other parts will be the same. Or am I not correct?
Please see writing bindings (or any presentation for DTS and bindings):
you are expected to have SoC specific compatibles for every block in the SoC. There are many examples in recent bindings, so take a look there.
Best regards,
Krzysztof
Re: [PATCH v3 2/5] spi: cadence: Add MRVL overlay bindings documentation for Cadence XSPI
In reply to Witold SadowskiQuoted 5 lines · Witold Sadowski
Add new bindings for v2 Marvell xSPI overlay:
mrvl,xspi-nor compatible string
New compatible string to distinguish between orginal and modified xSPI block
Do not attach (thread) your patchsets to some other threads (unrelated or older versions). This buries them deep in the mailbox and might interfere with applying entire sets.
Quoted 9 lines
PHY configuration registers
Allow to change orginal xSPI PHY configuration values. If not set, and Marvell overlay is enabled, safe defaults will be written into xSPI PHYOptional base for xfer register set
Additional reg field to allocate xSPI Marvell overlay XFER blockSigned-off-by Witold Sadowski <[email protected]>---
Please use subject prefixes matching the subsystem. You can get them for example with git log --oneline -- DIRECTORY_OR_FILE on the directory your patch is touching.
You already received *exactly* the same comment. Can you respond to feedbacks and acknowledge that you will implement them?
Please provide changelog and explain what happened in between. There were several comments already, so did you implement them? Were they ignored?
There was no single response from you.
Quoted 11 lines
.../devicetree/bindings/spi/cdns,xspi.yaml | 92 ++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-)Documentation/devicetree/bindings/spi/cdns,xspi.yaml +0
-0@@ -20,23 +20,82 @@ allOf: properties: compatible:
Documentation/devicetree/bindings/spi/cdns,xspi.yaml allOf: · line 31
Quoted 10 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +8
-1- const: cdns,xspi-nor + oneOf: + - description: Vanilla Cadence xSPI controller + items: + - const: cdns,xspi-nor + - description: Cadence xSPI controller with v2 Marvell overlay + items: + - const: mrvl,xspi-nor +
No need for two blank lines. BTW, that's just enum.
Quoted 11 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +3
-0reg: + minItems: 3 items: - description: address and length of the controller register set - description: address and length of the Slave DMA data port - description: address and length of the auxiliary registers + - description: address and length of the xfer registers reg-names: + minItems: 3 items:
Documentation/devicetree/bindings/spi/cdns,xspi.yaml allOf: · line 52
Quoted 10 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +3
-0- const: io - const: sdma - const: aux + - const: xferbase interrupts: maxItems: 1 + cdns,dll-phy-control: + description: |
Do not need '|' unless you need to preserve formatting.
Quoted 31 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +31
-0+ PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x707 + + cdns,rfile-phy-control: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x40000 + + cdns,rfile-phy-tsel: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0 + + cdns,phy-dq-timing: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x101 + + cdns,phy-dqs-timing: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x700404 + + cdns,phy-gate-lpbk-ctrl: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor
Documentation/devicetree/bindings/spi/cdns,xspi.yaml allOf: · line 93
Quoted 10 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +10
-0+ $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x200030 + + cdns,phy-dll-master-ctrl: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x00800000 + + cdns,phy-dll-slave-ctrl:
Please use some easier to read logical properties, not just register values. Specifically, this is impossible to review whether any of these are actually OS policy, instead of hardware configuration.
You also miss constraining these and reg per variant (but that was mentioned by Conor, I think).
Best regards,
Krzysztof
RE: [EXTERNAL] Re: [PATCH v3 2/5] spi: cadence: Add MRVL overlay bindings documentation for Cadence XSPI
Quoted 11 lines
----------------------------------------------------------------------
Quoted 5 lines · Witold Sadowski
Add new bindings for v2 Marvell xSPI overlay:
mrvl,xspi-nor compatible string
New compatible string to distinguish between orginal and modified xSPI blockDo not attach (thread) your patchsets to some other threads (unrelated or older versions). This buries them deep in the mailbox and might interfere with applying entire sets.
Ok.
Quoted 16 lines
Quoted 11 lines
PHY configuration registers
Allow to change orginal xSPI PHY configuration values. If not set, and Marvell overlay is enabled, safe defaults will be written into xSPI PHYOptional base for xfer register set
Additional reg field to allocate xSPI Marvell overlay XFER blockSigned-off-by Witold Sadowski <[email protected]>---
Please use subject prefixes matching the subsystem. You can get them for example with
git log --oneline -- DIRECTORY_OR_FILEon the directory your patch is touching.
Quoted 8 lines
You already received *exactly* the same comment. Can you respond to feedbacks and acknowledge that you will implement them?
Please provide changelog and explain what happened in between. There were several comments already, so did you implement them? Were they ignored?
There was no single response from you.
Sorry for that. I will try to do better from now on.
Quoted 11 lines
Quoted 11 lines
.../devicetree/bindings/spi/cdns,xspi.yaml | 92 ++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-)Documentation/devicetree/bindings/spi/cdns,xspi.yaml +0
-0@@ -20,23 +20,82 @@ allOf:
Quoted 14 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml allOf: · line 31
Quoted 12 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +8
-1properties: compatible: - const: cdns,xspi-nor + oneOf: + - description: Vanilla Cadence xSPI controller + items: + - const: cdns,xspi-nor + - description: Cadence xSPI controller with v2 Marvell overlay + items: + - const: mrvl,xspi-nor +No need for two blank lines. BTW, that's just enum.
Ok, will change that.
Quoted 72 lines
Quoted 13 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +3
-0reg: + minItems: 3 items: - description: address and length of the controller register set - description: address and length of the Slave DMA data port - description: address and length of the auxiliary registers + - description: address and length of the xfer registers reg-names: + minItems: 3 items:Documentation/devicetree/bindings/spi/cdns,xspi.yaml allOf: · line 52
Quoted 10 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +3
-0- const: io - const: sdma - const: aux + - const: xferbase interrupts: maxItems: 1 + cdns,dll-phy-control: + description: |Do not need '|' unless you need to preserve formatting.
Quoted 31 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +31
-0+ PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x707 + + cdns,rfile-phy-control: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x40000 + + cdns,rfile-phy-tsel: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0 + + cdns,phy-dq-timing: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x101 + + cdns,phy-dqs-timing: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x700404 + + cdns,phy-gate-lpbk-ctrl: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-norDocumentation/devicetree/bindings/spi/cdns,xspi.yaml allOf: · line 93
Quoted 10 lines
Documentation/devicetree/bindings/spi/cdns,xspi.yaml +10
-0+ $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x200030 + + cdns,phy-dll-master-ctrl: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x00800000 + + cdns,phy-dll-slave-ctrl:Please use some easier to read logical properties, not just register values. Specifically, this is impossible to review whether any of these are actually OS policy, instead of hardware configuration.
Quoted 2 lines
You also miss constraining these and reg per variant (but that was mentioned by Conor, I think).
All of that will be removed, PHY configuration is stable around whole SPI frequency range. Internal SoC structure must be changed to change That values, it will be easier to track that in the driver, based on SoC version/overlay version(if ever that will be necessary)
Quoted 3 lines
Best regards,
Krzysztof
PATCH v3 3/5 spi: cadence: Add Marvell xSPI IP overlay changes
In reply to Witold SadowskiAdd support for basic v2 Marvell overlay block. Support for basic operation is added here: clock configuration, PHY configuration, interrupt configuration(enabling)
Clock divider block is build on top of Cadence xSPI IP, and divides external 800MHz clock. It allows only for a few different clock speeds starting from 6.25MHz up to 200MHz.
PHY configuration can be read from device-tree, if parameter is not present - safe defaults will be used..
In addition to handle interrupt propoerly driver must clear MSI-X interrupt bit, in addition to clearing xSPI interrupt bit. Interrupt masking must be disabled.
--- drivers/spi/spi-cadence-xspi.c | 326 ++++++++++++++++++++++++++++++++- 1 file changed, 318 insertions(+), 8 deletions(-)
drivers/spi/spi-cadence-xspi.c +318 -8
@@ -193,6 +193,44 @@ ((op)->data.dir == SPI_MEM_DATA_IN) ? \ CDNS_XSPI_STIG_CMD_DIR_READ : CDNS_XSPI_STIG_CMD_DIR_WRITE)) +/*PHY default values*/ +#define REGS_DLL_PHY_CTRL 0x00000707 +#define CTB_RFILE_PHY_CTRL 0x00004000 +#define RFILE_PHY_TSEL 0x00000000 +#define RFILE_PHY_DQ_TIMING 0x00000101 +#define RFILE_PHY_DQS_TIMING 0x00700404 +#define RFILE_PHY_GATE_LPBK_CTRL 0x00200030 +#define RFILE_PHY_DLL_MASTER_CTRL 0x00800000 +#define RFILE_PHY_DLL_SLAVE_CTRL 0x0000ff01 + +/*PHY config rtegisters*/ +#define CDNS_XSPI_RF_MINICTRL_REGS_DLL_PHY_CTRL 0x1034 +#define CDNS_XSPI_PHY_CTB_RFILE_PHY_CTRL 0x0080 +#define CDNS_XSPI_PHY_CTB_RFILE_PHY_TSEL 0x0084 +#define CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DQ_TIMING 0x0000 +#define CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DQS_TIMING 0x0004 +#define CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_GATE_LPBK_CTRL 0x0008 +#define CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DLL_MASTER_CTRL 0x000c +#define CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DLL_SLAVE_CTRL 0x0010 +#define CDNS_XSPI_DATASLICE_RFILE_PHY_DLL_OBS_REG_0 0x001c + +#define CDNS_XSPI_DLL_RST_N BIT(24) +#define CDNS_XSPI_DLL_LOCK BIT(0) + +/* Marvell clock config register */ +#define CDNS_MRVL_XSPI_CLK_CTRL_AUX_REG 0x2020 +#define CDNS_MRVL_XSPI_CLK_ENABLE BIT(0) +#define CDNS_MRVL_XSPI_CLK_DIV GENMASK(4, 1) +#define CDNS_MRVL_XSPI_IRQ_ENABLE BIT(6) + +/* Marvell MSI-X clear interrupt register */ +#define CDNS_MRVL_XSPI_SPIX_INTR_AUX 0x2000 +#define CDNS_MRVL_MSIX_CLEAR_IRQ 0x01 + +/* Marvell clock macros */ +#define CDNS_MRVL_XSPI_CLOCK_IO_HZ 800000000 +#define CDNS_MRVL_XSPI_CLOCK_DIVIDED (div) ((CDNS_MRVL_XSPI_CLOCK_IO_HZ) / (div)) +enum cdns_xspi_stig_instr_type {CDNS_XSPI_STIG_INSTR_TYPE_0 ,CDNS_XSPI_STIG_INSTR_TYPE_1 ,
@@ -212,6 +250,7 @@ enum cdns_xspi_stig_cmd_dir {struct cdns_xspi_dev {struct platform_device *pdev;struct device *dev; +bool mrvl_hw_overlay;void __iomem *iobase;void __iomem *auxbase;
@@ -232,6 +271,170 @@ struct cdns_xspi_dev {u8 hw_num_banks; }; +struct cdns_xspi_driver_data { +bool mrvl_hw_overlay; +}; + +static struct cdns_xspi_driver_data mrvl_driver_data = { + .mrvl_hw_overlay = true, +}; + +static struct cdns_xspi_driver_data cdns_driver_data = { + .mrvl_hw_overlay = false, +}; + +#define MRVL_DEFAULT_CLK 25000000 + +const int cdns_mrvl_xspi_clk_div_list[] = { +4 ,//0x0 = Divide by 4. SPI clock is 200 MHz. +6 ,//0x1 = Divide by 6. SPI clock is 133.33 MHz. +8 ,//0x2 = Divide by 8. SPI clock is 100 MHz. +10 ,//0x3 = Divide by 10. SPI clock is 80 MHz. +12 ,//0x4 = Divide by 12. SPI clock is 66.666 MHz. +16 ,//0x5 = Divide by 16. SPI clock is 50 MHz. +18 ,//0x6 = Divide by 18. SPI clock is 44.44 MHz. +20 ,//0x7 = Divide by 20. SPI clock is 40 MHz. +24 ,//0x8 = Divide by 24. SPI clock is 33.33 MHz. +32 ,//0x9 = Divide by 32. SPI clock is 25 MHz. +40 ,//0xA = Divide by 40. SPI clock is 20 MHz. +50 ,//0xB = Divide by 50. SPI clock is 16 MHz. +64 ,//0xC = Divide by 64. SPI clock is 12.5 MHz. +128 ,//0xD = Divide by 128. SPI clock is 6.25 MHz. +-1 //End of list +}; + +static bool cdns_xspi_reset_dll (struct cdns_xspi_dev *cdns_xspi) +{ +u32 dll_cntrl =readl (cdns_xspi->iobase + +CDNS_XSPI_RF_MINICTRL_REGS_DLL_PHY_CTRL ); +u32 dll_lock; + +/*Reset DLL*/ + dll_cntrl |=CDNS_XSPI_DLL_RST_N ; +writel (dll_cntrl, cdns_xspi->iobase + +CDNS_XSPI_RF_MINICTRL_REGS_DLL_PHY_CTRL ); + +/*Wait for DLL lock*/ +return readl_relaxed_poll_timeout (cdns_xspi->iobase + +CDNS_XSPI_INTR_STATUS_REG , + dll_lock, ((dll_lock &CDNS_XSPI_DLL_LOCK ) ==1 ),10 ,10000 ); +} + +static void cdns_configure_phy_register_io (struct cdns_xspi_dev *cdns_xspi, +const char *prop_name, +u64 default_value,u64 offset) +{ +struct device_node *node_prop = cdns_xspi->pdev->dev.of_node; +u64 phy_cfg; + +if (of_property_read_u64 (node_prop, prop_name, &phy_cfg)) + phy_cfg = default_value; +writel (phy_cfg, + cdns_xspi->iobase + offset); +} + +static void cdns_configure_phy_register_aux (struct cdns_xspi_dev *cdns_xspi, +const char *prop_name, +u64 default_value,u64 offset) +{ +struct device_node *node_prop = cdns_xspi->pdev->dev.of_node; +u64 phy_cfg; + +if (of_property_read_u64 (node_prop,"cdns,dll-phy-control" , &phy_cfg)) + phy_cfg = default_value; +writel (phy_cfg, + cdns_xspi->auxbase + offset); +} + +//Static confiuration of PHY +static bool cdns_xspi_configure_phy (struct cdns_xspi_dev *cdns_xspi) +{ +cdns_configure_phy_register_io (cdns_xspi, +"cdns,dll-phy-control" , +REGS_DLL_PHY_CTRL , +CDNS_XSPI_RF_MINICTRL_REGS_DLL_PHY_CTRL ); +cdns_configure_phy_register_aux (cdns_xspi, +"cdns,rfile-phy-control" , +CTB_RFILE_PHY_CTRL , +CDNS_XSPI_PHY_CTB_RFILE_PHY_CTRL ); +cdns_configure_phy_register_aux (cdns_xspi, +"cdns,rfile-phy-tsel" , +RFILE_PHY_TSEL , +CDNS_XSPI_PHY_CTB_RFILE_PHY_TSEL ); +cdns_configure_phy_register_aux (cdns_xspi, +"cdns,phy-dq-timing" , +RFILE_PHY_DQ_TIMING , +CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DQ_TIMING ); +cdns_configure_phy_register_aux (cdns_xspi, +"cdns,phy-dqs-timing" , +RFILE_PHY_DQS_TIMING , +CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DQS_TIMING ); +cdns_configure_phy_register_aux (cdns_xspi, +"cdns,phy-gate-lpbk-ctrl" , +RFILE_PHY_GATE_LPBK_CTRL , +CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_GATE_LPBK_CTRL ); +cdns_configure_phy_register_aux (cdns_xspi, +"cdns,phy-dll-master-ctrl" , +RFILE_PHY_DLL_MASTER_CTRL , +CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_GATE_LPBK_CTRL ); +cdns_configure_phy_register_aux (cdns_xspi, +"cdns,phy-dll-slave-ctrl" , +RFILE_PHY_DLL_SLAVE_CTRL , +CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DLL_SLAVE_CTRL ); + +return cdns_xspi_reset_dll (cdns_xspi); +} + +// Find max avalible clock +static bool cdns_mrvl_xspi_setup_clock (struct cdns_xspi_dev *cdns_xspi, +int requested_clk) +{ +int i =0 ; +int clk_val; +u32 clk_reg; +bool update_clk = false; + +while (cdns_mrvl_xspi_clk_div_list[i] >0 ) { + clk_val =CDNS_MRVL_XSPI_CLOCK_DIVIDED ( + cdns_mrvl_xspi_clk_div_list[i]); +if (clk_val <= requested_clk) +break ; + i++; + } + +if (cdns_mrvl_xspi_clk_div_list[i] ==-1 ) { +dev_info (cdns_xspi->dev, +"Unable to find clk div for CLK: %d - using 6.25MHz\n" , + requested_clk); + i =0x0D ; + }else { +dev_dbg (cdns_xspi->dev,"Found clk div: %d, clk val: %d\n" , + cdns_mrvl_xspi_clk_div_list[i], +CDNS_MRVL_XSPI_CLOCK_DIVIDED ( + cdns_mrvl_xspi_clk_div_list[i])); + } + + clk_reg =readl (cdns_xspi->auxbase +CDNS_MRVL_XSPI_CLK_CTRL_AUX_REG ); + +if (FIELD_GET (CDNS_MRVL_XSPI_CLK_DIV , clk_reg) != i) { + clk_reg &= ~CDNS_MRVL_XSPI_CLK_ENABLE ; +writel (clk_reg, + cdns_xspi->auxbase +CDNS_MRVL_XSPI_CLK_CTRL_AUX_REG ); + clk_reg =FIELD_PREP (CDNS_MRVL_XSPI_CLK_DIV , i); + clk_reg &= ~CDNS_MRVL_XSPI_CLK_DIV ; + clk_reg |=FIELD_PREP (CDNS_MRVL_XSPI_CLK_DIV , i); + clk_reg |=CDNS_MRVL_XSPI_CLK_ENABLE ; + clk_reg |=CDNS_MRVL_XSPI_IRQ_ENABLE ; + update_clk = true; + } + +if (update_clk) +writel (clk_reg, + cdns_xspi->auxbase +CDNS_MRVL_XSPI_CLK_CTRL_AUX_REG ); + +return update_clk; +} +static int cdns_xspi_wait_for_controller_idle (struct cdns_xspi_dev *cdns_xspi) {u32 ctrl_stat;
@@ -295,6 +498,10 @@ static void cdns_xspi_set_interrupts(struct cdns_xspi_dev *cdns_xspi, bool enabled) {u32 intr_enable; +u32 irq_status; + + irq_status =readl (cdns_xspi->iobase +CDNS_XSPI_INTR_STATUS_REG ); +writel (irq_status, cdns_xspi->iobase +CDNS_XSPI_INTR_STATUS_REG ); intr_enable =readl (cdns_xspi->iobase +CDNS_XSPI_INTR_ENABLE_REG );if (enabled)
@@ -319,6 +526,9 @@ static int cdns_xspi_controller_init(struct cdns_xspi_dev *cdns_xspi)return -EIO ; } +writel (FIELD_PREP (CDNS_XSPI_CTRL_WORK_MODE ,CDNS_XSPI_WORK_MODE_STIG ), + cdns_xspi->iobase +CDNS_XSPI_CTRL_CONFIG_REG ); + ctrl_features =readl (cdns_xspi->iobase +CDNS_XSPI_CTRL_FEATURES_REG ); cdns_xspi->hw_num_banks =FIELD_GET (CDNS_XSPI_NUM_BANKS , ctrl_features);cdns_xspi_set_interrupts (cdns_xspi, false);
@@ -326,6 +536,70 @@ static int cdns_xspi_controller_init(struct cdns_xspi_dev *cdns_xspi)return 0 ; } +static void mrvl_ioreadq (void __iomem *addr,void *buf,int len) +{ +int i =0 ; +int rcount = len /8 ; +int rcount_nf = len %8 ; +uint64_t tmp; +uint64_t *buf64 = (uint64_t *)buf; + +if (((uint64_t )buf %8 ) ==0 ) { +for (i =0 ; i < rcount; i++) + *buf64++ =readq (addr); + }else { +for (i =0 ; i < rcount; i++) { + tmp =readq (addr); +memcpy (buf+(i*8 ), &tmp,8 ); + } + } + +if (rcount_nf !=0 ) { + tmp =readq (addr); +memcpy (buf+(i*8 ), &tmp, rcount_nf); + } +} + +static void mrvl_iowriteq (void __iomem *addr,const void *buf,int len) +{ +int i =0 ; +int rcount = len /8 ; +int rcount_nf = len %8 ; +uint64_t tmp; +uint64_t *buf64 = (uint64_t *)buf; + +if (((uint64_t )buf %8 ) ==0 ) { +for (i =0 ; i < rcount; i++) +writeq (*buf64++, addr); + }else { +for (i =0 ; i < rcount; i++) { +memcpy (&tmp, buf+(i*8 ),8 ); +writeq (tmp, addr); + } + } + +if (rcount_nf !=0 ) { +memcpy (&tmp, buf+(i*8 ), rcount_nf); +writeq (tmp, addr); + } +} + +static void cdns_xspi_sdma_memread (struct cdns_xspi_dev *cdns_xspi,int len) +{ +if (cdns_xspi->mrvl_hw_overlay) +mrvl_ioreadq (cdns_xspi->sdmabase, cdns_xspi->in_buffer, len); +else +ioread8_rep (cdns_xspi->sdmabase, cdns_xspi->in_buffer, len); +} + +static void cdns_xspi_sdma_memwrite (struct cdns_xspi_dev *cdns_xspi,int len) +{ +if (cdns_xspi->mrvl_hw_overlay) +mrvl_iowriteq (cdns_xspi->sdmabase, cdns_xspi->out_buffer, len); +else +iowrite8_rep (cdns_xspi->sdmabase, cdns_xspi->out_buffer, len); +} +static void cdns_xspi_sdma_handle (struct cdns_xspi_dev *cdns_xspi) {u32 sdma_size, sdma_trd_info;
@@ -337,13 +611,11 @@ static void cdns_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi)switch (sdma_dir) {case CDNS_XSPI_SDMA_DIR_READ : -ioread8_rep (cdns_xspi->sdmabase, - cdns_xspi->in_buffer, sdma_size); +cdns_xspi_sdma_memread (cdns_xspi, sdma_size);break ;case CDNS_XSPI_SDMA_DIR_WRITE : -iowrite8_rep (cdns_xspi->sdmabase, - cdns_xspi->out_buffer, sdma_size); +cdns_xspi_sdma_memwrite (cdns_xspi, sdma_size);break ; } }
@@ -421,6 +693,9 @@ static int cdns_xspi_mem_op(struct cdns_xspi_dev *cdns_xspi,if (cdns_xspi->cur_cs !=spi_get_chipselect (mem->spi,0 )) cdns_xspi->cur_cs =spi_get_chipselect (mem->spi,0 ); +if (cdns_xspi->mrvl_hw_overlay) +cdns_mrvl_xspi_setup_clock (cdns_xspi, mem->spi->max_speed_hz); +return cdns_xspi_send_stig_command (cdns_xspi, op, (dir !=SPI_MEM_NO_DATA )); }
@@ -461,6 +736,10 @@ static irqreturn_t cdns_xspi_irq_handler(int this_irq, void *dev) irq_status =readl (cdns_xspi->iobase +CDNS_XSPI_INTR_STATUS_REG );writel (irq_status, cdns_xspi->iobase +CDNS_XSPI_INTR_STATUS_REG ); +if (cdns_xspi->mrvl_hw_overlay) +writel (CDNS_MRVL_MSIX_CLEAR_IRQ , + cdns_xspi->auxbase +CDNS_MRVL_XSPI_SPIX_INTR_AUX ); +if (irq_status & (CDNS_XSPI_SDMA_ERROR |CDNS_XSPI_SDMA_TRIGGER |CDNS_XSPI_STIG_DONE )) {
@@ -534,11 +813,23 @@ static void cdns_xspi_print_phy_config(struct cdns_xspi_dev *cdns_xspi) readl(cdns_xspi->auxbase + CDNS_XSPI_CCP_PHY_DLL_SLAVE_CTRL)); } +static int cdns_xspi_setup (struct spi_device *spi_dev) +{ +struct cdns_xspi_dev *cdns_xspi =spi_controller_get_devdata ( + spi_dev->controller); + +if (cdns_xspi->mrvl_hw_overlay) +cdns_mrvl_xspi_setup_clock (cdns_xspi, spi_dev->max_speed_hz); + +return 0 ; +} +static int cdns_xspi_probe (struct platform_device *pdev) {struct device *dev = &pdev->dev;struct spi_controller *host =NULL ;struct cdns_xspi_dev *cdns_xspi =NULL ; +const struct cdns_xspi_driver_data *drv_data;struct resource *res;int ret;
@@ -550,10 +841,16 @@ static int cdns_xspi_probe(struct platform_device *pdev)SPI_RX_DUAL |SPI_RX_QUAD |SPI_TX_OCTAL |SPI_RX_OCTAL |SPI_MODE_0 |SPI_MODE_3 ; + drv_data =of_device_get_match_data (dev); + host->mem_ops = &cadence_xspi_mem_ops; host->dev.of_node = pdev->dev.of_node; + host->dev.fwnode = pdev->dev.fwnode; host->bus_num =-1 ; +if (drv_data->mrvl_hw_overlay) + host->setup = cdns_xspi_setup; +platform_set_drvdata (pdev, host); cdns_xspi =spi_controller_get_devdata (host);
@@ -565,23 +862,27 @@ static int cdns_xspi_probe(struct platform_device *pdev)init_completion (&cdns_xspi->auto_cmd_complete);init_completion (&cdns_xspi->sdma_complete); + cdns_xspi->mrvl_hw_overlay = drv_data->mrvl_hw_overlay; + ret =cdns_xspi_of_get_plat_data (pdev);if (ret)return -ENODEV ; - cdns_xspi->iobase =devm_platform_ioremap_resource_byname (pdev,"io" ); + res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); + cdns_xspi->iobase =devm_ioremap_resource (dev, res);if (IS_ERR (cdns_xspi->iobase)) {dev_err (dev,"Failed to remap controller base address\n" );return PTR_ERR (cdns_xspi->iobase); } - res =platform_get_resource_byname (pdev,IORESOURCE_MEM ,"sdma" ); + res =platform_get_resource (pdev,IORESOURCE_MEM ,1 ); cdns_xspi->sdmabase =devm_ioremap_resource (dev, res);if (IS_ERR (cdns_xspi->sdmabase))return PTR_ERR (cdns_xspi->sdmabase); cdns_xspi->sdmasize =resource_size (res); - cdns_xspi->auxbase =devm_platform_ioremap_resource_byname (pdev,"aux" ); + res =platform_get_resource (pdev,IORESOURCE_MEM ,2 ); + cdns_xspi->auxbase =devm_ioremap_resource (dev, res);if (IS_ERR (cdns_xspi->auxbase)) {dev_err (dev,"Failed to remap AUX address\n" );return PTR_ERR (cdns_xspi->auxbase);
@@ -598,8 +899,12 @@ static int cdns_xspi_probe(struct platform_device *pdev)return ret; } -cdns_xspi_print_phy_config (cdns_xspi); +if (drv_data->mrvl_hw_overlay) { +cdns_mrvl_xspi_setup_clock (cdns_xspi,MRVL_DEFAULT_CLK ); +cdns_xspi_configure_phy (cdns_xspi); + } +cdns_xspi_print_phy_config (cdns_xspi); ret =cdns_xspi_controller_init (cdns_xspi);if (ret) {dev_err (dev,"Failed to initialize controller\n" );
@@ -622,6 +927,11 @@ static int cdns_xspi_probe(struct platform_device *pdev)static const struct of_device_id cdns_xspi_of_match[] = { { .compatible ="cdns,xspi-nor" , + .data = &cdns_driver_data, + }, + { + .compatible ="mrvl,xspi-nor" , + .data = &mrvl_driver_data, }, {/* end of table */ } };
Signature · 1 line
2.43.0
kernel test robot
build botRe: [PATCH v3 3/5] spi: cadence: Add Marvell xSPI IP overlay changes
kernel test robot noticed the following build warnings:
Hi Witold,
kernel test robot noticed the following build warnings:
[auto build test WARNING on v6.9-rc4]
[also build test WARNING on linus/master next-20240418] [cannot apply to broonie-spi/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Witold-Sadowski/spi-cadence-Ensure-data-lines-set-to-low-during-dummy-cycle-period/20240418-091647 base: v6.9-rc4 patch link: https://lore.kernel.org/r/20240418011353.1764672-4-wsadowski%40marvell.com patch subject: [PATCH v3 3/5] spi: cadence: Add Marvell xSPI IP overlay changes config: x86_64-randconfig-122-20240419 (https://download.01.org/0day-ci/archive/20240419/[email protected]/config) compiler: gcc-13 (Ubuntu 13.2.0-4ubuntu3) 13.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240419/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
sparse warnings: (new ones prefixed by >>)
>> drivers/spi/spi-cadence-xspi.c:288:11: sparse: sparse: symbol 'cdns_mrvl_xspi_clk_div_list' was not declared. Should it be static?
vim +/cdns_mrvl_xspi_clk_div_list +288 drivers/spi/spi-cadence-xspi.c
287
> 288 const int cdns_mrvl_xspi_clk_div_list[] = {
289 4, //0x0 = Divide by 4. SPI clock is 200 MHz.
290 6, //0x1 = Divide by 6. SPI clock is 133.33 MHz.
291 8, //0x2 = Divide by 8. SPI clock is 100 MHz.
292 10, //0x3 = Divide by 10. SPI clock is 80 MHz.
293 12, //0x4 = Divide by 12. SPI clock is 66.666 MHz.
294 16, //0x5 = Divide by 16. SPI clock is 50 MHz.
295 18, //0x6 = Divide by 18. SPI clock is 44.44 MHz.
296 20, //0x7 = Divide by 20. SPI clock is 40 MHz.
297 24, //0x8 = Divide by 24. SPI clock is 33.33 MHz.
298 32, //0x9 = Divide by 32. SPI clock is 25 MHz.
299 40, //0xA = Divide by 40. SPI clock is 20 MHz.
300 50, //0xB = Divide by 50. SPI clock is 16 MHz.
301 64, //0xC = Divide by 64. SPI clock is 12.5 MHz. 302 128, //0xD = Divide by 128. SPI clock is 6.25 MHz.
303 -1 //End of list
304 };
305
Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
PATCH v3 4/5 spi: cadence: Allow to read basic xSPI configuration from ACPI
In reply to Witold SadowskiFrom: Piyush Malgujar <[email protected]>
These changes enables to read the configs from ACPI tables as required for successful probing in ACPI uefi environment.
In case of ACPI disabled/dts based environment, it will continue to read configs from dts as before
--- drivers/spi/spi-cadence-xspi.c | 97 +++++++++++++++++++++++++++++++--- 1 file changed, 90 insertions(+), 7 deletions(-)
drivers/spi/spi-cadence-xspi.c +90 -7
@@ -2,6 +2,7 @@// Cadence XSPI flash controller driver // Copyright (C) 2020-21 Cadence +#include <linux/acpi.h> #include <linux/completion.h> #include <linux/delay.h> #include <linux/err.h>
@@ -14,6 +15,7 @@#include <linux/of.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> +#include <linux/property.h> #include <linux/spi/spi.h> #include <linux/spi/spi-mem.h> #include <linux/bitfield.h>
@@ -700,6 +702,67 @@ static int cdns_xspi_mem_op(struct cdns_xspi_dev *cdns_xspi, (dir != SPI_MEM_NO_DATA)); } +#ifdef CONFIG_ACPI +static bool cdns_xspi_supports_op (struct spi_mem *mem, +const struct spi_mem_op *op) +{ +struct spi_device *spi = mem->spi; +const union acpi_object *obj; +struct acpi_device *adev; + + adev =ACPI_COMPANION (&spi->dev); + +if (!acpi_dev_get_property (adev,"spi-tx-bus-width" ,ACPI_TYPE_INTEGER , + &obj)) { +switch (obj->integer.value) { +case 1 : +break ; +case 2 : + spi->mode |=SPI_TX_DUAL ; +break ; +case 4 : + spi->mode |=SPI_TX_QUAD ; +break ; +case 8 : + spi->mode |=SPI_TX_OCTAL ; +break ; +default : +dev_warn (&spi->dev, +"spi-tx-bus-width %lld not supported\n" , + obj->integer.value); +break ; + } + } + +if (!acpi_dev_get_property (adev,"spi-rx-bus-width" ,ACPI_TYPE_INTEGER , + &obj)) { +switch (obj->integer.value) { +case 1 : +break ; +case 2 : + spi->mode |=SPI_RX_DUAL ; +break ; +case 4 : + spi->mode |=SPI_RX_QUAD ; +break ; +case 8 : + spi->mode |=SPI_RX_OCTAL ; +break ; +default : +dev_warn (&spi->dev, +"spi-rx-bus-width %lld not supported\n" , + obj->integer.value); +break ; + } + } + +if (!spi_mem_default_supports_op (mem, op)) +return false; + +return true; +} +#endif +static int cdns_xspi_mem_op_execute (struct spi_mem *mem,const struct spi_mem_op *op) {
@@ -723,6 +786,9 @@ static int cdns_xspi_adjust_mem_op_size(struct spi_mem *mem, struct spi_mem_op * }static const struct spi_controller_mem_ops cadence_xspi_mem_ops = { +#ifdef CONFIG_ACPI + .supports_op = cdns_xspi_supports_op, +#endif .exec_op = cdns_xspi_mem_op_execute, .adjust_op_size = cdns_xspi_adjust_mem_op_size, };
@@ -774,21 +840,20 @@ static irqreturn_t cdns_xspi_irq_handler(int this_irq, void *dev)static int cdns_xspi_of_get_plat_data (struct platform_device *pdev) { -struct device_node *node_prop = pdev->dev.of_node; -struct device_node *node_child; +struct fwnode_handle *fwnode_child;unsigned int cs; -for_each_child_of_node (node_prop, node_child) { -if (!of_device_is_available (node_child)) +device_for_each_child_node (&pdev->dev, fwnode_child) { +if (!fwnode_device_is_available (fwnode_child))continue ; -if (of_property_read_u32 (node_child,"reg" , &cs)) { +if (fwnode_property_read_u32 (fwnode_child,"reg" , &cs)) {dev_err (&pdev->dev,"Couldn't get memory chip select\n" ); -of_node_put (node_child); +fwnode_handle_put (fwnode_child);return -ENXIO ; }else if (cs >=CDNS_XSPI_MAX_BANKS ) {dev_err (&pdev->dev,"reg (cs) parameter value too large\n" ); -of_node_put (node_child); +fwnode_handle_put (fwnode_child);return -ENXIO ; } }
@@ -924,6 +989,21 @@ static int cdns_xspi_probe(struct platform_device *pdev)return 0 ; } +#ifdef CONFIG_ACPI +static const struct acpi_device_id cdns_xspi_acpi_match[] = { + { + .id ="cdns,xspi-nor" , + .driver_data = (kernel_ulong_t) &cdns_driver_data, + }, + { + .id ="mrvl,xspi-nor" , + .driver_data = (kernel_ulong_t) &mrvl_driver_data, + }, + {}, +}; +MODULE_DEVICE_TABLE (acpi, cdns_xspi_acpi_match); +#endif +static const struct of_device_id cdns_xspi_of_match[] = { { .compatible ="cdns,xspi-nor" ,
@@ -942,6 +1022,9 @@ static struct platform_driver cdns_xspi_platform_driver = { .driver = { .name = CDNS_XSPI_NAME, .of_match_table = cdns_xspi_of_match, +#ifdef CONFIG_ACPI + .acpi_match_table = cdns_xspi_acpi_match, +#endif }, };
Signature · 1 line
2.43.0
Re: [PATCH v3 4/5] spi: cadence: Allow to read basic xSPI configuration from ACPI
Quoted 7 lines · Witold Sadowski
From: Piyush Malgujar <[email protected]>
These changes enables to read the configs from ACPI tables as required for successful probing in ACPI uefi environment.
In case of ACPI disabled/dts based environment, it will continue to read configs from dts as before
...
Quoted 4 lines
drivers/spi/spi-cadence-xspi.c +0
-0}@@ -924,6 +989,21 @@ static int cdns_xspi_probe(struct platform_device *pdev)return 0 ; }
drivers/spi/spi-cadence-xspi.c static int cdns_xspi_probe(struct platform_device *pdev) · line 1000
Quoted 10 lines
drivers/spi/spi-cadence-xspi.c +9
-0+#ifdef CONFIG_ACPI +static const struct acpi_device_id cdns_xspi_acpi_match[] = { + { + .id = "cdns,xspi-nor", + .driver_data = (kernel_ulong_t) &cdns_driver_data, + }, + { + .id = "mrvl,xspi-nor", + .driver_data = (kernel_ulong_t) &mrvl_driver_data,
UEFI provides compatibles for ACPI? I think that's first such format in the kernel.
Best regards,
Krzysztof
RE: [EXTERNAL] Re: [PATCH v3 4/5] spi: cadence: Allow to read basic xSPI configuration from ACPI
Quoted 17 lines · Witold Sadowski
Quoted 7 lines
From: Piyush Malgujar <[email protected]>
These changes enables to read the configs from ACPI tables as required for successful probing in ACPI uefi environment.
In case of ACPI disabled/dts based environment, it will continue to read configs from dts as before...
Review static int cdns_xspi_probe(struct platform_device
Quoted 2 lines
(quoted diff) +0
-0}@@ -924,6 +989,21 @@ static int cdns_xspi_probe(struct platform_device*pdev)
Quoted 3 lines
drivers/spi/spi-cadence-xspi.c +0
-0return 0 ; }
Quoted 12 lines
drivers/spi/spi-cadence-xspi.c static int cdns_xspi_probe(struct platform_device *pdev) · line 1000
Quoted 9 lines
drivers/spi/spi-cadence-xspi.c +9
-0+#ifdef CONFIG_ACPI +static const struct acpi_device_id cdns_xspi_acpi_match[] = { + { + .id = "cdns,xspi-nor", + .driver_data = (kernel_ulong_t) &cdns_driver_data, + }, + { + .id = "mrvl,xspi-nor", + .driver_data = (kernel_ulong_t) &mrvl_driver_data,UEFI provides compatibles for ACPI? I think that's first such format in the kernel.
Yes, that code is not doing what was expected.
Current usage scenario in ACPI mode is:
xSPI block with HID PRP0001, and additional compatible package set to correct compatible string
With that approach only issue(in ACPI mode) is with matching device with data field from of_device_id. It looks like there are functions to match that when DTB is used, but in ACPI mode it fails. I believe solution is to traverse dev->driver->of_match_table manually To match device name with correct compatible data structure. That will be included in next patchset.
Quoted 3 lines
Best regards,
Krzysztof
Regards
Witek
Re: [EXTERNAL] Re: [PATCH v3 4/5] spi: cadence: Allow to read basic xSPI configuration from ACPI
Quoted 14 lines · Witold Sadowski
Quoted 13 lines
drivers/spi/spi-cadence-xspi.c static int cdns_xspi_probe(struct platform_device *pdev) · line 1000
Quoted 10 lines
drivers/spi/spi-cadence-xspi.c +9
-0+#ifdef CONFIG_ACPI +static const struct acpi_device_id cdns_xspi_acpi_match[] = { + { + .id = "cdns,xspi-nor", + .driver_data = (kernel_ulong_t) &cdns_driver_data, + }, + { + .id = "mrvl,xspi-nor", + .driver_data = (kernel_ulong_t) &mrvl_driver_data,UEFI provides compatibles for ACPI? I think that's first such format in the kernel.
Quoted 10 lines
Yes, that code is not doing what was expected.
Current usage scenario in ACPI mode is:
xSPI block with HID PRP0001, and additional compatible package set to correct compatible string
With that approach only issue(in ACPI mode) is with matching device with data field fromof_device_id. It looks like there are functions to match that when DTB is used, but in ACPI mode it fails. I believe solution is to traversedev->driver->of_match_tablemanually To match device name with correct compatible data structure. That will be included in next patchset.
PRP0001 should be handled by regular of_device_id table, of course assuming your kernel has build-in CONFIG_OF.
Best regards,
Krzysztof
RE: [EXTERNAL] Re: [PATCH v3 4/5] spi: cadence: Allow to read basic xSPI configuration from ACPI
Quoted 26 lines · Witold Sadowski
Quoted 14 lines
Quoted 13 lines
drivers/spi/spi-cadence-xspi.c static int cdns_xspi_probe(struct platform_device *pdev) · line 1000
Quoted 10 lines
drivers/spi/spi-cadence-xspi.c +9
-0+#ifdef CONFIG_ACPI +static const struct acpi_device_id cdns_xspi_acpi_match[] = { + { + .id = "cdns,xspi-nor", + .driver_data = (kernel_ulong_t) &cdns_driver_data, + }, + { + .id = "mrvl,xspi-nor", + .driver_data = (kernel_ulong_t) &mrvl_driver_data,UEFI provides compatibles for ACPI? I think that's first such format in the kernel.
Quoted 10 lines
Yes, that code is not doing what was expected.
Current usage scenario in ACPI mode is:
xSPI block with HID PRP0001, and additional compatible package set to correct compatible string With that approach only issue(in ACPI mode) is with matching device with data field fromof_device_id. It looks like there are functions to match that when DTB is used, but in ACPI mode it fails.
I believe solution is to traversedev->driver->of_match_tablemanually To match device name with correct compatible data structure. That will be included in next patchset.
Quoted 2 lines
PRP0001 should be handled by regular
of_device_idtable, of course assuming your kernel has build-inCONFIG_OF.
And it is correctly matched by id, but functions to retrieve data fails. I'm referring to of_device_get_match_data - there is no of node in ACPI case.
I have come up with solution, as I wasn't able to find similar function that will work with ACPI and dtb on the same time:
static const void * cdns_xspi_get_data(struct device *dev)
{
const struct of_device_id *matches = dev->driver->of_match_table;
for (; matches->name[0] || matches->type[0] || matches->compatible[0];
matches++) {
if (device_is_compatible(dev, matches->compatible))
return matches->data;
}
return NULL;
}Is there a better way to handle that?
Quoted 3 lines
Best regards,
Krzysztof
Mark Brown
maintainerRe: [EXTERNAL] Re: [PATCH v3 4/5] spi: cadence: Allow to read basic xSPI configuration from ACPI
Quoted 3 lines · Witold Sadowski
I have come up with solution, as I wasn't able to find similar function that will work with ACPI and dtb on the same time:
The usual thing would just be to try both an ACPI match and an OF match.
RE: [EXTERNAL] Re: [PATCH v3 4/5] spi: cadence: Allow to read basic xSPI configuration from ACPI
Quoted 7 lines · Witold Sadowski
Quoted 4 lines
I have come up with solution, as I wasn't able to find similar function that will work with ACPI and dtb on the same time:
The usual thing would just be to try both an ACPI match and an OF match.
Ok, thanks. I thought it can be done in single step.
PATCH v3 5/5 spi: cadence: Add MRVL overlay xfer operation support
In reply to Witold SadowskiMRVL Xfer overlay extend xSPI capabilities, to support non-memory SPI operations. Marvell overlay combined with generic command allows to create full-duplex SPI transactions. It also allows to create transaction with undetermined transaction length - with cs_hold parameter, and ability to extend CS signal assertion, even if xSPI block requests CS signal de-assertion.
--- drivers/spi/spi-cadence-xspi.c | 248 +++++++++++++++++++++++++++++++++ 1 file changed, 248 insertions(+)
drivers/spi/spi-cadence-xspi.c +248 -0
@@ -219,20 +219,39 @@#define CDNS_XSPI_DLL_RST_N BIT(24)#define CDNS_XSPI_DLL_LOCK BIT(0) +#define CDNS_XSPI_POLL_TIMEOUT_US 1000 +#define CDNS_XSPI_POLL_DELAY_US 10 +/* Marvell clock config register */ #define CDNS_MRVL_XSPI_CLK_CTRL_AUX_REG 0x2020#define CDNS_MRVL_XSPI_CLK_ENABLE BIT(0)#define CDNS_MRVL_XSPI_CLK_DIV GENMASK(4, 1)#define CDNS_MRVL_XSPI_IRQ_ENABLE BIT(6) +/* Marvell MSI-X clear interrupt register */ #define CDNS_MRVL_XSPI_SPIX_INTR_AUX 0x2000#define CDNS_MRVL_MSIX_CLEAR_IRQ 0x01 +#define SPIX_XFER_FUNC_CTRL 0x210 +#define SPIX_XFER_FUNC_CTRL_READ_DATA (i) (0x000 + 8 * (i)) +/* Marvell clock macros */ #define CDNS_MRVL_XSPI_CLOCK_IO_HZ 800000000#define CDNS_MRVL_XSPI_CLOCK_DIVIDED (div) ((CDNS_MRVL_XSPI_CLOCK_IO_HZ) / (div)) +/* Marvell XFER registers */ +#define XFER_SOFT_RESET BIT(11) +#define XFER_CS_N_HOLD GENMASK(9, 6) +#define XFER_RECEIVE_ENABLE BIT(4) +#define XFER_FUNC_ENABLE BIT(3) +#define XFER_CLK_CAPTURE_POL BIT(2) +#define XFER_CLK_DRIVE_POL BIT(1) +#define XFER_FUNC_START BIT(0) + +#define XFER_QWORD_COUNT 32 +#define XFER_QWORD_BYTECOUNT 8 +enum cdns_xspi_stig_instr_type {CDNS_XSPI_STIG_INSTR_TYPE_0 ,CDNS_XSPI_STIG_INSTR_TYPE_1 ,
@@ -257,6 +276,7 @@ struct cdns_xspi_dev {void __iomem *iobase;void __iomem *auxbase;void __iomem *sdmabase; +void __iomem *xferbase;int irq;int cur_cs;
@@ -271,6 +291,9 @@ struct cdns_xspi_dev {const void *out_buffer;u8 hw_num_banks; + +bool xfer_in_progress; +int current_xfer_qword; };struct cdns_xspi_driver_data {
@@ -889,6 +912,220 @@ static int cdns_xspi_setup(struct spi_device *spi_dev)return 0 ; } +static int cdns_xspi_prepare_generic (int cs,const void *dout,int len,int glue,u32 *cmd_regs) +{ +u8 *data = (u8 *)dout; +int i; +int data_counter =0 ; + +memset (cmd_regs,0x00 ,6 *4 ); + +if (len >7 ) { +for (i = (len >=10 ?2 : len -8 ); i >=0 ; i--) + cmd_regs[3 ] |= data[data_counter++] << (8 *i); + } +if (len >3 ) { +for (i = (len >=7 ?3 : len -4 ); i >=0 ; i--) + cmd_regs[2 ] |= data[data_counter++] << (8 *i); + } +for (i = (len >=3 ?2 : len -1 ); i >=0 ; i--) + cmd_regs[1 ] |= data[data_counter++] << (8 +8 *i); + + cmd_regs[1 ] |=96 ; + cmd_regs[3 ] |= len <<24 ; + cmd_regs[4 ] |= cs <<12 ; + +if (glue ==1 ) + cmd_regs[4 ] |=1 <<28 ; + +return 0 ; +} + +static unsigned char reverse_bits (unsigned char num) +{ +unsigned int count =sizeof (num) *8 -1 ; +unsigned int reverse_num = num; + + num >>=1 ; +while (num) { + reverse_num <<=1 ; + reverse_num |= num &1 ; + num >>=1 ; + count--; + } + reverse_num <<= count; +return reverse_num; +} + +static void cdns_xspi_read_single_qword (struct cdns_xspi_dev *cdns_xspi,u8 **buffer) +{ +u64 d =readq (cdns_xspi->xferbase + +SPIX_XFER_FUNC_CTRL_READ_DATA (cdns_xspi->current_xfer_qword)); +u8 *ptr = (u8 *)&d; +int k; + +for (k =0 ; k <8 ; k++) { +u8 val =reverse_bits ((ptr[k])); + **buffer = val; + *buffer = *buffer +1 ; + } + + cdns_xspi->current_xfer_qword++; + cdns_xspi->current_xfer_qword %=XFER_QWORD_COUNT ; +} + +static void cdns_xspi_finish_read (struct cdns_xspi_dev *cdns_xspi,u8 **buffer,u32 data_count) +{ +u64 d =readq (cdns_xspi->xferbase + +SPIX_XFER_FUNC_CTRL_READ_DATA (cdns_xspi->current_xfer_qword)); +u8 *ptr = (u8 *)&d; +int k; + +for (k =0 ; k < data_count %XFER_QWORD_BYTECOUNT ; k++) { +u8 val =reverse_bits ((ptr[k])); + **buffer = val; + *buffer = *buffer +1 ; + } + + cdns_xspi->current_xfer_qword++; + cdns_xspi->current_xfer_qword %=XFER_QWORD_COUNT ; +} + +static int cdns_xspi_prepare_transfer (int cs,int dir,int len,u32 *cmd_regs) +{ +memset (cmd_regs,0x00 ,6 *4 ); + + cmd_regs[1 ] |=127 ; + cmd_regs[2 ] |= len <<16 ; + cmd_regs[4 ] |= dir <<4 ;//dir = 0 read, dir =1 write + cmd_regs[4 ] |= cs <<12 ; + +return 0 ; +} + +static bool cdns_xspi_stig_ready (struct cdns_xspi_dev *cdns_xspi,bool sleep) +{ +u32 ctrl_stat; + +return readl_relaxed_poll_timeout + (cdns_xspi->iobase +CDNS_XSPI_CTRL_STATUS_REG , + ctrl_stat, + ((ctrl_stat &BIT (3 )) ==0 ), + sleep ?CDNS_XSPI_POLL_DELAY_US :0 , + sleep ?CDNS_XSPI_POLL_TIMEOUT_US :0 ); +} + +static bool cdns_xspi_sdma_ready (struct cdns_xspi_dev *cdns_xspi,bool sleep) +{ +u32 ctrl_stat; + +return readl_relaxed_poll_timeout + (cdns_xspi->iobase +CDNS_XSPI_INTR_STATUS_REG , + ctrl_stat, + (ctrl_stat &CDNS_XSPI_SDMA_TRIGGER ), + sleep ?CDNS_XSPI_POLL_DELAY_US :0 , + sleep ?CDNS_XSPI_POLL_TIMEOUT_US :0 ); +} + +static int cdns_xspi_transfer_one_message_b0 (struct spi_controller *controller, +struct spi_message *m) +{ +struct cdns_xspi_dev *cdns_xspi =spi_controller_get_devdata (controller); +struct spi_device *spi = m->spi; +struct spi_transfer *t =NULL ; + +const int max_len =XFER_QWORD_BYTECOUNT *XFER_QWORD_COUNT ; +int current_cycle_count; +int cs =spi_get_chipselect (spi,0 ); +int cs_change =0 ; + +/* Enable xfer state machine */ +if (!cdns_xspi->xfer_in_progress) { +u32 xfer_control =readl (cdns_xspi->xferbase +SPIX_XFER_FUNC_CTRL ); + + cdns_xspi->current_xfer_qword =0 ; + cdns_xspi->xfer_in_progress = true; + xfer_control |= (XFER_RECEIVE_ENABLE | +XFER_CLK_CAPTURE_POL | +XFER_FUNC_START | +XFER_SOFT_RESET | +FIELD_PREP (XFER_CS_N_HOLD , (1 << cs))); + xfer_control &= ~(XFER_FUNC_ENABLE |XFER_CLK_DRIVE_POL ); +writel (xfer_control, cdns_xspi->xferbase +SPIX_XFER_FUNC_CTRL ); + } + +list_for_each_entry (t, &m->transfers, transfer_list) { +u8 *txd = (u8 *) t->tx_buf; +u8 *rxd = (u8 *) t->rx_buf; +u8 data[10 ]; +u32 cmd_regs[6 ]; + +if (!txd) + txd = data; + + cdns_xspi->in_buffer = txd +1 ; + cdns_xspi->out_buffer = txd +1 ; + +while (t->len) { + + current_cycle_count = t->len > max_len ? max_len : t->len; + +if (current_cycle_count <10 ) { +cdns_xspi_prepare_generic (cs, txd, current_cycle_count, + false, cmd_regs); +cdns_xspi_trigger_command (cdns_xspi, cmd_regs); +if (cdns_xspi_stig_ready (cdns_xspi, true)) +return -EIO ; + }else { +cdns_xspi_prepare_generic (cs, txd,1 , true, cmd_regs); +cdns_xspi_trigger_command (cdns_xspi, cmd_regs); +cdns_xspi_prepare_transfer (cs,1 , current_cycle_count -1 , + cmd_regs); +cdns_xspi_trigger_command (cdns_xspi, cmd_regs); +if (cdns_xspi_sdma_ready (cdns_xspi, true)) +return -EIO ; +cdns_xspi_sdma_handle (cdns_xspi); +if (cdns_xspi_stig_ready (cdns_xspi, true)) +return -EIO ; + + cdns_xspi->in_buffer += current_cycle_count; + cdns_xspi->out_buffer += current_cycle_count; + } + +if (rxd) { +int j; + +for (j =0 ; j < current_cycle_count /8 ; j++) +cdns_xspi_read_single_qword (cdns_xspi, &rxd); +cdns_xspi_finish_read (cdns_xspi, &rxd, current_cycle_count); + }else { + cdns_xspi->current_xfer_qword += current_cycle_count / +XFER_QWORD_BYTECOUNT ; +if (current_cycle_count %XFER_QWORD_BYTECOUNT ) + cdns_xspi->current_xfer_qword++; + + cdns_xspi->current_xfer_qword %=XFER_QWORD_COUNT ; + } + cs_change = t->cs_change; + t->len -= current_cycle_count; + } + } + +if (!cs_change) { +u32 xfer_control =readl (cdns_xspi->xferbase +SPIX_XFER_FUNC_CTRL ); + + xfer_control &= ~(XFER_RECEIVE_ENABLE | +XFER_SOFT_RESET ); +writel (xfer_control, cdns_xspi->xferbase +SPIX_XFER_FUNC_CTRL ); + cdns_xspi->xfer_in_progress = false; + } + + m->status =0 ; +spi_finalize_current_message (controller); + +return 0 ; +} +static int cdns_xspi_probe (struct platform_device *pdev) {struct device *dev = &pdev->dev;
@@ -953,6 +1190,16 @@ static int cdns_xspi_probe(struct platform_device *pdev)return PTR_ERR (cdns_xspi->auxbase); } +if (drv_data->mrvl_hw_overlay) { + res =platform_get_resource (pdev,IORESOURCE_MEM ,3 ); + cdns_xspi->xferbase =devm_ioremap_resource (dev, res); +if (IS_ERR (cdns_xspi->xferbase)) { +dev_info (dev,"XFER register base not found, set it\n" ); +// For compatibility with older firmware + cdns_xspi->xferbase = cdns_xspi->iobase +0x8000 ; + } + } + cdns_xspi->irq =platform_get_irq (pdev,0 );if (cdns_xspi->irq <0 )return -ENXIO ;
@@ -967,6 +1214,7 @@ static int cdns_xspi_probe(struct platform_device *pdev)if (drv_data->mrvl_hw_overlay) {cdns_mrvl_xspi_setup_clock (cdns_xspi,MRVL_DEFAULT_CLK );cdns_xspi_configure_phy (cdns_xspi); + host->transfer_one_message = cdns_xspi_transfer_one_message_b0; }cdns_xspi_print_phy_config (cdns_xspi);
Signature · 1 line
2.43.0