Re: [PATCH 6/7] spi: cadence: Add Marvell IP modification changes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 19/12/2022 15:42, Witold Sadowski wrote:
> 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.
> 
> Signed-off-by: Witold Sadowski <wsadowski@xxxxxxxxxxx>
> Reviewed-by: Chandrakala Chavva <cchavva@xxxxxxxxxxx>
> Tested-by: Sunil Kovvuri Goutham <sgoutham@xxxxxxxxxxx>
> ---
>  drivers/spi/Kconfig            |  12 +++
>  drivers/spi/spi-cadence-xspi.c | 172 ++++++++++++++++++++++++++++++++-
>  2 files changed, 183 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
> index 3b1c0878bb85..42af5943d00a 100644
> --- a/drivers/spi/Kconfig
> +++ b/drivers/spi/Kconfig
> @@ -251,6 +251,18 @@ config SPI_CADENCE_XSPI
>  	  device with a Cadence XSPI controller and want to access the
>  	  Flash as an MTD device.
>  
> +config SPI_CADENCE_MRVL_XSPI
> +	tristate "Marvell mods for XSPI controller"
> +	depends on SPI_CADENCE_XSPI
> +
> +	help
> +	  Enable support for Marvell XSPI modifications
> +
> +	  During implementation of Cadence XSPI core Marvell
> +	  has added some additional features like clock divider,
> +	  PHY config support or non-memory SPI capabilities.
> +	  Enable that option if you want to enable these features.
> +
>  config SPI_CLPS711X
>  	tristate "CLPS711X host SPI controller"
>  	depends on ARCH_CLPS711X || COMPILE_TEST
> diff --git a/drivers/spi/spi-cadence-xspi.c b/drivers/spi/spi-cadence-xspi.c
> index 719c2f3b4771..c73faf6b0546 100644
> --- a/drivers/spi/spi-cadence-xspi.c
> +++ b/drivers/spi/spi-cadence-xspi.c
> @@ -193,6 +193,46 @@
>  #define CDNS_XSPI_POLL_TIMEOUT_US	1000
>  #define CDNS_XSPI_POLL_DELAY_US	10
>  
> +#if IS_ENABLED(CONFIG_SPI_CADENCE_MRVL_XSPI)
> +/* clock config register */
> +#define CDNS_XSPI_CLK_CTRL_AUX_REG	0x2020
> +#define CDNS_XSPI_CLK_ENABLE		BIT(0)
> +#define CDNS_XSPI_CLK_DIV		GENMASK(4, 1)
> +
> +/* Clock macros */
> +#define CDNS_XSPI_CLOCK_IO_HZ 800000000
> +#define CDNS_XSPI_CLOCK_DIVIDED(div) ((CDNS_XSPI_CLOCK_IO_HZ) / (div))
> +
> +/*PHY default values*/

Keep consistent style.

> +#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)
> +
> +/* MSI-X clear interrupt register */
> +#define CDNS_XSPI_SPIX_INTR_AUX				0x2000
> +#define CDNS_MSIX_CLEAR_IRQ					0x01
> +
> +#endif
> +
>  enum cdns_xspi_stig_instr_type {
>  	CDNS_XSPI_STIG_INSTR_TYPE_0,
>  	CDNS_XSPI_STIG_INSTR_TYPE_1,
> @@ -238,6 +278,106 @@ struct cdns_xspi_dev {
>  	enum cdns_xspi_sdma_size read_size;
>  };
>  
> +#if IS_ENABLED(CONFIG_SPI_CADENCE_MRVL_XSPI)

Why this is under #if? Different devices have always built-in support
and behavior is determined by binding method (e.g. match data).

> +
> +#define MRVL_DEFAULT_CLK 25000000
> +
> +const int cdns_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

Why? This is a static list so size is known.

> +};
> +
> +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*/

All these comments miss spaces around.

> +	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 confiuration of PHY

Keep consistent style.

> +static bool cdns_xspi_configure_phy(struct cdns_xspi_dev *cdns_xspi)
> +{
> +	writel(REGS_DLL_PHY_CTRL,
> +		cdns_xspi->iobase + CDNS_XSPI_RF_MINICTRL_REGS_DLL_PHY_CTRL);

Don't you need a phy driver?

> +	writel(CTB_RFILE_PHY_CTRL,
> +		cdns_xspi->auxbase + CDNS_XSPI_PHY_CTB_RFILE_PHY_CTRL);
> +	writel(RFILE_PHY_TSEL,
> +		cdns_xspi->auxbase + CDNS_XSPI_PHY_CTB_RFILE_PHY_TSEL);
> +	writel(RFILE_PHY_DQ_TIMING,
> +		cdns_xspi->auxbase + CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DQ_TIMING);
> +	writel(RFILE_PHY_DQS_TIMING,
> +		cdns_xspi->auxbase + CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DQS_TIMING);
> +	writel(RFILE_PHY_GATE_LPBK_CTRL,
> +		cdns_xspi->auxbase + CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_GATE_LPBK_CTRL);
> +	writel(RFILE_PHY_DLL_MASTER_CTRL,
> +		cdns_xspi->auxbase + CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DLL_MASTER_CTRL);
> +	writel(RFILE_PHY_DLL_SLAVE_CTRL,
> +		cdns_xspi->auxbase + CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DLL_SLAVE_CTRL);
> +
> +	return cdns_xspi_reset_dll(cdns_xspi);
> +}
> +
> +// Find max avalible clock

Run spell-check.


Best regards,
Krzysztof




[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux