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