Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b42a81ca authored by Jassi Brar's avatar Jassi Brar Committed by Grant Likely
Browse files

spi/s3c64xx: Consider the clk_from_cmu flag



Newer SoCs have the SPI clock scaling control in platform's
clock management unit. Inorder for such SoCs to work, we need
to check the flag clk_from_cmu before making any clock changes.

Signed-off-by: default avatarJassi Brar <jassi.brar@samsung.com>
Signed-off-by: default avatarGrant Likely <grant.likely@secretlab.ca>
parent e02ddd44
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@ struct s3c64xx_spi_csinfo {
 * struct s3c64xx_spi_info - SPI Controller defining structure
 * @src_clk_nr: Clock source index for the CLK_CFG[SPI_CLKSEL] field.
 * @src_clk_name: Platform name of the corresponding clock.
 * @clk_from_cmu: If the SPI clock/prescalar control block is present
 *     by the platform's clock-management-unit and not in SPI controller.
 * @num_cs: Number of CS this controller emulates.
 * @cfg_gpio: Configure pins for this SPI controller.
 * @fifo_lvl_mask: All tx fifo_lvl fields start at offset-6
@@ -41,6 +43,7 @@ struct s3c64xx_spi_csinfo {
struct s3c64xx_spi_info {
	int src_clk_nr;
	char *src_clk_name;
	bool clk_from_cmu;

	int num_cs;

+56 −38
Original line number Diff line number Diff line
@@ -399,13 +399,18 @@ static inline void disable_cs(struct s3c64xx_spi_driver_data *sdd,

static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
{
	struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
	void __iomem *regs = sdd->regs;
	u32 val;

	/* Disable Clock */
	if (sci->clk_from_cmu) {
		clk_disable(sdd->src_clk);
	} else {
		val = readl(regs + S3C64XX_SPI_CLK_CFG);
		val &= ~S3C64XX_SPI_ENCLK_ENABLE;
		writel(val, regs + S3C64XX_SPI_CLK_CFG);
	}

	/* Set Polarity and Phase */
	val = readl(regs + S3C64XX_SPI_CH_CFG);
@@ -441,6 +446,13 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)

	writel(val, regs + S3C64XX_SPI_MODE_CFG);

	if (sci->clk_from_cmu) {
		/* Configure Clock */
		/* There is half-multiplier before the SPI */
		clk_set_rate(sdd->src_clk, sdd->cur_speed * 2);
		/* Enable Clock */
		clk_enable(sdd->src_clk);
	} else {
		/* Configure Clock */
		val = readl(regs + S3C64XX_SPI_CLK_CFG);
		val &= ~S3C64XX_SPI_PSR_MASK;
@@ -453,6 +465,7 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
		val |= S3C64XX_SPI_ENCLK_ENABLE;
		writel(val, regs + S3C64XX_SPI_CLK_CFG);
	}
}

static void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id,
				 int size, enum s3c2410_dma_buffresult res)
@@ -806,7 +819,6 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
	struct s3c64xx_spi_driver_data *sdd;
	struct s3c64xx_spi_info *sci;
	struct spi_message *msg;
	u32 psr, speed;
	unsigned long flags;
	int err = 0;

@@ -849,7 +861,11 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
	}

	/* Check if we can provide the requested rate */
	speed = clk_get_rate(sdd->src_clk) / 2 / (0 + 1); /* Max possible */
	if (!sci->clk_from_cmu) {
		u32 psr, speed;

		/* Max possible */
		speed = clk_get_rate(sdd->src_clk) / 2 / (0 + 1);

		if (spi->max_speed_hz > speed)
			spi->max_speed_hz = speed;
@@ -874,6 +890,7 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
			spi->max_speed_hz = speed;
		else
			err = -EINVAL;
	}

setup_exit:

@@ -896,6 +913,7 @@ static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel)
	/* Disable Interrupts - we use Polling if not DMA mode */
	writel(0, regs + S3C64XX_SPI_INT_EN);

	if (!sci->clk_from_cmu)
		writel(sci->src_clk_nr << S3C64XX_SPI_CLKSEL_SRCSHFT,
				regs + S3C64XX_SPI_CLK_CFG);
	writel(0, regs + S3C64XX_SPI_MODE_CFG);