blob: 6b0361497e0dc4a15aeebcc6798dd0f5f63512b9 [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
27/* GPIO/perihperal function select */
28#define PFC_GPSR2 0xE6060108
29#define PFC_GPSR6 0xE6060118
30
31static 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
43static 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
52static 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
62static 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
90static 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
105void rcar_cpld_reset_cpu(void)
106{
107 cpld_init();
108
109 cpld_write(CPLD_ADDR_RESET, 1);
110}