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