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