Skip to content

Commit

Permalink
arch/arm64/lspi: improve spi initialization
Browse files Browse the repository at this point in the history
Hardware initialization is based refcount, not
spi enable bit. Interface to disable selected bus
added and interface to unitialize interface that
uses refcount

Signed-off-by: Jouni Ukkonen <[email protected]>
  • Loading branch information
joukkone committed Nov 19, 2024
1 parent 3873bcc commit 953dee1
Show file tree
Hide file tree
Showing 2 changed files with 163 additions and 49 deletions.
180 changes: 131 additions & 49 deletions arch/arm64/src/imx9/imx9_lpspi.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ struct imx9_lpspidev_s
sem_t txsem; /* Wait for TX DMA to complete */
void *txbuf; /* Driver DMA safe buffer for TX */
void *rxbuf; /* Driver DMA safe buffer for RX */
int refcount; /* SPIn initialization counter */
int bus_number; /* Bus number of instance */
#endif
};

Expand Down Expand Up @@ -264,6 +266,7 @@ static struct imx9_lpspidev_s g_lpspi1dev =
.rxsem = SEM_INITIALIZER(0),
.txsem = SEM_INITIALIZER(0),
#endif
.bus_number = 1,
};
#endif

Expand All @@ -287,6 +290,7 @@ static struct imx9_lpspidev_s g_lpspi2dev =
.rxsem = SEM_INITIALIZER(0),
.txsem = SEM_INITIALIZER(0),
#endif
.bus_number = 2,
};
#endif

Expand All @@ -310,6 +314,7 @@ static struct imx9_lpspidev_s g_lpspi3dev =
.rxsem = SEM_INITIALIZER(0),
.txsem = SEM_INITIALIZER(0),
#endif
.bus_number = 3,
};
#endif

Expand All @@ -333,6 +338,7 @@ static struct imx9_lpspidev_s g_lpspi4dev =
.rxsem = SEM_INITIALIZER(0),
.txsem = SEM_INITIALIZER(0),
#endif
.bus_number = 4,
};
#endif

Expand All @@ -356,6 +362,7 @@ static struct imx9_lpspidev_s g_lpspi5dev =
.rxsem = SEM_INITIALIZER(0),
.txsem = SEM_INITIALIZER(0),
#endif
.bus_number = 5,
};
#endif

Expand All @@ -379,6 +386,7 @@ static struct imx9_lpspidev_s g_lpspi6dev =
.rxsem = SEM_INITIALIZER(0),
.txsem = SEM_INITIALIZER(0),
#endif
.bus_number = 6,
};
#endif

Expand All @@ -402,6 +410,7 @@ static struct imx9_lpspidev_s g_lpspi7dev =
.rxsem = SEM_INITIALIZER(0),
.txsem = SEM_INITIALIZER(0),
#endif
.bus_number = 7,
};
#endif

Expand All @@ -425,6 +434,7 @@ static struct imx9_lpspidev_s g_lpspi8dev =
.rxsem = SEM_INITIALIZER(0),
.txsem = SEM_INITIALIZER(0),
#endif
.bus_number = 8,
};
#endif

Expand Down Expand Up @@ -1802,8 +1812,7 @@ struct spi_dev_s *imx9_lpspibus_initialize(int bus)

/* Only configure if the bus is not already configured */

if ((imx9_lpspi_getreg32(priv, IMX9_LPSPI_CR_OFFSET)
& LPSPI_CR_MEN) == 0)
if (priv->refcount == 0)
{
/* Configure SPI1 pins: SCK, MISO, and MOSI */

Expand All @@ -1817,10 +1826,6 @@ struct spi_dev_s *imx9_lpspibus_initialize(int bus)
#if defined(GPIO_LPSPI1_DC) && defined(CONFIG_SPI_CMDDATA)
imx9_iomux_configure(GPIO_LPSPI1_DC);
#endif

/* Set up default configuration: Master, 8-bit, etc. */

imx9_lpspi_bus_initialize(priv);
}
}
else
Expand All @@ -1834,8 +1839,7 @@ struct spi_dev_s *imx9_lpspibus_initialize(int bus)

/* Only configure if the bus is not already configured */

if ((imx9_lpspi_getreg32(priv, IMX9_LPSPI_CR_OFFSET)
& LPSPI_CR_MEN) == 0)
if (priv->refcount == 0)
{
/* Configure SPI2 pins: SCK, MISO, and MOSI */

Expand All @@ -1849,10 +1853,6 @@ struct spi_dev_s *imx9_lpspibus_initialize(int bus)
#if defined(GPIO_LPSPI2_DC) && defined(CONFIG_SPI_CMDDATA)
imx9_iomux_configure(GPIO_LPSPI2_DC);
#endif

/* Set up default configuration: Master, 8-bit, etc. */

imx9_lpspi_bus_initialize(priv);
}
}
else
Expand All @@ -1866,8 +1866,7 @@ struct spi_dev_s *imx9_lpspibus_initialize(int bus)

