Skip to content

Commit 2c86060

Browse files
blarson866broonie
authored andcommitted
spi: dw: Add support for AMD Pensando Elba SoC
The AMD Pensando Elba SoC includes a DW apb_ssi v4 controller with device specific chip-select control. The Elba SoC provides four chip-selects where the native DW IP supports two chip-selects. The Elba DW_SPI instance has two native CS signals that are always overridden. Signed-off-by: Brad Larson <[email protected]> Reviewed-by: Serge Semin <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 6282a6c commit 2c86060

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

drivers/spi/spi-dw-mmio.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,20 @@ struct dw_spi_mscc {
5353
void __iomem *spi_mst; /* Not sparx5 */
5454
};
5555

56+
/*
57+
* Elba SoC does not use ssi, pin override is used for cs 0,1 and
58+
* gpios for cs 2,3 as defined in the device tree.
59+
*
60+
* cs: | 1 0
61+
* bit: |---3-------2-------1-------0
62+
* | cs1 cs1_ovr cs0 cs0_ovr
63+
*/
64+
#define ELBA_SPICS_REG 0x2468
65+
#define ELBA_SPICS_OFFSET(cs) ((cs) << 1)
66+
#define ELBA_SPICS_MASK(cs) (GENMASK(1, 0) << ELBA_SPICS_OFFSET(cs))
67+
#define ELBA_SPICS_SET(cs, val) \
68+
((((val) << 1) | BIT(0)) << ELBA_SPICS_OFFSET(cs))
69+
5670
/*
5771
* The Designware SPI controller (referred to as master in the documentation)
5872
* automatically deasserts chip select when the tx fifo is empty. The chip
@@ -237,6 +251,49 @@ static int dw_spi_canaan_k210_init(struct platform_device *pdev,
237251
return 0;
238252
}
239253

254+
static void dw_spi_elba_override_cs(struct regmap *syscon, int cs, int enable)
255+
{
256+
regmap_update_bits(syscon, ELBA_SPICS_REG, ELBA_SPICS_MASK(cs),
257+
ELBA_SPICS_SET(cs, enable));
258+
}
259+
260+
static void dw_spi_elba_set_cs(struct spi_device *spi, bool enable)
261+
{
262+
struct dw_spi *dws = spi_master_get_devdata(spi->master);
263+
struct dw_spi_mmio *dwsmmio = container_of(dws, struct dw_spi_mmio, dws);
264+
struct regmap *syscon = dwsmmio->priv;
265+
u8 cs;
266+
267+
cs = spi->chip_select;
268+
if (cs < 2)
269+
dw_spi_elba_override_cs(syscon, spi->chip_select, enable);
270+
271+
/*
272+
* The DW SPI controller needs a native CS bit selected to start
273+
* the serial engine.
274+
*/
275+
spi->chip_select = 0;
276+
dw_spi_set_cs(spi, enable);
277+
spi->chip_select = cs;
278+
}
279+
280+
static int dw_spi_elba_init(struct platform_device *pdev,
281+
struct dw_spi_mmio *dwsmmio)
282+
{
283+
struct regmap *syscon;
284+
285+
syscon = syscon_regmap_lookup_by_phandle(dev_of_node(&pdev->dev),
286+
"amd,pensando-elba-syscon");
287+
if (IS_ERR(syscon))
288+
return dev_err_probe(&pdev->dev, PTR_ERR(syscon),
289+
"syscon regmap lookup failed\n");
290+
291+
dwsmmio->priv = syscon;
292+
dwsmmio->dws.set_cs = dw_spi_elba_set_cs;
293+
294+
return 0;
295+
}
296+
240297
static int dw_spi_mmio_probe(struct platform_device *pdev)
241298
{
242299
int (*init_func)(struct platform_device *pdev,
@@ -350,6 +407,7 @@ static const struct of_device_id dw_spi_mmio_of_match[] = {
350407
{ .compatible = "intel,thunderbay-ssi", .data = dw_spi_intel_init},
351408
{ .compatible = "microchip,sparx5-spi", dw_spi_mscc_sparx5_init},
352409
{ .compatible = "canaan,k210-spi", dw_spi_canaan_k210_init},
410+
{ .compatible = "amd,pensando-elba-spi", .data = dw_spi_elba_init},
353411
{ /* end of table */}
354412
};
355413
MODULE_DEVICE_TABLE(of, dw_spi_mmio_of_match);

0 commit comments

Comments
 (0)