xref: /rk3399_ARM-atf/drivers/renesas/rcar/cpld/ulcb_cpld.c (revision c948f77136c42a92d0bb660543a3600c36dcf7f1)
1 /*
2  * Copyright (c) 2018, Renesas Electronics Corporation. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <lib/mmio.h>
8 #include "ulcb_cpld.h"
9 
10 #define SCLK			8	/* GP_6_8 */
11 #define SSTBZ			3	/* GP_2_3 */
12 #define MOSI			7	/* GP_6_7 */
13 
14 #define CPLD_ADDR_RESET		0x80	/* RW */
15 
16 /* LSI Multiplexed Pin Setting Mask Register */
17 #define PFC_PMMR		0xE6060000
18 
19 /* General output registers */
20 #define GPIO_OUTDT2		0xE6052008
21 #define GPIO_OUTDT6		0xE6055408
22 
23 /* General input/output switching registers */
24 #define GPIO_INOUTSEL2		0xE6052004
25 #define GPIO_INOUTSEL6		0xE6055404
26 
27 /* GPIO/perihperal function select */
28 #define PFC_GPSR2		0xE6060108
29 #define PFC_GPSR6		0xE6060118
30 
31 static void gpio_set_value(uint32_t addr, uint8_t gpio, uint32_t val)
32 {
33 	uint32_t reg;
34 
35 	reg = mmio_read_32(addr);
36 	if (val)
37 		reg |= (1 << gpio);
38 	else
39 		reg &= ~(1 << gpio);
40 	mmio_write_32(addr, reg);
41 }
42 
43 static void gpio_direction_output(uint32_t addr, uint8_t gpio)
44 {
45 	uint32_t reg;
46 
47 	reg = mmio_read_32(addr);
48 	reg |= (1 << gpio);
49 	mmio_write_32(addr, reg);
50 }
51 
52 static void gpio_pfc(uint32_t addr, uint8_t gpio)
53 {
54 	uint32_t reg;
55 
56 	reg = mmio_read_32(addr);
57 	reg &= ~(1 << gpio);
58 	mmio_write_32(PFC_PMMR, ~reg);
59 	mmio_write_32(addr, reg);
60 }
61 
62 static void cpld_write(uint8_t addr, uint32_t data)
63 {
64 	int i;
65 
66 	for (i = 0; i < 32; i++) {
67 		/* MSB first */
68 		gpio_set_value(GPIO_OUTDT6, MOSI, data & (1 << 31));
69 		gpio_set_value(GPIO_OUTDT6, SCLK, 1);
70 		data <<= 1;
71 		gpio_set_value(GPIO_OUTDT6, SCLK, 0);
72 	}
73 
74 	for (i = 0; i < 8; i++) {
75 		/* MSB first */
76 		gpio_set_value(GPIO_OUTDT6, MOSI, addr & 0x80);
77 		gpio_set_value(GPIO_OUTDT6, SCLK, 1);
78 		addr <<= 1;
79 		gpio_set_value(GPIO_OUTDT6, SCLK, 0);
80 	}
81 
82 	/* WRITE */
83 	gpio_set_value(GPIO_OUTDT6, MOSI, 1);
84 	gpio_set_value(GPIO_OUTDT2, SSTBZ, 0);
85 	gpio_set_value(GPIO_OUTDT6, SCLK, 1);
86 	gpio_set_value(GPIO_OUTDT6, SCLK, 0);
87 	gpio_set_value(GPIO_OUTDT2, SSTBZ, 1);
88 }
89 
90 static void cpld_init(void)
91 {
92 	gpio_pfc(PFC_GPSR6, SCLK);
93 	gpio_pfc(PFC_GPSR2, SSTBZ);
94 	gpio_pfc(PFC_GPSR6, MOSI);
95 
96 	gpio_set_value(GPIO_OUTDT6, SCLK, 0);
97 	gpio_set_value(GPIO_OUTDT2, SSTBZ, 1);
98 	gpio_set_value(GPIO_OUTDT6, MOSI, 0);
99 
100 	gpio_direction_output(GPIO_INOUTSEL6, SCLK);
101 	gpio_direction_output(GPIO_INOUTSEL2, SSTBZ);
102 	gpio_direction_output(GPIO_INOUTSEL6, MOSI);
103 }
104 
105 void rcar_cpld_reset_cpu(void)
106 {
107 	cpld_init();
108 
109 	cpld_write(CPLD_ADDR_RESET, 1);
110 }
111