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