/* Only configure if the bus is not already configured */

if ((imx9_lpspi_getreg32(priv, IMX9_LPSPI_CR_OFFSET)
& LPSPI_CR_MEN) == 0)
if (priv->refcount == 0)
{
/* Configure SPI3 pins: SCK, MISO, and MOSI */

Expand All @@ -1881,10 +1880,6 @@ struct spi_dev_s *imx9_lpspibus_initialize(int bus)
#if defined(GPIO_LPSPI3_DC) && defined(CONFIG_SPI_CMDDATA)
imx9_iomux_configure(GPIO_LPSPI3_DC);
#endif

/* Set up default configuration: Master, 8-bit, etc. */

imx9_lpspi_bus_initialize(priv);
}
}
else
Expand All @@ -1898,8 +1893,7 @@ struct spi_dev_s *imx9_lpspibus_initialize(int bus)

/* Only configure if the bus is not already configured */

if ((imx9_lpspi_getreg32(priv, IMX9_LPSPI_CR_OFFSET)
& LPSPI_CR_MEN) == 0)
if (priv->refcount == 0)
{
/* Configure SPI4 pins: SCK, MISO, and MOSI */

Expand All @@ -1913,10 +1907,6 @@ struct spi_dev_s *imx9_lpspibus_initialize(int bus)
#if defined(GPIO_LPSPI4_DC) && defined(CONFIG_SPI_CMDDATA)
imx9_iomux_configure(GPIO_LPSPI4_DC);
#endif

/* Set up default configuration: Master, 8-bit, etc. */

imx9_lpspi_bus_initialize(priv);
}
}
else
Expand All @@ -1930,8 +1920,7 @@ struct spi_dev_s *imx9_lpspibus_initialize(int bus)

/* Only configure if the bus is not already configured */

if ((imx9_lpspi_getreg32(priv, IMX9_LPSPI_CR_OFFSET)
& LPSPI_CR_MEN) == 0)
if (priv->refcount == 0)
{
/* Configure SPI5 pins: SCK, MISO, and MOSI */

Expand All @@ -1945,10 +1934,6 @@ struct spi_dev_s *imx9_lpspibus_initialize(int bus)
#if defined(GPIO_LPSPI5_DC) && defined(CONFIG_SPI_CMDDATA)
imx9_iomux_configure(GPIO_LPSPI5_DC);
#endif

/* Set up default configuration: Master, 8-bit, etc. */

imx9_lpspi_bus_initialize(priv);
}
}
else
Expand All @@ -1962,8 +1947,7 @@ struct spi_dev_s *imx9_lpspibus_initialize(int bus)

/* Only configure if the bus is not already configured */

if ((imx9_lpspi_getreg32(priv, IMX9_LPSPI_CR_OFFSET)
& LPSPI_CR_MEN) == 0)
if (priv->refcount == 0)
{
/* Configure SPI6 pins: SCK, MISO, and MOSI */

Expand All @@ -1977,10 +1961,6 @@ struct spi_dev_s *imx9_lpspibus_initialize(int bus)
#if defined(GPIO_LPSPI6_DC) && defined(CONFIG_SPI_CMDDATA)
imx9_iomux_configure(GPIO_LPSPI6_DC);
#endif

/* Set up default configuration: Master, 8-bit, etc. */

imx9_lpspi_bus_initialize(priv);
}
}
else
Expand All @@ -1994,8 +1974,7 @@ struct spi_dev_s *imx9_lpspibus_initialize(int bus)

/* Only configure if the bus is not already configured */

if ((imx9_lpspi_getreg32(priv, IMX9_LPSPI_CR_OFFSET)
& LPSPI_CR_MEN) == 0)
if (priv->refcount == 0)
{
/* Configure SPI7 pins: SCK, MISO, and MOSI */

Expand All @@ -2009,10 +1988,6 @@ struct spi_dev_s *imx9_lpspibus_initialize(int bus)
#if defined(GPIO_LPSPI7_DC) && defined(CONFIG_SPI_CMDDATA)
imx9_iomux_configure(GPIO_LPSPI7_DC);
#endif

/* Set up default configuration: Master, 8-bit, etc. */

imx9_lpspi_bus_initialize(priv);
}
}
else
Expand All @@ -2026,8 +2001,7 @@ struct spi_dev_s *imx9_lpspibus_initialize(int bus)

/* Only configure if the bus is not already configured */

