xref: /openbmc/u-boot/board/renesas/stout/cpld.c (revision 83d290c56fab2d38cd1ab4c4cc7099559c1d5046)
1  // SPDX-License-Identifier: GPL-2.0
2  /*
3   * Stout board CPLD access support
4   *
5   * Copyright (C) 2015 Renesas Electronics Europe GmbH
6   * Copyright (C) 2015 Renesas Electronics Corporation
7   * Copyright (C) 2015 Cogent Embedded, Inc.
8   */
9  
10  #include <common.h>
11  #include <asm/io.h>
12  #include <asm/gpio.h>
13  #include "cpld.h"
14  
15  #define SCLK			(92 + 24)
16  #define SSTBZ			(92 + 25)
17  #define MOSI			(92 + 26)
18  #define MISO			(92 + 27)
19  
20  #define CPLD_ADDR_MODE		0x00 /* RW */
21  #define CPLD_ADDR_MUX		0x01 /* RW */
22  #define CPLD_ADDR_HDMI		0x02 /* RW */
23  #define CPLD_ADDR_DIPSW		0x08 /* R */
24  #define CPLD_ADDR_RESET		0x80 /* RW */
25  #define CPLD_ADDR_VERSION	0xFF /* R */
26  
cpld_read(u8 addr)27  static u32 cpld_read(u8 addr)
28  {
29  	int i;
30  	u32 data = 0;
31  
32  	for (i = 0; i < 8; i++) {
33  		gpio_set_value(MOSI, addr & 0x80); /* MSB first */
34  		gpio_set_value(SCLK, 1);
35  		addr <<= 1;
36  		gpio_set_value(SCLK, 0);
37  	}
38  
39  	gpio_set_value(MOSI, 0); /* READ */
40  	gpio_set_value(SSTBZ, 0);
41  	gpio_set_value(SCLK, 1);
42  	gpio_set_value(SCLK, 0);
43  	gpio_set_value(SSTBZ, 1);
44  
45  	for (i = 0; i < 32; i++) {
46  		gpio_set_value(SCLK, 1);
47  		data <<= 1;
48  		data |= gpio_get_value(MISO); /* MSB first */
49  		gpio_set_value(SCLK, 0);
50  	}
51  
52  	return data;
53  }
54  
cpld_write(u8 addr,u32 data)55  static void cpld_write(u8 addr, u32 data)
56  {
57  	int i;
58  
59  	for (i = 0; i < 32; i++) {
60  		gpio_set_value(MOSI, data & (1 << 31)); /* MSB first */
61  		gpio_set_value(SCLK, 1);
62  		data <<= 1;
63  		gpio_set_value(SCLK, 0);
64  	}
65  
66  	for (i = 0; i < 8; i++) {
67  		gpio_set_value(MOSI, addr & 0x80); /* MSB first */
68  		gpio_set_value(SCLK, 1);
69  		addr <<= 1;
70  		gpio_set_value(SCLK, 0);
71  	}
72  
73  	gpio_set_value(MOSI, 1); /* WRITE */
74  	gpio_set_value(SSTBZ, 0);
75  	gpio_set_value(SCLK, 1);
76  	gpio_set_value(SCLK, 0);
77  	gpio_set_value(SSTBZ, 1);
78  }
79  
80  /* LSI pin pull-up control */
81  #define PUPR3		0xe606010C
82  #define PUPR3_SD3_DAT1	(1 << 27)
83  
cpld_init(void)84  void cpld_init(void)
85  {
86  	u32 val;
87  
88  	/* PULL-UP on MISO line */
89  	val = readl(PUPR3);
90  	val |= PUPR3_SD3_DAT1;
91  	writel(val, PUPR3);
92  
93  	gpio_request(SCLK, "SCLK");
94  	gpio_request(SSTBZ, "SSTBZ");
95  	gpio_request(MOSI, "MOSI");
96  	gpio_request(MISO, "MISO");
97  
98  	gpio_direction_output(SCLK, 0);
99  	gpio_direction_output(SSTBZ, 1);
100  	gpio_direction_output(MOSI, 0);
101  	gpio_direction_input(MISO);
102  
103  	/* dummy read */
104  	cpld_read(CPLD_ADDR_VERSION);
105  
106  	printf("CPLD version:              0x%08x\n",
107  	       cpld_read(CPLD_ADDR_VERSION));
108  	printf("H2 Mode setting (MD0..28): 0x%08x\n",
109  	       cpld_read(CPLD_ADDR_MODE));
110  	printf("Multiplexer settings:      0x%08x\n",
111  	       cpld_read(CPLD_ADDR_MUX));
112  	printf("HDMI setting:              0x%08x\n",
113  	       cpld_read(CPLD_ADDR_HDMI));
114  	printf("DIPSW (SW3):               0x%08x\n",
115  	       cpld_read(CPLD_ADDR_DIPSW));
116  
117  #ifdef CONFIG_SH_SDHI
118  	/* switch MUX to SD0 */
119  	val = cpld_read(CPLD_ADDR_MUX);
120  	val &= ~MUX_MSK_SD0;
121  	val |= MUX_VAL_SD0;
122  	cpld_write(CPLD_ADDR_MUX, val);
123  #endif
124  }
125  
do_cpld(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])126  static int do_cpld(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
127  {
128  	u32 addr, val;
129  
130  	if (argc < 3)
131  		return CMD_RET_USAGE;
132  
133  	addr = simple_strtoul(argv[2], NULL, 16);
134  	if (!(addr == CPLD_ADDR_VERSION || addr == CPLD_ADDR_MODE ||
135  	      addr == CPLD_ADDR_MUX || addr == CPLD_ADDR_HDMI ||
136  	      addr == CPLD_ADDR_DIPSW || addr == CPLD_ADDR_RESET)) {
137  		printf("cpld invalid addr\n");
138  		return CMD_RET_USAGE;
139  	}
140  
141  	if (argc == 3 && strcmp(argv[1], "read") == 0) {
142  		printf("0x%x\n", cpld_read(addr));
143  	} else if (argc == 4 && strcmp(argv[1], "write") == 0) {
144  		val = simple_strtoul(argv[3], NULL, 16);
145  		if (addr == CPLD_ADDR_MUX) {
146  			/* never mask SCIFA0 console */
147  			val &= ~MUX_MSK_SCIFA0_USB;
148  			val |= MUX_VAL_SCIFA0_USB;
149  		}
150  		cpld_write(addr, val);
151  	}
152  
153  	return 0;
154  }
155  
156  U_BOOT_CMD(
157  	cpld, 4, 1, do_cpld,
158  	"CPLD access",
159  	"read addr\n"
160  	"cpld write addr val\n"
161  );
162  
reset_cpu(ulong addr)163  void reset_cpu(ulong addr)
164  {
165  	cpld_write(CPLD_ADDR_RESET, 1);
166  }
167