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

Commit 5bcc3b0b authored by Qipan Li's avatar Qipan Li Committed by Mark Brown
Browse files

spi: sirf: add the reset for USP-based SPI



USP-based SPI need a disable and enable, otherwise it doesn't work.
this patch adds it as HW initialization.

Signed-off-by: default avatarQipan Li <Qipan.Li@csr.com>
Signed-off-by: default avatarBarry Song <Baohua.Song@csr.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 3aa7b1d6
Loading
Loading
Loading
Loading
+42 −28
Original line number Diff line number Diff line
@@ -248,34 +248,6 @@ static const struct sirf_spi_register usp_spi_register = {
	.usp_int_en_clr		= 0x140,
};

struct sirf_spi_comp_data {
	const struct sirf_spi_register *regs;
	enum sirf_spi_type type;
	unsigned int dat_max_frm_len;
	unsigned int fifo_size;
};

static const struct sirf_spi_comp_data sirf_real_spi = {
	.regs = &real_spi_register,
	.type = SIRF_REAL_SPI,
	.dat_max_frm_len = 64 * 1024,
	.fifo_size = 256,
};

static const struct sirf_spi_comp_data sirf_usp_spi_p2 = {
	.regs = &usp_spi_register,
	.type = SIRF_USP_SPI_P2,
	.dat_max_frm_len = 1024 * 1024,
	.fifo_size = 128,
};

static const struct sirf_spi_comp_data sirf_usp_spi_a7 = {
	.regs = &usp_spi_register,
	.type = SIRF_USP_SPI_A7,
	.dat_max_frm_len = 1024 * 1024,
	.fifo_size = 512,
};

struct sirfsoc_spi {
	struct spi_bitbang bitbang;
	struct completion rx_done;
@@ -321,6 +293,23 @@ struct sirfsoc_spi {
	unsigned int dat_max_frm_len;
};

struct sirf_spi_comp_data {
	const struct sirf_spi_register *regs;
	enum sirf_spi_type type;
	unsigned int dat_max_frm_len;
	unsigned int fifo_size;
	void (*hwinit)(struct sirfsoc_spi *sspi);
};

static void sirfsoc_usp_hwinit(struct sirfsoc_spi *sspi)
{
	/* reset USP and let USP can operate */
	writel(readl(sspi->base + sspi->regs->usp_mode1) &
		~SIRFSOC_USP_EN, sspi->base + sspi->regs->usp_mode1);
	writel(readl(sspi->base + sspi->regs->usp_mode1) |
		SIRFSOC_USP_EN, sspi->base + sspi->regs->usp_mode1);
}

static void spi_sirfsoc_rx_word_u8(struct sirfsoc_spi *sspi)
{
	u32 data;
@@ -1047,6 +1036,29 @@ static void spi_sirfsoc_cleanup(struct spi_device *spi)
	}
}

static const struct sirf_spi_comp_data sirf_real_spi = {
	.regs = &real_spi_register,
	.type = SIRF_REAL_SPI,
	.dat_max_frm_len = 64 * 1024,
	.fifo_size = 256,
};

static const struct sirf_spi_comp_data sirf_usp_spi_p2 = {
	.regs = &usp_spi_register,
	.type = SIRF_USP_SPI_P2,
	.dat_max_frm_len = 1024 * 1024,
	.fifo_size = 128,
	.hwinit = sirfsoc_usp_hwinit,
};

static const struct sirf_spi_comp_data sirf_usp_spi_a7 = {
	.regs = &usp_spi_register,
	.type = SIRF_USP_SPI_A7,
	.dat_max_frm_len = 1024 * 1024,
	.fifo_size = 512,
	.hwinit = sirfsoc_usp_hwinit,
};

static const struct of_device_id spi_sirfsoc_of_match[] = {
	{ .compatible = "sirf,prima2-spi", .data = &sirf_real_spi},
	{ .compatible = "sirf,prima2-usp-spi", .data = &sirf_usp_spi_p2},
@@ -1136,6 +1148,8 @@ static int spi_sirfsoc_probe(struct platform_device *pdev)
		goto free_tx_dma;
	}
	clk_prepare_enable(sspi->clk);
	if (spi_comp_data->hwinit)
		spi_comp_data->hwinit(sspi);
	sspi->ctrl_freq = clk_get_rate(sspi->clk);

	init_completion(&sspi->rx_done);