if ((imx9_lpspi_getreg32(priv, IMX9_LPSPI_CR_OFFSET)
& LPSPI_CR_MEN) == 0)
if (priv->refcount == 0)
{
/* Configure SPI6 pins: SCK, MISO, and MOSI */

Expand All @@ -2041,18 +2015,28 @@ struct spi_dev_s *imx9_lpspibus_initialize(int bus)
#if defined(GPIO_LPSPI8_DC) && defined(CONFIG_SPI_CMDDATA)
imx9_iomux_configure(GPIO_LPSPI8_DC);
#endif

/* Set up default configuration: Master, 8-bit, etc. */

imx9_lpspi_bus_initialize(priv);
}
}
else
#endif
{
leave_critical_section(flags);
spierr("ERROR: Unsupported SPI bus: %d\n", bus);
return NULL;
}

/* Set up default configuration: Master, 8-bit, etc. */

if (priv->refcount == 0)
{
/* Disable bus before initialization */

imx9_lpspibus_disable(bus);
imx9_lpspi_bus_initialize(priv);
}

priv->refcount++;

#ifdef CONFIG_IMX9_LPSPI_DMA
if (priv->rxch && priv->txch)
{
Expand Down Expand Up @@ -2084,8 +2068,106 @@ struct spi_dev_s *imx9_lpspibus_initialize(int bus)
#endif

leave_critical_section(flags);

return (struct spi_dev_s *)priv;
}

/****************************************************************************
* Name: imx9_lpspibus_disable
*
* Description:
* Disable selected bus unconditionally and set refcount to 0
*
* Input Parameters:
* Port number (for hardware that has multiple SPI interfaces)
*
* Returned Value:
* None
*
****************************************************************************/

void imx9_lpspibus_disable(int bus)
{
switch (bus)
{
#ifdef CONFIG_IMX9_LPSPI1
case 1:
modifyreg32(IMX9_LPSPI1_BASE + IMX9_LPSPI_CR_OFFSET, LPSPI_CR_MEN, 0);
g_lpspi1dev.refcount = 0;
break;
#endif
#ifdef CONFIG_IMX9_LPSPI2
case 2:
modifyreg32(IMX9_LPSPI2_BASE + IMX9_LPSPI_CR_OFFSET, LPSPI_CR_MEN, 0);
g_lpspi2dev.refcount = 0;
break;
#endif
#ifdef CONFIG_IMX9_LPSPI3
case 3:
modifyreg32(IMX9_LPSPI3_BASE + IMX9_LPSPI_CR_OFFSET, LPSPI_CR_MEN, 0);
g_lpspi3dev.refcount = 0;
break;
#endif
#ifdef CONFIG_IMX9_LPSPI4
case 4:
modifyreg32(IMX9_LPSPI4_BASE + IMX9_LPSPI_CR_OFFSET, LPSPI_CR_MEN, 0);
g_lpspi4dev.refcount = 0;
break;
#endif
#ifdef CONFIG_IMX9_LPSPI5
case 5:
modifyreg32(IMX9_LPSPI5_BASE + IMX9_LPSPI_CR_OFFSET, LPSPI_CR_MEN, 0);
g_lpspi5dev.refcount = 0;
break;
#endif
#ifdef CONFIG_IMX9_LPSPI6
case 6:
modifyreg32(IMX9_LPSPI6_BASE + IMX9_LPSPI_CR_OFFSET, LPSPI_CR_MEN, 0);
g_lpspi6dev.refcount = 0;
break;
#endif
#ifdef CONFIG_IMX9_LPSPI7
case 7:
modifyreg32(IMX9_LPSPI7_BASE + IMX9_LPSPI_CR_OFFSET, LPSPI_CR_MEN, 0);
g_lpspi7dev.refcount = 0;
break;
#endif
#ifdef CONFIG_IMX9_LPSPI8
case 8:
modifyreg32(IMX9_LPSPI8_BASE + IMX9_LPSPI_CR_OFFSET, LPSPI_CR_MEN, 0);
g_lpspi8dev.refcount = 0;
break;
#endif
default:
spierr("ERROR: Unsupported SPI bus: %d\n", bus);
}
}

/****************************************************************************
* Name: imx9_lpspibus_uninitialize
*
* Description:
* Unitialize the selected SPI bus
*
* Input Parameters:
* dev - Device-specific state data
*
* Returned Value:
* None
*
****************************************************************************/

void imx9_lpspi_uninitialize(struct spi_dev_s *dev)
{
struct imx9_lpspidev_s *priv = (struct imx9_lpspidev_s *)dev;

if (priv->refcount == 1)
{
imx9_lpspibus_disable(priv->bus_number);
}
else if (priv->refcount > 1)
{
priv->refcount--;
}
}

#endif /* CONFIG_IMX9_LPSPI */
Loading

0 comments on commit 953dee1

Please sign in to comment.