xref: /openbmc/u-boot/board/keymile/kmp204x/qrio.c (revision 909ea9aa)
1 /*
2  * (C) Copyright 2013 Keymile AG
3  * Valentin Longchamp <valentin.longchamp@keymile.com>
4  *
5  * SPDX-License-Identifier:	GPL-2.0+
6  */
7 
8 #include <common.h>
9 
10 #include "../common/common.h"
11 #include "kmp204x.h"
12 
13 /* QRIO GPIO register offsets */
14 #define DIRECT_OFF		0x18
15 #define GPRT_OFF		0x1c
16 
17 int qrio_get_gpio(u8 port_off, u8 gpio_nr)
18 {
19 	u32 gprt;
20 
21 	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
22 
23 	gprt = in_be32(qrio_base + port_off + GPRT_OFF);
24 
25 	return (gprt >> gpio_nr) & 1U;
26 }
27 
28 void qrio_set_gpio(u8 port_off, u8 gpio_nr, bool value)
29 {
30 	u32 gprt, mask;
31 
32 	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
33 
34 	mask = 1U << gpio_nr;
35 
36 	gprt = in_be32(qrio_base + port_off + GPRT_OFF);
37 	if (value)
38 		gprt |= mask;
39 	else
40 		gprt &= ~mask;
41 
42 	out_be32(qrio_base + port_off + GPRT_OFF, gprt);
43 }
44 
45 void qrio_gpio_direction_output(u8 port_off, u8 gpio_nr, bool value)
46 {
47 	u32 direct, mask;
48 
49 	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
50 
51 	mask = 1U << gpio_nr;
52 
53 	direct = in_be32(qrio_base + port_off + DIRECT_OFF);
54 	direct |= mask;
55 	out_be32(qrio_base + port_off + DIRECT_OFF, direct);
56 
57 	qrio_set_gpio(port_off, gpio_nr, value);
58 }
59 
60 void qrio_gpio_direction_input(u8 port_off, u8 gpio_nr)
61 {
62 	u32 direct, mask;
63 
64 	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
65 
66 	mask = 1U << gpio_nr;
67 
68 	direct = in_be32(qrio_base + port_off + DIRECT_OFF);
69 	direct &= ~mask;
70 	out_be32(qrio_base + port_off + DIRECT_OFF, direct);
71 }
72 
73 void qrio_set_opendrain_gpio(u8 port_off, u8 gpio_nr, u8 val)
74 {
75 	u32 direct, mask;
76 
77 	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
78 
79 	mask = 1U << gpio_nr;
80 
81 	direct = in_be32(qrio_base + port_off + DIRECT_OFF);
82 	if (val == 0)
83 		/* set to output -> GPIO drives low */
84 		direct |= mask;
85 	else
86 		/* set to input -> GPIO floating */
87 		direct &= ~mask;
88 
89 	out_be32(qrio_base + port_off + DIRECT_OFF, direct);
90 }
91 
92 #define WDMASK_OFF	0x16
93 
94 void qrio_wdmask(u8 bit, bool wden)
95 {
96 	u16 wdmask;
97 	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
98 
99 	wdmask = in_be16(qrio_base + WDMASK_OFF);
100 
101 	if (wden)
102 		wdmask |= (1 << bit);
103 	else
104 		wdmask &= ~(1 << bit);
105 
106 	out_be16(qrio_base + WDMASK_OFF, wdmask);
107 }
108 
109 #define PRST_OFF	0x1a
110 
111 void qrio_prst(u8 bit, bool en, bool wden)
112 {
113 	u16 prst;
114 	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
115 
116 	qrio_wdmask(bit, wden);
117 
118 	prst = in_be16(qrio_base + PRST_OFF);
119 
120 	if (en)
121 		prst &= ~(1 << bit);
122 	else
123 		prst |= (1 << bit);
124 
125 	out_be16(qrio_base + PRST_OFF, prst);
126 }
127 
128 #define PRSTCFG_OFF	0x1c
129 
130 void qrio_prstcfg(u8 bit, u8 mode)
131 {
132 	u32 prstcfg;
133 	u8 i;
134 	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
135 
136 	prstcfg = in_be32(qrio_base + PRSTCFG_OFF);
137 
138 	for (i = 0; i < 2; i++) {
139 		if (mode & (1<<i))
140 			set_bit(2*bit+i, &prstcfg);
141 		else
142 			clear_bit(2*bit+i, &prstcfg);
143 	}
144 
145 	out_be32(qrio_base + PRSTCFG_OFF, prstcfg);
146 }
147 
148 #define CTRLH_OFF		0x02
149 #define CTRLH_WRL_BOOT		0x01
150 #define CTRLH_WRL_UNITRUN	0x02
151 
152 void qrio_set_leds(void)
153 {
154 	u8 ctrlh;
155 	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
156 
157 	/* set UNIT LED to RED and BOOT LED to ON */
158 	ctrlh = in_8(qrio_base + CTRLH_OFF);
159 	ctrlh |= (CTRLH_WRL_BOOT | CTRLH_WRL_UNITRUN);
160 	out_8(qrio_base + CTRLH_OFF, ctrlh);
161 }
162 
163 #define CTRLL_OFF		0x03
164 #define CTRLL_WRB_BUFENA	0x20
165 
166 void qrio_enable_app_buffer(void)
167 {
168 	u8 ctrll;
169 	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
170 
171 	/* enable application buffer */
172 	ctrll = in_8(qrio_base + CTRLL_OFF);
173 	ctrll |= (CTRLL_WRB_BUFENA);
174 	out_8(qrio_base + CTRLL_OFF, ctrll);
175 }
176