xref: /OK3568_Linux_fs/kernel/drivers/spi/spi-sprd-adi.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright (C) 2017 Spreadtrum Communications Inc.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * SPDX-License-Identifier: GPL-2.0
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #include <linux/delay.h>
8*4882a593Smuzhiyun #include <linux/hwspinlock.h>
9*4882a593Smuzhiyun #include <linux/init.h>
10*4882a593Smuzhiyun #include <linux/io.h>
11*4882a593Smuzhiyun #include <linux/kernel.h>
12*4882a593Smuzhiyun #include <linux/module.h>
13*4882a593Smuzhiyun #include <linux/of.h>
14*4882a593Smuzhiyun #include <linux/of_device.h>
15*4882a593Smuzhiyun #include <linux/platform_device.h>
16*4882a593Smuzhiyun #include <linux/reboot.h>
17*4882a593Smuzhiyun #include <linux/spi/spi.h>
18*4882a593Smuzhiyun #include <linux/sizes.h>
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun /* Registers definitions for ADI controller */
21*4882a593Smuzhiyun #define REG_ADI_CTRL0			0x4
22*4882a593Smuzhiyun #define REG_ADI_CHN_PRIL		0x8
23*4882a593Smuzhiyun #define REG_ADI_CHN_PRIH		0xc
24*4882a593Smuzhiyun #define REG_ADI_INT_EN			0x10
25*4882a593Smuzhiyun #define REG_ADI_INT_RAW			0x14
26*4882a593Smuzhiyun #define REG_ADI_INT_MASK		0x18
27*4882a593Smuzhiyun #define REG_ADI_INT_CLR			0x1c
28*4882a593Smuzhiyun #define REG_ADI_GSSI_CFG0		0x20
29*4882a593Smuzhiyun #define REG_ADI_GSSI_CFG1		0x24
30*4882a593Smuzhiyun #define REG_ADI_RD_CMD			0x28
31*4882a593Smuzhiyun #define REG_ADI_RD_DATA			0x2c
32*4882a593Smuzhiyun #define REG_ADI_ARM_FIFO_STS		0x30
33*4882a593Smuzhiyun #define REG_ADI_STS			0x34
34*4882a593Smuzhiyun #define REG_ADI_EVT_FIFO_STS		0x38
35*4882a593Smuzhiyun #define REG_ADI_ARM_CMD_STS		0x3c
36*4882a593Smuzhiyun #define REG_ADI_CHN_EN			0x40
37*4882a593Smuzhiyun #define REG_ADI_CHN_ADDR(id)		(0x44 + (id - 2) * 4)
38*4882a593Smuzhiyun #define REG_ADI_CHN_EN1			0x20c
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun /* Bits definitions for register REG_ADI_GSSI_CFG0 */
41*4882a593Smuzhiyun #define BIT_CLK_ALL_ON			BIT(30)
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun /* Bits definitions for register REG_ADI_RD_DATA */
44*4882a593Smuzhiyun #define BIT_RD_CMD_BUSY			BIT(31)
45*4882a593Smuzhiyun #define RD_ADDR_SHIFT			16
46*4882a593Smuzhiyun #define RD_VALUE_MASK			GENMASK(15, 0)
47*4882a593Smuzhiyun #define RD_ADDR_MASK			GENMASK(30, 16)
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun /* Bits definitions for register REG_ADI_ARM_FIFO_STS */
50*4882a593Smuzhiyun #define BIT_FIFO_FULL			BIT(11)
51*4882a593Smuzhiyun #define BIT_FIFO_EMPTY			BIT(10)
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun /*
54*4882a593Smuzhiyun  * ADI slave devices include RTC, ADC, regulator, charger, thermal and so on.
55*4882a593Smuzhiyun  * The slave devices address offset is always 0x8000 and size is 4K.
56*4882a593Smuzhiyun  */
57*4882a593Smuzhiyun #define ADI_SLAVE_ADDR_SIZE		SZ_4K
58*4882a593Smuzhiyun #define ADI_SLAVE_OFFSET		0x8000
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun /* Timeout (ms) for the trylock of hardware spinlocks */
61*4882a593Smuzhiyun #define ADI_HWSPINLOCK_TIMEOUT		5000
62*4882a593Smuzhiyun /*
63*4882a593Smuzhiyun  * ADI controller has 50 channels including 2 software channels
64*4882a593Smuzhiyun  * and 48 hardware channels.
65*4882a593Smuzhiyun  */
66*4882a593Smuzhiyun #define ADI_HW_CHNS			50
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun #define ADI_FIFO_DRAIN_TIMEOUT		1000
69*4882a593Smuzhiyun #define ADI_READ_TIMEOUT		2000
70*4882a593Smuzhiyun #define REG_ADDR_LOW_MASK		GENMASK(11, 0)
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun /* Registers definitions for PMIC watchdog controller */
73*4882a593Smuzhiyun #define REG_WDG_LOAD_LOW		0x80
74*4882a593Smuzhiyun #define REG_WDG_LOAD_HIGH		0x84
75*4882a593Smuzhiyun #define REG_WDG_CTRL			0x88
76*4882a593Smuzhiyun #define REG_WDG_LOCK			0xa0
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun /* Bits definitions for register REG_WDG_CTRL */
79*4882a593Smuzhiyun #define BIT_WDG_RUN			BIT(1)
80*4882a593Smuzhiyun #define BIT_WDG_NEW			BIT(2)
81*4882a593Smuzhiyun #define BIT_WDG_RST			BIT(3)
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun /* Registers definitions for PMIC */
84*4882a593Smuzhiyun #define PMIC_RST_STATUS			0xee8
85*4882a593Smuzhiyun #define PMIC_MODULE_EN			0xc08
86*4882a593Smuzhiyun #define PMIC_CLK_EN			0xc18
87*4882a593Smuzhiyun #define BIT_WDG_EN			BIT(2)
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun /* Definition of PMIC reset status register */
90*4882a593Smuzhiyun #define HWRST_STATUS_SECURITY		0x02
91*4882a593Smuzhiyun #define HWRST_STATUS_RECOVERY		0x20
92*4882a593Smuzhiyun #define HWRST_STATUS_NORMAL		0x40
93*4882a593Smuzhiyun #define HWRST_STATUS_ALARM		0x50
94*4882a593Smuzhiyun #define HWRST_STATUS_SLEEP		0x60
95*4882a593Smuzhiyun #define HWRST_STATUS_FASTBOOT		0x30
96*4882a593Smuzhiyun #define HWRST_STATUS_SPECIAL		0x70
97*4882a593Smuzhiyun #define HWRST_STATUS_PANIC		0x80
98*4882a593Smuzhiyun #define HWRST_STATUS_CFTREBOOT		0x90
99*4882a593Smuzhiyun #define HWRST_STATUS_AUTODLOADER	0xa0
100*4882a593Smuzhiyun #define HWRST_STATUS_IQMODE		0xb0
101*4882a593Smuzhiyun #define HWRST_STATUS_SPRDISK		0xc0
102*4882a593Smuzhiyun #define HWRST_STATUS_FACTORYTEST	0xe0
103*4882a593Smuzhiyun #define HWRST_STATUS_WATCHDOG		0xf0
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun /* Use default timeout 50 ms that converts to watchdog values */
106*4882a593Smuzhiyun #define WDG_LOAD_VAL			((50 * 32768) / 1000)
107*4882a593Smuzhiyun #define WDG_LOAD_MASK			GENMASK(15, 0)
108*4882a593Smuzhiyun #define WDG_UNLOCK_KEY			0xe551
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun struct sprd_adi {
111*4882a593Smuzhiyun 	struct spi_controller	*ctlr;
112*4882a593Smuzhiyun 	struct device		*dev;
113*4882a593Smuzhiyun 	void __iomem		*base;
114*4882a593Smuzhiyun 	struct hwspinlock	*hwlock;
115*4882a593Smuzhiyun 	unsigned long		slave_vbase;
116*4882a593Smuzhiyun 	unsigned long		slave_pbase;
117*4882a593Smuzhiyun 	struct notifier_block	restart_handler;
118*4882a593Smuzhiyun };
119*4882a593Smuzhiyun 
sprd_adi_check_paddr(struct sprd_adi * sadi,u32 paddr)120*4882a593Smuzhiyun static int sprd_adi_check_paddr(struct sprd_adi *sadi, u32 paddr)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun 	if (paddr < sadi->slave_pbase || paddr >
123*4882a593Smuzhiyun 	    (sadi->slave_pbase + ADI_SLAVE_ADDR_SIZE)) {
124*4882a593Smuzhiyun 		dev_err(sadi->dev,
125*4882a593Smuzhiyun 			"slave physical address is incorrect, addr = 0x%x\n",
126*4882a593Smuzhiyun 			paddr);
127*4882a593Smuzhiyun 		return -EINVAL;
128*4882a593Smuzhiyun 	}
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun 	return 0;
131*4882a593Smuzhiyun }
132*4882a593Smuzhiyun 
sprd_adi_to_vaddr(struct sprd_adi * sadi,u32 paddr)133*4882a593Smuzhiyun static unsigned long sprd_adi_to_vaddr(struct sprd_adi *sadi, u32 paddr)
134*4882a593Smuzhiyun {
135*4882a593Smuzhiyun 	return (paddr - sadi->slave_pbase + sadi->slave_vbase);
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun 
sprd_adi_drain_fifo(struct sprd_adi * sadi)138*4882a593Smuzhiyun static int sprd_adi_drain_fifo(struct sprd_adi *sadi)
139*4882a593Smuzhiyun {
140*4882a593Smuzhiyun 	u32 timeout = ADI_FIFO_DRAIN_TIMEOUT;
141*4882a593Smuzhiyun 	u32 sts;
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun 	do {
144*4882a593Smuzhiyun 		sts = readl_relaxed(sadi->base + REG_ADI_ARM_FIFO_STS);
145*4882a593Smuzhiyun 		if (sts & BIT_FIFO_EMPTY)
146*4882a593Smuzhiyun 			break;
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun 		cpu_relax();
149*4882a593Smuzhiyun 	} while (--timeout);
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun 	if (timeout == 0) {
152*4882a593Smuzhiyun 		dev_err(sadi->dev, "drain write fifo timeout\n");
153*4882a593Smuzhiyun 		return -EBUSY;
154*4882a593Smuzhiyun 	}
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun 	return 0;
157*4882a593Smuzhiyun }
158*4882a593Smuzhiyun 
sprd_adi_fifo_is_full(struct sprd_adi * sadi)159*4882a593Smuzhiyun static int sprd_adi_fifo_is_full(struct sprd_adi *sadi)
160*4882a593Smuzhiyun {
161*4882a593Smuzhiyun 	return readl_relaxed(sadi->base + REG_ADI_ARM_FIFO_STS) & BIT_FIFO_FULL;
162*4882a593Smuzhiyun }
163*4882a593Smuzhiyun 
sprd_adi_read(struct sprd_adi * sadi,u32 reg_paddr,u32 * read_val)164*4882a593Smuzhiyun static int sprd_adi_read(struct sprd_adi *sadi, u32 reg_paddr, u32 *read_val)
165*4882a593Smuzhiyun {
166*4882a593Smuzhiyun 	int read_timeout = ADI_READ_TIMEOUT;
167*4882a593Smuzhiyun 	unsigned long flags;
168*4882a593Smuzhiyun 	u32 val, rd_addr;
169*4882a593Smuzhiyun 	int ret = 0;
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun 	if (sadi->hwlock) {
172*4882a593Smuzhiyun 		ret = hwspin_lock_timeout_irqsave(sadi->hwlock,
173*4882a593Smuzhiyun 						  ADI_HWSPINLOCK_TIMEOUT,
174*4882a593Smuzhiyun 						  &flags);
175*4882a593Smuzhiyun 		if (ret) {
176*4882a593Smuzhiyun 			dev_err(sadi->dev, "get the hw lock failed\n");
177*4882a593Smuzhiyun 			return ret;
178*4882a593Smuzhiyun 		}
179*4882a593Smuzhiyun 	}
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun 	/*
182*4882a593Smuzhiyun 	 * Set the physical register address need to read into RD_CMD register,
183*4882a593Smuzhiyun 	 * then ADI controller will start to transfer automatically.
184*4882a593Smuzhiyun 	 */
185*4882a593Smuzhiyun 	writel_relaxed(reg_paddr, sadi->base + REG_ADI_RD_CMD);
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun 	/*
188*4882a593Smuzhiyun 	 * Wait read operation complete, the BIT_RD_CMD_BUSY will be set
189*4882a593Smuzhiyun 	 * simultaneously when writing read command to register, and the
190*4882a593Smuzhiyun 	 * BIT_RD_CMD_BUSY will be cleared after the read operation is
191*4882a593Smuzhiyun 	 * completed.
192*4882a593Smuzhiyun 	 */
193*4882a593Smuzhiyun 	do {
194*4882a593Smuzhiyun 		val = readl_relaxed(sadi->base + REG_ADI_RD_DATA);
195*4882a593Smuzhiyun 		if (!(val & BIT_RD_CMD_BUSY))
196*4882a593Smuzhiyun 			break;
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun 		cpu_relax();
199*4882a593Smuzhiyun 	} while (--read_timeout);
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun 	if (read_timeout == 0) {
202*4882a593Smuzhiyun 		dev_err(sadi->dev, "ADI read timeout\n");
203*4882a593Smuzhiyun 		ret = -EBUSY;
204*4882a593Smuzhiyun 		goto out;
205*4882a593Smuzhiyun 	}
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun 	/*
208*4882a593Smuzhiyun 	 * The return value includes data and read register address, from bit 0
209*4882a593Smuzhiyun 	 * to bit 15 are data, and from bit 16 to bit 30 are read register
210*4882a593Smuzhiyun 	 * address. Then we can check the returned register address to validate
211*4882a593Smuzhiyun 	 * data.
212*4882a593Smuzhiyun 	 */
213*4882a593Smuzhiyun 	rd_addr = (val & RD_ADDR_MASK ) >> RD_ADDR_SHIFT;
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun 	if (rd_addr != (reg_paddr & REG_ADDR_LOW_MASK)) {
216*4882a593Smuzhiyun 		dev_err(sadi->dev, "read error, reg addr = 0x%x, val = 0x%x\n",
217*4882a593Smuzhiyun 			reg_paddr, val);
218*4882a593Smuzhiyun 		ret = -EIO;
219*4882a593Smuzhiyun 		goto out;
220*4882a593Smuzhiyun 	}
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 	*read_val = val & RD_VALUE_MASK;
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun out:
225*4882a593Smuzhiyun 	if (sadi->hwlock)
226*4882a593Smuzhiyun 		hwspin_unlock_irqrestore(sadi->hwlock, &flags);
227*4882a593Smuzhiyun 	return ret;
228*4882a593Smuzhiyun }
229*4882a593Smuzhiyun 
sprd_adi_write(struct sprd_adi * sadi,u32 reg_paddr,u32 val)230*4882a593Smuzhiyun static int sprd_adi_write(struct sprd_adi *sadi, u32 reg_paddr, u32 val)
231*4882a593Smuzhiyun {
232*4882a593Smuzhiyun 	unsigned long reg = sprd_adi_to_vaddr(sadi, reg_paddr);
233*4882a593Smuzhiyun 	u32 timeout = ADI_FIFO_DRAIN_TIMEOUT;
234*4882a593Smuzhiyun 	unsigned long flags;
235*4882a593Smuzhiyun 	int ret;
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun 	if (sadi->hwlock) {
238*4882a593Smuzhiyun 		ret = hwspin_lock_timeout_irqsave(sadi->hwlock,
239*4882a593Smuzhiyun 						  ADI_HWSPINLOCK_TIMEOUT,
240*4882a593Smuzhiyun 						  &flags);
241*4882a593Smuzhiyun 		if (ret) {
242*4882a593Smuzhiyun 			dev_err(sadi->dev, "get the hw lock failed\n");
243*4882a593Smuzhiyun 			return ret;
244*4882a593Smuzhiyun 		}
245*4882a593Smuzhiyun 	}
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	ret = sprd_adi_drain_fifo(sadi);
248*4882a593Smuzhiyun 	if (ret < 0)
249*4882a593Smuzhiyun 		goto out;
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun 	/*
252*4882a593Smuzhiyun 	 * we should wait for write fifo is empty before writing data to PMIC
253*4882a593Smuzhiyun 	 * registers.
254*4882a593Smuzhiyun 	 */
255*4882a593Smuzhiyun 	do {
256*4882a593Smuzhiyun 		if (!sprd_adi_fifo_is_full(sadi)) {
257*4882a593Smuzhiyun 			writel_relaxed(val, (void __iomem *)reg);
258*4882a593Smuzhiyun 			break;
259*4882a593Smuzhiyun 		}
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun 		cpu_relax();
262*4882a593Smuzhiyun 	} while (--timeout);
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun 	if (timeout == 0) {
265*4882a593Smuzhiyun 		dev_err(sadi->dev, "write fifo is full\n");
266*4882a593Smuzhiyun 		ret = -EBUSY;
267*4882a593Smuzhiyun 	}
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun out:
270*4882a593Smuzhiyun 	if (sadi->hwlock)
271*4882a593Smuzhiyun 		hwspin_unlock_irqrestore(sadi->hwlock, &flags);
272*4882a593Smuzhiyun 	return ret;
273*4882a593Smuzhiyun }
274*4882a593Smuzhiyun 
sprd_adi_transfer_one(struct spi_controller * ctlr,struct spi_device * spi_dev,struct spi_transfer * t)275*4882a593Smuzhiyun static int sprd_adi_transfer_one(struct spi_controller *ctlr,
276*4882a593Smuzhiyun 				 struct spi_device *spi_dev,
277*4882a593Smuzhiyun 				 struct spi_transfer *t)
278*4882a593Smuzhiyun {
279*4882a593Smuzhiyun 	struct sprd_adi *sadi = spi_controller_get_devdata(ctlr);
280*4882a593Smuzhiyun 	u32 phy_reg, val;
281*4882a593Smuzhiyun 	int ret;
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun 	if (t->rx_buf) {
284*4882a593Smuzhiyun 		phy_reg = *(u32 *)t->rx_buf + sadi->slave_pbase;
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun 		ret = sprd_adi_check_paddr(sadi, phy_reg);
287*4882a593Smuzhiyun 		if (ret)
288*4882a593Smuzhiyun 			return ret;
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun 		ret = sprd_adi_read(sadi, phy_reg, &val);
291*4882a593Smuzhiyun 		if (ret)
292*4882a593Smuzhiyun 			return ret;
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun 		*(u32 *)t->rx_buf = val;
295*4882a593Smuzhiyun 	} else if (t->tx_buf) {
296*4882a593Smuzhiyun 		u32 *p = (u32 *)t->tx_buf;
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun 		/*
299*4882a593Smuzhiyun 		 * Get the physical register address need to write and convert
300*4882a593Smuzhiyun 		 * the physical address to virtual address. Since we need
301*4882a593Smuzhiyun 		 * virtual register address to write.
302*4882a593Smuzhiyun 		 */
303*4882a593Smuzhiyun 		phy_reg = *p++ + sadi->slave_pbase;
304*4882a593Smuzhiyun 		ret = sprd_adi_check_paddr(sadi, phy_reg);
305*4882a593Smuzhiyun 		if (ret)
306*4882a593Smuzhiyun 			return ret;
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun 		val = *p;
309*4882a593Smuzhiyun 		ret = sprd_adi_write(sadi, phy_reg, val);
310*4882a593Smuzhiyun 		if (ret)
311*4882a593Smuzhiyun 			return ret;
312*4882a593Smuzhiyun 	} else {
313*4882a593Smuzhiyun 		dev_err(sadi->dev, "no buffer for transfer\n");
314*4882a593Smuzhiyun 		return -EINVAL;
315*4882a593Smuzhiyun 	}
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun 	return 0;
318*4882a593Smuzhiyun }
319*4882a593Smuzhiyun 
sprd_adi_set_wdt_rst_mode(struct sprd_adi * sadi)320*4882a593Smuzhiyun static void sprd_adi_set_wdt_rst_mode(struct sprd_adi *sadi)
321*4882a593Smuzhiyun {
322*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_SPRD_WATCHDOG)
323*4882a593Smuzhiyun 	u32 val;
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun 	/* Set default watchdog reboot mode */
326*4882a593Smuzhiyun 	sprd_adi_read(sadi, sadi->slave_pbase + PMIC_RST_STATUS, &val);
327*4882a593Smuzhiyun 	val |= HWRST_STATUS_WATCHDOG;
328*4882a593Smuzhiyun 	sprd_adi_write(sadi, sadi->slave_pbase + PMIC_RST_STATUS, val);
329*4882a593Smuzhiyun #endif
330*4882a593Smuzhiyun }
331*4882a593Smuzhiyun 
sprd_adi_restart_handler(struct notifier_block * this,unsigned long mode,void * cmd)332*4882a593Smuzhiyun static int sprd_adi_restart_handler(struct notifier_block *this,
333*4882a593Smuzhiyun 				    unsigned long mode, void *cmd)
334*4882a593Smuzhiyun {
335*4882a593Smuzhiyun 	struct sprd_adi *sadi = container_of(this, struct sprd_adi,
336*4882a593Smuzhiyun 					     restart_handler);
337*4882a593Smuzhiyun 	u32 val, reboot_mode = 0;
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun 	if (!cmd)
340*4882a593Smuzhiyun 		reboot_mode = HWRST_STATUS_NORMAL;
341*4882a593Smuzhiyun 	else if (!strncmp(cmd, "recovery", 8))
342*4882a593Smuzhiyun 		reboot_mode = HWRST_STATUS_RECOVERY;
343*4882a593Smuzhiyun 	else if (!strncmp(cmd, "alarm", 5))
344*4882a593Smuzhiyun 		reboot_mode = HWRST_STATUS_ALARM;
345*4882a593Smuzhiyun 	else if (!strncmp(cmd, "fastsleep", 9))
346*4882a593Smuzhiyun 		reboot_mode = HWRST_STATUS_SLEEP;
347*4882a593Smuzhiyun 	else if (!strncmp(cmd, "bootloader", 10))
348*4882a593Smuzhiyun 		reboot_mode = HWRST_STATUS_FASTBOOT;
349*4882a593Smuzhiyun 	else if (!strncmp(cmd, "panic", 5))
350*4882a593Smuzhiyun 		reboot_mode = HWRST_STATUS_PANIC;
351*4882a593Smuzhiyun 	else if (!strncmp(cmd, "special", 7))
352*4882a593Smuzhiyun 		reboot_mode = HWRST_STATUS_SPECIAL;
353*4882a593Smuzhiyun 	else if (!strncmp(cmd, "cftreboot", 9))
354*4882a593Smuzhiyun 		reboot_mode = HWRST_STATUS_CFTREBOOT;
355*4882a593Smuzhiyun 	else if (!strncmp(cmd, "autodloader", 11))
356*4882a593Smuzhiyun 		reboot_mode = HWRST_STATUS_AUTODLOADER;
357*4882a593Smuzhiyun 	else if (!strncmp(cmd, "iqmode", 6))
358*4882a593Smuzhiyun 		reboot_mode = HWRST_STATUS_IQMODE;
359*4882a593Smuzhiyun 	else if (!strncmp(cmd, "sprdisk", 7))
360*4882a593Smuzhiyun 		reboot_mode = HWRST_STATUS_SPRDISK;
361*4882a593Smuzhiyun 	else if (!strncmp(cmd, "tospanic", 8))
362*4882a593Smuzhiyun 		reboot_mode = HWRST_STATUS_SECURITY;
363*4882a593Smuzhiyun 	else if (!strncmp(cmd, "factorytest", 11))
364*4882a593Smuzhiyun 		reboot_mode = HWRST_STATUS_FACTORYTEST;
365*4882a593Smuzhiyun 	else
366*4882a593Smuzhiyun 		reboot_mode = HWRST_STATUS_NORMAL;
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun 	/* Record the reboot mode */
369*4882a593Smuzhiyun 	sprd_adi_read(sadi, sadi->slave_pbase + PMIC_RST_STATUS, &val);
370*4882a593Smuzhiyun 	val &= ~HWRST_STATUS_WATCHDOG;
371*4882a593Smuzhiyun 	val |= reboot_mode;
372*4882a593Smuzhiyun 	sprd_adi_write(sadi, sadi->slave_pbase + PMIC_RST_STATUS, val);
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun 	/* Enable the interface clock of the watchdog */
375*4882a593Smuzhiyun 	sprd_adi_read(sadi, sadi->slave_pbase + PMIC_MODULE_EN, &val);
376*4882a593Smuzhiyun 	val |= BIT_WDG_EN;
377*4882a593Smuzhiyun 	sprd_adi_write(sadi, sadi->slave_pbase + PMIC_MODULE_EN, val);
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun 	/* Enable the work clock of the watchdog */
380*4882a593Smuzhiyun 	sprd_adi_read(sadi, sadi->slave_pbase + PMIC_CLK_EN, &val);
381*4882a593Smuzhiyun 	val |= BIT_WDG_EN;
382*4882a593Smuzhiyun 	sprd_adi_write(sadi, sadi->slave_pbase + PMIC_CLK_EN, val);
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun 	/* Unlock the watchdog */
385*4882a593Smuzhiyun 	sprd_adi_write(sadi, sadi->slave_pbase + REG_WDG_LOCK, WDG_UNLOCK_KEY);
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun 	sprd_adi_read(sadi, sadi->slave_pbase + REG_WDG_CTRL, &val);
388*4882a593Smuzhiyun 	val |= BIT_WDG_NEW;
389*4882a593Smuzhiyun 	sprd_adi_write(sadi, sadi->slave_pbase + REG_WDG_CTRL, val);
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun 	/* Load the watchdog timeout value, 50ms is always enough. */
392*4882a593Smuzhiyun 	sprd_adi_write(sadi, sadi->slave_pbase + REG_WDG_LOAD_HIGH, 0);
393*4882a593Smuzhiyun 	sprd_adi_write(sadi, sadi->slave_pbase + REG_WDG_LOAD_LOW,
394*4882a593Smuzhiyun 		       WDG_LOAD_VAL & WDG_LOAD_MASK);
395*4882a593Smuzhiyun 
396*4882a593Smuzhiyun 	/* Start the watchdog to reset system */
397*4882a593Smuzhiyun 	sprd_adi_read(sadi, sadi->slave_pbase + REG_WDG_CTRL, &val);
398*4882a593Smuzhiyun 	val |= BIT_WDG_RUN | BIT_WDG_RST;
399*4882a593Smuzhiyun 	sprd_adi_write(sadi, sadi->slave_pbase + REG_WDG_CTRL, val);
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun 	/* Lock the watchdog */
402*4882a593Smuzhiyun 	sprd_adi_write(sadi, sadi->slave_pbase + REG_WDG_LOCK, ~WDG_UNLOCK_KEY);
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun 	mdelay(1000);
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun 	dev_emerg(sadi->dev, "Unable to restart system\n");
407*4882a593Smuzhiyun 	return NOTIFY_DONE;
408*4882a593Smuzhiyun }
409*4882a593Smuzhiyun 
sprd_adi_hw_init(struct sprd_adi * sadi)410*4882a593Smuzhiyun static void sprd_adi_hw_init(struct sprd_adi *sadi)
411*4882a593Smuzhiyun {
412*4882a593Smuzhiyun 	struct device_node *np = sadi->dev->of_node;
413*4882a593Smuzhiyun 	int i, size, chn_cnt;
414*4882a593Smuzhiyun 	const __be32 *list;
415*4882a593Smuzhiyun 	u32 tmp;
416*4882a593Smuzhiyun 
417*4882a593Smuzhiyun 	/* Set all channels as default priority */
418*4882a593Smuzhiyun 	writel_relaxed(0, sadi->base + REG_ADI_CHN_PRIL);
419*4882a593Smuzhiyun 	writel_relaxed(0, sadi->base + REG_ADI_CHN_PRIH);
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun 	/* Set clock auto gate mode */
422*4882a593Smuzhiyun 	tmp = readl_relaxed(sadi->base + REG_ADI_GSSI_CFG0);
423*4882a593Smuzhiyun 	tmp &= ~BIT_CLK_ALL_ON;
424*4882a593Smuzhiyun 	writel_relaxed(tmp, sadi->base + REG_ADI_GSSI_CFG0);
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun 	/* Set hardware channels setting */
427*4882a593Smuzhiyun 	list = of_get_property(np, "sprd,hw-channels", &size);
428*4882a593Smuzhiyun 	if (!list || !size) {
429*4882a593Smuzhiyun 		dev_info(sadi->dev, "no hw channels setting in node\n");
430*4882a593Smuzhiyun 		return;
431*4882a593Smuzhiyun 	}
432*4882a593Smuzhiyun 
433*4882a593Smuzhiyun 	chn_cnt = size / 8;
434*4882a593Smuzhiyun 	for (i = 0; i < chn_cnt; i++) {
435*4882a593Smuzhiyun 		u32 value;
436*4882a593Smuzhiyun 		u32 chn_id = be32_to_cpu(*list++);
437*4882a593Smuzhiyun 		u32 chn_config = be32_to_cpu(*list++);
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun 		/* Channel 0 and 1 are software channels */
440*4882a593Smuzhiyun 		if (chn_id < 2)
441*4882a593Smuzhiyun 			continue;
442*4882a593Smuzhiyun 
443*4882a593Smuzhiyun 		writel_relaxed(chn_config, sadi->base +
444*4882a593Smuzhiyun 			       REG_ADI_CHN_ADDR(chn_id));
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun 		if (chn_id < 32) {
447*4882a593Smuzhiyun 			value = readl_relaxed(sadi->base + REG_ADI_CHN_EN);
448*4882a593Smuzhiyun 			value |= BIT(chn_id);
449*4882a593Smuzhiyun 			writel_relaxed(value, sadi->base + REG_ADI_CHN_EN);
450*4882a593Smuzhiyun 		} else if (chn_id < ADI_HW_CHNS) {
451*4882a593Smuzhiyun 			value = readl_relaxed(sadi->base + REG_ADI_CHN_EN1);
452*4882a593Smuzhiyun 			value |= BIT(chn_id - 32);
453*4882a593Smuzhiyun 			writel_relaxed(value, sadi->base + REG_ADI_CHN_EN1);
454*4882a593Smuzhiyun 		}
455*4882a593Smuzhiyun 	}
456*4882a593Smuzhiyun }
457*4882a593Smuzhiyun 
sprd_adi_probe(struct platform_device * pdev)458*4882a593Smuzhiyun static int sprd_adi_probe(struct platform_device *pdev)
459*4882a593Smuzhiyun {
460*4882a593Smuzhiyun 	struct device_node *np = pdev->dev.of_node;
461*4882a593Smuzhiyun 	struct spi_controller *ctlr;
462*4882a593Smuzhiyun 	struct sprd_adi *sadi;
463*4882a593Smuzhiyun 	struct resource *res;
464*4882a593Smuzhiyun 	u32 num_chipselect;
465*4882a593Smuzhiyun 	int ret;
466*4882a593Smuzhiyun 
467*4882a593Smuzhiyun 	if (!np) {
468*4882a593Smuzhiyun 		dev_err(&pdev->dev, "can not find the adi bus node\n");
469*4882a593Smuzhiyun 		return -ENODEV;
470*4882a593Smuzhiyun 	}
471*4882a593Smuzhiyun 
472*4882a593Smuzhiyun 	pdev->id = of_alias_get_id(np, "spi");
473*4882a593Smuzhiyun 	num_chipselect = of_get_child_count(np);
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun 	ctlr = spi_alloc_master(&pdev->dev, sizeof(struct sprd_adi));
476*4882a593Smuzhiyun 	if (!ctlr)
477*4882a593Smuzhiyun 		return -ENOMEM;
478*4882a593Smuzhiyun 
479*4882a593Smuzhiyun 	dev_set_drvdata(&pdev->dev, ctlr);
480*4882a593Smuzhiyun 	sadi = spi_controller_get_devdata(ctlr);
481*4882a593Smuzhiyun 
482*4882a593Smuzhiyun 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
483*4882a593Smuzhiyun 	sadi->base = devm_ioremap_resource(&pdev->dev, res);
484*4882a593Smuzhiyun 	if (IS_ERR(sadi->base)) {
485*4882a593Smuzhiyun 		ret = PTR_ERR(sadi->base);
486*4882a593Smuzhiyun 		goto put_ctlr;
487*4882a593Smuzhiyun 	}
488*4882a593Smuzhiyun 
489*4882a593Smuzhiyun 	sadi->slave_vbase = (unsigned long)sadi->base + ADI_SLAVE_OFFSET;
490*4882a593Smuzhiyun 	sadi->slave_pbase = res->start + ADI_SLAVE_OFFSET;
491*4882a593Smuzhiyun 	sadi->ctlr = ctlr;
492*4882a593Smuzhiyun 	sadi->dev = &pdev->dev;
493*4882a593Smuzhiyun 	ret = of_hwspin_lock_get_id(np, 0);
494*4882a593Smuzhiyun 	if (ret > 0 || (IS_ENABLED(CONFIG_HWSPINLOCK) && ret == 0)) {
495*4882a593Smuzhiyun 		sadi->hwlock =
496*4882a593Smuzhiyun 			devm_hwspin_lock_request_specific(&pdev->dev, ret);
497*4882a593Smuzhiyun 		if (!sadi->hwlock) {
498*4882a593Smuzhiyun 			ret = -ENXIO;
499*4882a593Smuzhiyun 			goto put_ctlr;
500*4882a593Smuzhiyun 		}
501*4882a593Smuzhiyun 	} else {
502*4882a593Smuzhiyun 		switch (ret) {
503*4882a593Smuzhiyun 		case -ENOENT:
504*4882a593Smuzhiyun 			dev_info(&pdev->dev, "no hardware spinlock supplied\n");
505*4882a593Smuzhiyun 			break;
506*4882a593Smuzhiyun 		default:
507*4882a593Smuzhiyun 			dev_err_probe(&pdev->dev, ret, "failed to find hwlock id\n");
508*4882a593Smuzhiyun 			goto put_ctlr;
509*4882a593Smuzhiyun 		}
510*4882a593Smuzhiyun 	}
511*4882a593Smuzhiyun 
512*4882a593Smuzhiyun 	sprd_adi_hw_init(sadi);
513*4882a593Smuzhiyun 	sprd_adi_set_wdt_rst_mode(sadi);
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun 	ctlr->dev.of_node = pdev->dev.of_node;
516*4882a593Smuzhiyun 	ctlr->bus_num = pdev->id;
517*4882a593Smuzhiyun 	ctlr->num_chipselect = num_chipselect;
518*4882a593Smuzhiyun 	ctlr->flags = SPI_MASTER_HALF_DUPLEX;
519*4882a593Smuzhiyun 	ctlr->bits_per_word_mask = 0;
520*4882a593Smuzhiyun 	ctlr->transfer_one = sprd_adi_transfer_one;
521*4882a593Smuzhiyun 
522*4882a593Smuzhiyun 	ret = devm_spi_register_controller(&pdev->dev, ctlr);
523*4882a593Smuzhiyun 	if (ret) {
524*4882a593Smuzhiyun 		dev_err(&pdev->dev, "failed to register SPI controller\n");
525*4882a593Smuzhiyun 		goto put_ctlr;
526*4882a593Smuzhiyun 	}
527*4882a593Smuzhiyun 
528*4882a593Smuzhiyun 	sadi->restart_handler.notifier_call = sprd_adi_restart_handler;
529*4882a593Smuzhiyun 	sadi->restart_handler.priority = 128;
530*4882a593Smuzhiyun 	ret = register_restart_handler(&sadi->restart_handler);
531*4882a593Smuzhiyun 	if (ret) {
532*4882a593Smuzhiyun 		dev_err(&pdev->dev, "can not register restart handler\n");
533*4882a593Smuzhiyun 		goto put_ctlr;
534*4882a593Smuzhiyun 	}
535*4882a593Smuzhiyun 
536*4882a593Smuzhiyun 	return 0;
537*4882a593Smuzhiyun 
538*4882a593Smuzhiyun put_ctlr:
539*4882a593Smuzhiyun 	spi_controller_put(ctlr);
540*4882a593Smuzhiyun 	return ret;
541*4882a593Smuzhiyun }
542*4882a593Smuzhiyun 
sprd_adi_remove(struct platform_device * pdev)543*4882a593Smuzhiyun static int sprd_adi_remove(struct platform_device *pdev)
544*4882a593Smuzhiyun {
545*4882a593Smuzhiyun 	struct spi_controller *ctlr = dev_get_drvdata(&pdev->dev);
546*4882a593Smuzhiyun 	struct sprd_adi *sadi = spi_controller_get_devdata(ctlr);
547*4882a593Smuzhiyun 
548*4882a593Smuzhiyun 	unregister_restart_handler(&sadi->restart_handler);
549*4882a593Smuzhiyun 	return 0;
550*4882a593Smuzhiyun }
551*4882a593Smuzhiyun 
552*4882a593Smuzhiyun static const struct of_device_id sprd_adi_of_match[] = {
553*4882a593Smuzhiyun 	{
554*4882a593Smuzhiyun 		.compatible = "sprd,sc9860-adi",
555*4882a593Smuzhiyun 	},
556*4882a593Smuzhiyun 	{ },
557*4882a593Smuzhiyun };
558*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, sprd_adi_of_match);
559*4882a593Smuzhiyun 
560*4882a593Smuzhiyun static struct platform_driver sprd_adi_driver = {
561*4882a593Smuzhiyun 	.driver = {
562*4882a593Smuzhiyun 		.name = "sprd-adi",
563*4882a593Smuzhiyun 		.of_match_table = sprd_adi_of_match,
564*4882a593Smuzhiyun 	},
565*4882a593Smuzhiyun 	.probe = sprd_adi_probe,
566*4882a593Smuzhiyun 	.remove = sprd_adi_remove,
567*4882a593Smuzhiyun };
568*4882a593Smuzhiyun module_platform_driver(sprd_adi_driver);
569*4882a593Smuzhiyun 
570*4882a593Smuzhiyun MODULE_DESCRIPTION("Spreadtrum ADI Controller Driver");
571*4882a593Smuzhiyun MODULE_AUTHOR("Baolin Wang <Baolin.Wang@spreadtrum.com>");
572*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
573