1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * udbg serial input/output routines for the USB Gecko adapter.
6*4882a593Smuzhiyun * Copyright (C) 2008-2009 The GameCube Linux Team
7*4882a593Smuzhiyun * Copyright (C) 2008,2009 Albert Herranz
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include <mm/mmu_decl.h>
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun #include <asm/io.h>
13*4882a593Smuzhiyun #include <asm/prom.h>
14*4882a593Smuzhiyun #include <asm/udbg.h>
15*4882a593Smuzhiyun #include <asm/fixmap.h>
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun #include "usbgecko_udbg.h"
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun #define EXI_CLK_32MHZ 5
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun #define EXI_CSR 0x00
23*4882a593Smuzhiyun #define EXI_CSR_CLKMASK (0x7<<4)
24*4882a593Smuzhiyun #define EXI_CSR_CLK_32MHZ (EXI_CLK_32MHZ<<4)
25*4882a593Smuzhiyun #define EXI_CSR_CSMASK (0x7<<7)
26*4882a593Smuzhiyun #define EXI_CSR_CS_0 (0x1<<7) /* Chip Select 001 */
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun #define EXI_CR 0x0c
29*4882a593Smuzhiyun #define EXI_CR_TSTART (1<<0)
30*4882a593Smuzhiyun #define EXI_CR_WRITE (1<<2)
31*4882a593Smuzhiyun #define EXI_CR_READ_WRITE (2<<2)
32*4882a593Smuzhiyun #define EXI_CR_TLEN(len) (((len)-1)<<4)
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun #define EXI_DATA 0x10
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun #define UG_READ_ATTEMPTS 100
37*4882a593Smuzhiyun #define UG_WRITE_ATTEMPTS 100
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun static void __iomem *ug_io_base;
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun /*
43*4882a593Smuzhiyun * Performs one input/output transaction between the exi host and the usbgecko.
44*4882a593Smuzhiyun */
ug_io_transaction(u32 in)45*4882a593Smuzhiyun static u32 ug_io_transaction(u32 in)
46*4882a593Smuzhiyun {
47*4882a593Smuzhiyun u32 __iomem *csr_reg = ug_io_base + EXI_CSR;
48*4882a593Smuzhiyun u32 __iomem *data_reg = ug_io_base + EXI_DATA;
49*4882a593Smuzhiyun u32 __iomem *cr_reg = ug_io_base + EXI_CR;
50*4882a593Smuzhiyun u32 csr, data, cr;
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun /* select */
53*4882a593Smuzhiyun csr = EXI_CSR_CLK_32MHZ | EXI_CSR_CS_0;
54*4882a593Smuzhiyun out_be32(csr_reg, csr);
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun /* read/write */
57*4882a593Smuzhiyun data = in;
58*4882a593Smuzhiyun out_be32(data_reg, data);
59*4882a593Smuzhiyun cr = EXI_CR_TLEN(2) | EXI_CR_READ_WRITE | EXI_CR_TSTART;
60*4882a593Smuzhiyun out_be32(cr_reg, cr);
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun while (in_be32(cr_reg) & EXI_CR_TSTART)
63*4882a593Smuzhiyun barrier();
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun /* deselect */
66*4882a593Smuzhiyun out_be32(csr_reg, 0);
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun /* result */
69*4882a593Smuzhiyun data = in_be32(data_reg);
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun return data;
72*4882a593Smuzhiyun }
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun /*
75*4882a593Smuzhiyun * Returns true if an usbgecko adapter is found.
76*4882a593Smuzhiyun */
ug_is_adapter_present(void)77*4882a593Smuzhiyun static int ug_is_adapter_present(void)
78*4882a593Smuzhiyun {
79*4882a593Smuzhiyun if (!ug_io_base)
80*4882a593Smuzhiyun return 0;
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun return ug_io_transaction(0x90000000) == 0x04700000;
83*4882a593Smuzhiyun }
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun /*
86*4882a593Smuzhiyun * Returns true if the TX fifo is ready for transmission.
87*4882a593Smuzhiyun */
ug_is_txfifo_ready(void)88*4882a593Smuzhiyun static int ug_is_txfifo_ready(void)
89*4882a593Smuzhiyun {
90*4882a593Smuzhiyun return ug_io_transaction(0xc0000000) & 0x04000000;
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun /*
94*4882a593Smuzhiyun * Tries to transmit a character.
95*4882a593Smuzhiyun * If the TX fifo is not ready the result is undefined.
96*4882a593Smuzhiyun */
ug_raw_putc(char ch)97*4882a593Smuzhiyun static void ug_raw_putc(char ch)
98*4882a593Smuzhiyun {
99*4882a593Smuzhiyun ug_io_transaction(0xb0000000 | (ch << 20));
100*4882a593Smuzhiyun }
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun /*
103*4882a593Smuzhiyun * Transmits a character.
104*4882a593Smuzhiyun * It silently fails if the TX fifo is not ready after a number of retries.
105*4882a593Smuzhiyun */
ug_putc(char ch)106*4882a593Smuzhiyun static void ug_putc(char ch)
107*4882a593Smuzhiyun {
108*4882a593Smuzhiyun int count = UG_WRITE_ATTEMPTS;
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun if (!ug_io_base)
111*4882a593Smuzhiyun return;
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun if (ch == '\n')
114*4882a593Smuzhiyun ug_putc('\r');
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun while (!ug_is_txfifo_ready() && count--)
117*4882a593Smuzhiyun barrier();
118*4882a593Smuzhiyun if (count >= 0)
119*4882a593Smuzhiyun ug_raw_putc(ch);
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun /*
123*4882a593Smuzhiyun * Returns true if the RX fifo is ready for transmission.
124*4882a593Smuzhiyun */
ug_is_rxfifo_ready(void)125*4882a593Smuzhiyun static int ug_is_rxfifo_ready(void)
126*4882a593Smuzhiyun {
127*4882a593Smuzhiyun return ug_io_transaction(0xd0000000) & 0x04000000;
128*4882a593Smuzhiyun }
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun /*
131*4882a593Smuzhiyun * Tries to receive a character.
132*4882a593Smuzhiyun * If a character is unavailable the function returns -1.
133*4882a593Smuzhiyun */
ug_raw_getc(void)134*4882a593Smuzhiyun static int ug_raw_getc(void)
135*4882a593Smuzhiyun {
136*4882a593Smuzhiyun u32 data = ug_io_transaction(0xa0000000);
137*4882a593Smuzhiyun if (data & 0x08000000)
138*4882a593Smuzhiyun return (data >> 16) & 0xff;
139*4882a593Smuzhiyun else
140*4882a593Smuzhiyun return -1;
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun /*
144*4882a593Smuzhiyun * Receives a character.
145*4882a593Smuzhiyun * It fails if the RX fifo is not ready after a number of retries.
146*4882a593Smuzhiyun */
ug_getc(void)147*4882a593Smuzhiyun static int ug_getc(void)
148*4882a593Smuzhiyun {
149*4882a593Smuzhiyun int count = UG_READ_ATTEMPTS;
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun if (!ug_io_base)
152*4882a593Smuzhiyun return -1;
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun while (!ug_is_rxfifo_ready() && count--)
155*4882a593Smuzhiyun barrier();
156*4882a593Smuzhiyun return ug_raw_getc();
157*4882a593Smuzhiyun }
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun /*
160*4882a593Smuzhiyun * udbg functions.
161*4882a593Smuzhiyun *
162*4882a593Smuzhiyun */
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun /*
165*4882a593Smuzhiyun * Transmits a character.
166*4882a593Smuzhiyun */
ug_udbg_putc(char ch)167*4882a593Smuzhiyun static void ug_udbg_putc(char ch)
168*4882a593Smuzhiyun {
169*4882a593Smuzhiyun ug_putc(ch);
170*4882a593Smuzhiyun }
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun /*
173*4882a593Smuzhiyun * Receives a character. Waits until a character is available.
174*4882a593Smuzhiyun */
ug_udbg_getc(void)175*4882a593Smuzhiyun static int ug_udbg_getc(void)
176*4882a593Smuzhiyun {
177*4882a593Smuzhiyun int ch;
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun while ((ch = ug_getc()) == -1)
180*4882a593Smuzhiyun barrier();
181*4882a593Smuzhiyun return ch;
182*4882a593Smuzhiyun }
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun /*
185*4882a593Smuzhiyun * Receives a character. If a character is not available, returns -1.
186*4882a593Smuzhiyun */
ug_udbg_getc_poll(void)187*4882a593Smuzhiyun static int ug_udbg_getc_poll(void)
188*4882a593Smuzhiyun {
189*4882a593Smuzhiyun if (!ug_is_rxfifo_ready())
190*4882a593Smuzhiyun return -1;
191*4882a593Smuzhiyun return ug_getc();
192*4882a593Smuzhiyun }
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun /*
195*4882a593Smuzhiyun * Retrieves and prepares the virtual address needed to access the hardware.
196*4882a593Smuzhiyun */
ug_udbg_setup_exi_io_base(struct device_node * np)197*4882a593Smuzhiyun static void __iomem *ug_udbg_setup_exi_io_base(struct device_node *np)
198*4882a593Smuzhiyun {
199*4882a593Smuzhiyun void __iomem *exi_io_base = NULL;
200*4882a593Smuzhiyun phys_addr_t paddr;
201*4882a593Smuzhiyun const unsigned int *reg;
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun reg = of_get_property(np, "reg", NULL);
204*4882a593Smuzhiyun if (reg) {
205*4882a593Smuzhiyun paddr = of_translate_address(np, reg);
206*4882a593Smuzhiyun if (paddr)
207*4882a593Smuzhiyun exi_io_base = ioremap(paddr, reg[1]);
208*4882a593Smuzhiyun }
209*4882a593Smuzhiyun return exi_io_base;
210*4882a593Smuzhiyun }
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun /*
213*4882a593Smuzhiyun * Checks if a USB Gecko adapter is inserted in any memory card slot.
214*4882a593Smuzhiyun */
ug_udbg_probe(void __iomem * exi_io_base)215*4882a593Smuzhiyun static void __iomem *ug_udbg_probe(void __iomem *exi_io_base)
216*4882a593Smuzhiyun {
217*4882a593Smuzhiyun int i;
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun /* look for a usbgecko on memcard slots A and B */
220*4882a593Smuzhiyun for (i = 0; i < 2; i++) {
221*4882a593Smuzhiyun ug_io_base = exi_io_base + 0x14 * i;
222*4882a593Smuzhiyun if (ug_is_adapter_present())
223*4882a593Smuzhiyun break;
224*4882a593Smuzhiyun }
225*4882a593Smuzhiyun if (i == 2)
226*4882a593Smuzhiyun ug_io_base = NULL;
227*4882a593Smuzhiyun return ug_io_base;
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun }
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun /*
232*4882a593Smuzhiyun * USB Gecko udbg support initialization.
233*4882a593Smuzhiyun */
ug_udbg_init(void)234*4882a593Smuzhiyun void __init ug_udbg_init(void)
235*4882a593Smuzhiyun {
236*4882a593Smuzhiyun struct device_node *np;
237*4882a593Smuzhiyun void __iomem *exi_io_base;
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun if (ug_io_base)
240*4882a593Smuzhiyun udbg_printf("%s: early -> final\n", __func__);
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun np = of_find_compatible_node(NULL, NULL, "nintendo,flipper-exi");
243*4882a593Smuzhiyun if (!np) {
244*4882a593Smuzhiyun udbg_printf("%s: EXI node not found\n", __func__);
245*4882a593Smuzhiyun goto out;
246*4882a593Smuzhiyun }
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun exi_io_base = ug_udbg_setup_exi_io_base(np);
249*4882a593Smuzhiyun if (!exi_io_base) {
250*4882a593Smuzhiyun udbg_printf("%s: failed to setup EXI io base\n", __func__);
251*4882a593Smuzhiyun goto done;
252*4882a593Smuzhiyun }
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun if (!ug_udbg_probe(exi_io_base)) {
255*4882a593Smuzhiyun udbg_printf("usbgecko_udbg: not found\n");
256*4882a593Smuzhiyun iounmap(exi_io_base);
257*4882a593Smuzhiyun } else {
258*4882a593Smuzhiyun udbg_putc = ug_udbg_putc;
259*4882a593Smuzhiyun udbg_getc = ug_udbg_getc;
260*4882a593Smuzhiyun udbg_getc_poll = ug_udbg_getc_poll;
261*4882a593Smuzhiyun udbg_printf("usbgecko_udbg: ready\n");
262*4882a593Smuzhiyun }
263*4882a593Smuzhiyun
264*4882a593Smuzhiyun done:
265*4882a593Smuzhiyun of_node_put(np);
266*4882a593Smuzhiyun out:
267*4882a593Smuzhiyun return;
268*4882a593Smuzhiyun }
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun #ifdef CONFIG_PPC_EARLY_DEBUG_USBGECKO
271*4882a593Smuzhiyun
ug_early_grab_io_addr(void)272*4882a593Smuzhiyun static phys_addr_t __init ug_early_grab_io_addr(void)
273*4882a593Smuzhiyun {
274*4882a593Smuzhiyun #if defined(CONFIG_GAMECUBE)
275*4882a593Smuzhiyun return 0x0c000000;
276*4882a593Smuzhiyun #elif defined(CONFIG_WII)
277*4882a593Smuzhiyun return 0x0d000000;
278*4882a593Smuzhiyun #else
279*4882a593Smuzhiyun #error Invalid platform for USB Gecko based early debugging.
280*4882a593Smuzhiyun #endif
281*4882a593Smuzhiyun }
282*4882a593Smuzhiyun
283*4882a593Smuzhiyun /*
284*4882a593Smuzhiyun * USB Gecko early debug support initialization for udbg.
285*4882a593Smuzhiyun */
udbg_init_usbgecko(void)286*4882a593Smuzhiyun void __init udbg_init_usbgecko(void)
287*4882a593Smuzhiyun {
288*4882a593Smuzhiyun void __iomem *early_debug_area;
289*4882a593Smuzhiyun void __iomem *exi_io_base;
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun /*
292*4882a593Smuzhiyun * At this point we have a BAT already setup that enables I/O
293*4882a593Smuzhiyun * to the EXI hardware.
294*4882a593Smuzhiyun *
295*4882a593Smuzhiyun * The BAT uses a virtual address range reserved at the fixmap.
296*4882a593Smuzhiyun * This must match the virtual address configured in
297*4882a593Smuzhiyun * head_32.S:setup_usbgecko_bat().
298*4882a593Smuzhiyun */
299*4882a593Smuzhiyun early_debug_area = (void __iomem *)__fix_to_virt(FIX_EARLY_DEBUG_BASE);
300*4882a593Smuzhiyun exi_io_base = early_debug_area + 0x00006800;
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun /* try to detect a USB Gecko */
303*4882a593Smuzhiyun if (!ug_udbg_probe(exi_io_base))
304*4882a593Smuzhiyun return;
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun /* we found a USB Gecko, load udbg hooks */
307*4882a593Smuzhiyun udbg_putc = ug_udbg_putc;
308*4882a593Smuzhiyun udbg_getc = ug_udbg_getc;
309*4882a593Smuzhiyun udbg_getc_poll = ug_udbg_getc_poll;
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun /*
312*4882a593Smuzhiyun * Prepare again the same BAT for MMU_init.
313*4882a593Smuzhiyun * This allows udbg I/O to continue working after the MMU is
314*4882a593Smuzhiyun * turned on for real.
315*4882a593Smuzhiyun * It is safe to continue using the same virtual address as it is
316*4882a593Smuzhiyun * a reserved fixmap area.
317*4882a593Smuzhiyun */
318*4882a593Smuzhiyun setbat(1, (unsigned long)early_debug_area,
319*4882a593Smuzhiyun ug_early_grab_io_addr(), 128*1024, PAGE_KERNEL_NCG);
320*4882a593Smuzhiyun }
321*4882a593Smuzhiyun
322*4882a593Smuzhiyun #endif /* CONFIG_PPC_EARLY_DEBUG_USBGECKO */
323*4882a593Smuzhiyun
324