blob: 5ffb2e1971cf8f801d5bbe1cb6be4df9a3260173 [file] [log] [blame]
Jorge Ramirez-Ortiz67650d22018-09-23 09:39:19 +02001/*
2 * Copyright (c) 2018, Renesas Electronics Corporation. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00007#include <lib/mmio.h>
Marek Vasut38ec9e52018-12-28 11:26:03 +01008#include "ulcb_cpld.h"
Jorge Ramirez-Ortiz67650d22018-09-23 09:39:19 +02009
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
Sergii Boryshchenkoaafafce2017-11-30 14:53:52 +020027/* General IO/Interrupt Switching Register */
28#define GPIO_IOINTSEL6 0xE6055400
29
Jorge Ramirez-Ortiz67650d22018-09-23 09:39:19 +020030/* GPIO/perihperal function select */
31#define PFC_GPSR2 0xE6060108
32#define PFC_GPSR6 0xE6060118
33
34static void gpio_set_value(uint32_t addr, uint8_t gpio, uint32_t val)
35{
36 uint32_t reg;
37
38 reg = mmio_read_32(addr);
39 if (val)
40 reg |= (1 << gpio);
41 else
42 reg &= ~(1 << gpio);
43 mmio_write_32(addr, reg);
44}
45
46static void gpio_direction_output(uint32_t addr, uint8_t gpio)
47{
48 uint32_t reg;
49
50 reg = mmio_read_32(addr);
51 reg |= (1 << gpio);
52 mmio_write_32(addr, reg);
53}
54
55static void gpio_pfc(uint32_t addr, uint8_t gpio)
56{
57 uint32_t reg;
58
59 reg = mmio_read_32(addr);
60 reg &= ~(1 << gpio);
61 mmio_write_32(PFC_PMMR, ~reg);
62 mmio_write_32(addr, reg);
63}
64
65static void cpld_write(uint8_t addr, uint32_t data)
66{
67 int i;
68
69 for (i = 0; i < 32; i++) {
70 /* MSB first */
Justin Chadwelle454beb2019-07-03 14:11:06 +010071 gpio_set_value(GPIO_OUTDT6, MOSI, data & (1U << 31));
Jorge Ramirez-Ortiz67650d22018-09-23 09:39:19 +020072 gpio_set_value(GPIO_OUTDT6, SCLK, 1);
73 data <<= 1;
74 gpio_set_value(GPIO_OUTDT6, SCLK, 0);
75 }
76
77 for (i = 0; i < 8; i++) {
78 /* MSB first */
79 gpio_set_value(GPIO_OUTDT6, MOSI, addr & 0x80);
80 gpio_set_value(GPIO_OUTDT6, SCLK, 1);
81 addr <<= 1;
82 gpio_set_value(GPIO_OUTDT6, SCLK, 0);
83 }
84
85 /* WRITE */
86 gpio_set_value(GPIO_OUTDT6, MOSI, 1);
87 gpio_set_value(GPIO_OUTDT2, SSTBZ, 0);
88 gpio_set_value(GPIO_OUTDT6, SCLK, 1);
89 gpio_set_value(GPIO_OUTDT6, SCLK, 0);
90 gpio_set_value(GPIO_OUTDT2, SSTBZ, 1);
91}
92
93static void cpld_init(void)
94{
95 gpio_pfc(PFC_GPSR6, SCLK);
96 gpio_pfc(PFC_GPSR2, SSTBZ);
97 gpio_pfc(PFC_GPSR6, MOSI);
98
Sergii Boryshchenkoaafafce2017-11-30 14:53:52 +020099 gpio_set_value(GPIO_IOINTSEL6, SCLK, 0);
Jorge Ramirez-Ortiz67650d22018-09-23 09:39:19 +0200100 gpio_set_value(GPIO_OUTDT6, SCLK, 0);
101 gpio_set_value(GPIO_OUTDT2, SSTBZ, 1);
102 gpio_set_value(GPIO_OUTDT6, MOSI, 0);
103
104 gpio_direction_output(GPIO_INOUTSEL6, SCLK);
105 gpio_direction_output(GPIO_INOUTSEL2, SSTBZ);
106 gpio_direction_output(GPIO_INOUTSEL6, MOSI);
107}
108
109void rcar_cpld_reset_cpu(void)
110{
111 cpld_init();
112
113 cpld_write(CPLD_ADDR_RESET, 1);
114}