xref: /OK3568_Linux_fs/kernel/drivers/video/fbdev/mmp/hw/mmp_spi.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * linux/drivers/video/mmp/hw/mmp_spi.c
4*4882a593Smuzhiyun  * using the spi in LCD controler for commands send
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Copyright (C) 2012 Marvell Technology Group Ltd.
7*4882a593Smuzhiyun  * Authors:  Guoqing Li <ligq@marvell.com>
8*4882a593Smuzhiyun  *          Lisa Du <cldu@marvell.com>
9*4882a593Smuzhiyun  *          Zhou Zhu <zzhu3@marvell.com>
10*4882a593Smuzhiyun  */
11*4882a593Smuzhiyun #include <linux/errno.h>
12*4882a593Smuzhiyun #include <linux/delay.h>
13*4882a593Smuzhiyun #include <linux/err.h>
14*4882a593Smuzhiyun #include <linux/io.h>
15*4882a593Smuzhiyun #include <linux/spi/spi.h>
16*4882a593Smuzhiyun #include "mmp_ctrl.h"
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun /**
19*4882a593Smuzhiyun  * spi_write - write command to the SPI port
20*4882a593Smuzhiyun  * @data: can be 8/16/32-bit, MSB justified data to write.
21*4882a593Smuzhiyun  * @len:  data length.
22*4882a593Smuzhiyun  *
23*4882a593Smuzhiyun  * Wait bus transfer complete IRQ.
24*4882a593Smuzhiyun  * The caller is expected to perform the necessary locking.
25*4882a593Smuzhiyun  *
26*4882a593Smuzhiyun  * Returns:
27*4882a593Smuzhiyun  *   %-ETIMEDOUT	timeout occurred
28*4882a593Smuzhiyun  *   0			success
29*4882a593Smuzhiyun  */
lcd_spi_write(struct spi_device * spi,u32 data)30*4882a593Smuzhiyun static inline int lcd_spi_write(struct spi_device *spi, u32 data)
31*4882a593Smuzhiyun {
32*4882a593Smuzhiyun 	int timeout = 100000, isr, ret = 0;
33*4882a593Smuzhiyun 	u32 tmp;
34*4882a593Smuzhiyun 	void __iomem *reg_base = (void __iomem *)
35*4882a593Smuzhiyun 		*(void **)spi_master_get_devdata(spi->master);
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun 	/* clear ISR */
38*4882a593Smuzhiyun 	writel_relaxed(~SPI_IRQ_MASK, reg_base + SPU_IRQ_ISR);
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun 	switch (spi->bits_per_word) {
41*4882a593Smuzhiyun 	case 8:
42*4882a593Smuzhiyun 		writel_relaxed((u8)data, reg_base + LCD_SPU_SPI_TXDATA);
43*4882a593Smuzhiyun 		break;
44*4882a593Smuzhiyun 	case 16:
45*4882a593Smuzhiyun 		writel_relaxed((u16)data, reg_base + LCD_SPU_SPI_TXDATA);
46*4882a593Smuzhiyun 		break;
47*4882a593Smuzhiyun 	case 32:
48*4882a593Smuzhiyun 		writel_relaxed((u32)data, reg_base + LCD_SPU_SPI_TXDATA);
49*4882a593Smuzhiyun 		break;
50*4882a593Smuzhiyun 	default:
51*4882a593Smuzhiyun 		dev_err(&spi->dev, "Wrong spi bit length\n");
52*4882a593Smuzhiyun 	}
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun 	/* SPI start to send command */
55*4882a593Smuzhiyun 	tmp = readl_relaxed(reg_base + LCD_SPU_SPI_CTRL);
56*4882a593Smuzhiyun 	tmp &= ~CFG_SPI_START_MASK;
57*4882a593Smuzhiyun 	tmp |= CFG_SPI_START(1);
58*4882a593Smuzhiyun 	writel(tmp, reg_base + LCD_SPU_SPI_CTRL);
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun 	isr = readl_relaxed(reg_base + SPU_IRQ_ISR);
61*4882a593Smuzhiyun 	while (!(isr & SPI_IRQ_ENA_MASK)) {
62*4882a593Smuzhiyun 		udelay(100);
63*4882a593Smuzhiyun 		isr = readl_relaxed(reg_base + SPU_IRQ_ISR);
64*4882a593Smuzhiyun 		if (!--timeout) {
65*4882a593Smuzhiyun 			ret = -ETIMEDOUT;
66*4882a593Smuzhiyun 			dev_err(&spi->dev, "spi cmd send time out\n");
67*4882a593Smuzhiyun 			break;
68*4882a593Smuzhiyun 		}
69*4882a593Smuzhiyun 	}
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun 	tmp = readl_relaxed(reg_base + LCD_SPU_SPI_CTRL);
72*4882a593Smuzhiyun 	tmp &= ~CFG_SPI_START_MASK;
73*4882a593Smuzhiyun 	tmp |= CFG_SPI_START(0);
74*4882a593Smuzhiyun 	writel_relaxed(tmp, reg_base + LCD_SPU_SPI_CTRL);
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun 	writel_relaxed(~SPI_IRQ_MASK, reg_base + SPU_IRQ_ISR);
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun 	return ret;
79*4882a593Smuzhiyun }
80*4882a593Smuzhiyun 
lcd_spi_setup(struct spi_device * spi)81*4882a593Smuzhiyun static int lcd_spi_setup(struct spi_device *spi)
82*4882a593Smuzhiyun {
83*4882a593Smuzhiyun 	void __iomem *reg_base = (void __iomem *)
84*4882a593Smuzhiyun 		*(void **)spi_master_get_devdata(spi->master);
85*4882a593Smuzhiyun 	u32 tmp;
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun 	tmp = CFG_SCLKCNT(16) |
88*4882a593Smuzhiyun 		CFG_TXBITS(spi->bits_per_word) |
89*4882a593Smuzhiyun 		CFG_SPI_SEL(1) | CFG_SPI_ENA(1) |
90*4882a593Smuzhiyun 		CFG_SPI_3W4WB(1);
91*4882a593Smuzhiyun 	writel(tmp, reg_base + LCD_SPU_SPI_CTRL);
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	/*
94*4882a593Smuzhiyun 	 * After set mode it need a time to pull up the spi singals,
95*4882a593Smuzhiyun 	 * or it would cause the wrong waveform when send spi command,
96*4882a593Smuzhiyun 	 * especially on pxa910h
97*4882a593Smuzhiyun 	 */
98*4882a593Smuzhiyun 	tmp = readl_relaxed(reg_base + SPU_IOPAD_CONTROL);
99*4882a593Smuzhiyun 	if ((tmp & CFG_IOPADMODE_MASK) != IOPAD_DUMB18SPI)
100*4882a593Smuzhiyun 		writel_relaxed(IOPAD_DUMB18SPI |
101*4882a593Smuzhiyun 			(tmp & ~CFG_IOPADMODE_MASK),
102*4882a593Smuzhiyun 			reg_base + SPU_IOPAD_CONTROL);
103*4882a593Smuzhiyun 	udelay(20);
104*4882a593Smuzhiyun 	return 0;
105*4882a593Smuzhiyun }
106*4882a593Smuzhiyun 
lcd_spi_one_transfer(struct spi_device * spi,struct spi_message * m)107*4882a593Smuzhiyun static int lcd_spi_one_transfer(struct spi_device *spi, struct spi_message *m)
108*4882a593Smuzhiyun {
109*4882a593Smuzhiyun 	struct spi_transfer *t;
110*4882a593Smuzhiyun 	int i;
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun 	list_for_each_entry(t, &m->transfers, transfer_list) {
113*4882a593Smuzhiyun 		switch (spi->bits_per_word) {
114*4882a593Smuzhiyun 		case 8:
115*4882a593Smuzhiyun 			for (i = 0; i < t->len; i++)
116*4882a593Smuzhiyun 				lcd_spi_write(spi, ((u8 *)t->tx_buf)[i]);
117*4882a593Smuzhiyun 			break;
118*4882a593Smuzhiyun 		case 16:
119*4882a593Smuzhiyun 			for (i = 0; i < t->len/2; i++)
120*4882a593Smuzhiyun 				lcd_spi_write(spi, ((u16 *)t->tx_buf)[i]);
121*4882a593Smuzhiyun 			break;
122*4882a593Smuzhiyun 		case 32:
123*4882a593Smuzhiyun 			for (i = 0; i < t->len/4; i++)
124*4882a593Smuzhiyun 				lcd_spi_write(spi, ((u32 *)t->tx_buf)[i]);
125*4882a593Smuzhiyun 			break;
126*4882a593Smuzhiyun 		default:
127*4882a593Smuzhiyun 			dev_err(&spi->dev, "Wrong spi bit length\n");
128*4882a593Smuzhiyun 		}
129*4882a593Smuzhiyun 	}
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun 	m->status = 0;
132*4882a593Smuzhiyun 	if (m->complete)
133*4882a593Smuzhiyun 		m->complete(m->context);
134*4882a593Smuzhiyun 	return 0;
135*4882a593Smuzhiyun }
136*4882a593Smuzhiyun 
lcd_spi_register(struct mmphw_ctrl * ctrl)137*4882a593Smuzhiyun int lcd_spi_register(struct mmphw_ctrl *ctrl)
138*4882a593Smuzhiyun {
139*4882a593Smuzhiyun 	struct spi_master *master;
140*4882a593Smuzhiyun 	void **p_regbase;
141*4882a593Smuzhiyun 	int err;
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun 	master = spi_alloc_master(ctrl->dev, sizeof(void *));
144*4882a593Smuzhiyun 	if (!master) {
145*4882a593Smuzhiyun 		dev_err(ctrl->dev, "unable to allocate SPI master\n");
146*4882a593Smuzhiyun 		return -ENOMEM;
147*4882a593Smuzhiyun 	}
148*4882a593Smuzhiyun 	p_regbase = spi_master_get_devdata(master);
149*4882a593Smuzhiyun 	*p_regbase = (void __force *)ctrl->reg_base;
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun 	/* set bus num to 5 to avoid conflict with other spi hosts */
152*4882a593Smuzhiyun 	master->bus_num = 5;
153*4882a593Smuzhiyun 	master->num_chipselect = 1;
154*4882a593Smuzhiyun 	master->setup = lcd_spi_setup;
155*4882a593Smuzhiyun 	master->transfer = lcd_spi_one_transfer;
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun 	err = spi_register_master(master);
158*4882a593Smuzhiyun 	if (err < 0) {
159*4882a593Smuzhiyun 		dev_err(ctrl->dev, "unable to register SPI master\n");
160*4882a593Smuzhiyun 		spi_master_put(master);
161*4882a593Smuzhiyun 		return err;
162*4882a593Smuzhiyun 	}
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun 	dev_info(&master->dev, "registered\n");
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun 	return 0;
167*4882a593Smuzhiyun }
168