0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/of_address.h>
0011
0012 #include <mm/mmu_decl.h>
0013
0014 #include <asm/io.h>
0015 #include <asm/udbg.h>
0016 #include <asm/fixmap.h>
0017
0018 #include "usbgecko_udbg.h"
0019
0020
0021 #define EXI_CLK_32MHZ 5
0022
0023 #define EXI_CSR 0x00
0024 #define EXI_CSR_CLKMASK (0x7<<4)
0025 #define EXI_CSR_CLK_32MHZ (EXI_CLK_32MHZ<<4)
0026 #define EXI_CSR_CSMASK (0x7<<7)
0027 #define EXI_CSR_CS_0 (0x1<<7)
0028
0029 #define EXI_CR 0x0c
0030 #define EXI_CR_TSTART (1<<0)
0031 #define EXI_CR_WRITE (1<<2)
0032 #define EXI_CR_READ_WRITE (2<<2)
0033 #define EXI_CR_TLEN(len) (((len)-1)<<4)
0034
0035 #define EXI_DATA 0x10
0036
0037 #define UG_READ_ATTEMPTS 100
0038 #define UG_WRITE_ATTEMPTS 100
0039
0040
0041 static void __iomem *ug_io_base;
0042
0043
0044
0045
0046 static u32 ug_io_transaction(u32 in)
0047 {
0048 u32 __iomem *csr_reg = ug_io_base + EXI_CSR;
0049 u32 __iomem *data_reg = ug_io_base + EXI_DATA;
0050 u32 __iomem *cr_reg = ug_io_base + EXI_CR;
0051 u32 csr, data, cr;
0052
0053
0054 csr = EXI_CSR_CLK_32MHZ | EXI_CSR_CS_0;
0055 out_be32(csr_reg, csr);
0056
0057
0058 data = in;
0059 out_be32(data_reg, data);
0060 cr = EXI_CR_TLEN(2) | EXI_CR_READ_WRITE | EXI_CR_TSTART;
0061 out_be32(cr_reg, cr);
0062
0063 while (in_be32(cr_reg) & EXI_CR_TSTART)
0064 barrier();
0065
0066
0067 out_be32(csr_reg, 0);
0068
0069
0070 data = in_be32(data_reg);
0071
0072 return data;
0073 }
0074
0075
0076
0077
0078 static int ug_is_adapter_present(void)
0079 {
0080 if (!ug_io_base)
0081 return 0;
0082
0083 return ug_io_transaction(0x90000000) == 0x04700000;
0084 }
0085
0086
0087
0088
0089 static int ug_is_txfifo_ready(void)
0090 {
0091 return ug_io_transaction(0xc0000000) & 0x04000000;
0092 }
0093
0094
0095
0096
0097
0098 static void ug_raw_putc(char ch)
0099 {
0100 ug_io_transaction(0xb0000000 | (ch << 20));
0101 }
0102
0103
0104
0105
0106
0107 static void ug_putc(char ch)
0108 {
0109 int count = UG_WRITE_ATTEMPTS;
0110
0111 if (!ug_io_base)
0112 return;
0113
0114 if (ch == '\n')
0115 ug_putc('\r');
0116
0117 while (!ug_is_txfifo_ready() && count--)
0118 barrier();
0119 if (count >= 0)
0120 ug_raw_putc(ch);
0121 }
0122
0123
0124
0125
0126 static int ug_is_rxfifo_ready(void)
0127 {
0128 return ug_io_transaction(0xd0000000) & 0x04000000;
0129 }
0130
0131
0132
0133
0134
0135 static int ug_raw_getc(void)
0136 {
0137 u32 data = ug_io_transaction(0xa0000000);
0138 if (data & 0x08000000)
0139 return (data >> 16) & 0xff;
0140 else
0141 return -1;
0142 }
0143
0144
0145
0146
0147
0148 static int ug_getc(void)
0149 {
0150 int count = UG_READ_ATTEMPTS;
0151
0152 if (!ug_io_base)
0153 return -1;
0154
0155 while (!ug_is_rxfifo_ready() && count--)
0156 barrier();
0157 return ug_raw_getc();
0158 }
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168 static void ug_udbg_putc(char ch)
0169 {
0170 ug_putc(ch);
0171 }
0172
0173
0174
0175
0176 static int ug_udbg_getc(void)
0177 {
0178 int ch;
0179
0180 while ((ch = ug_getc()) == -1)
0181 barrier();
0182 return ch;
0183 }
0184
0185
0186
0187
0188 static int ug_udbg_getc_poll(void)
0189 {
0190 if (!ug_is_rxfifo_ready())
0191 return -1;
0192 return ug_getc();
0193 }
0194
0195
0196
0197
0198 static void __iomem *__init ug_udbg_setup_exi_io_base(struct device_node *np)
0199 {
0200 void __iomem *exi_io_base = NULL;
0201 phys_addr_t paddr;
0202 const unsigned int *reg;
0203
0204 reg = of_get_property(np, "reg", NULL);
0205 if (reg) {
0206 paddr = of_translate_address(np, reg);
0207 if (paddr)
0208 exi_io_base = ioremap(paddr, reg[1]);
0209 }
0210 return exi_io_base;
0211 }
0212
0213
0214
0215
0216 static void __iomem *__init ug_udbg_probe(void __iomem *exi_io_base)
0217 {
0218 int i;
0219
0220
0221 for (i = 0; i < 2; i++) {
0222 ug_io_base = exi_io_base + 0x14 * i;
0223 if (ug_is_adapter_present())
0224 break;
0225 }
0226 if (i == 2)
0227 ug_io_base = NULL;
0228 return ug_io_base;
0229
0230 }
0231
0232
0233
0234
0235 void __init ug_udbg_init(void)
0236 {
0237 struct device_node *np;
0238 void __iomem *exi_io_base;
0239
0240 if (ug_io_base)
0241 udbg_printf("%s: early -> final\n", __func__);
0242
0243 np = of_find_compatible_node(NULL, NULL, "nintendo,flipper-exi");
0244 if (!np) {
0245 udbg_printf("%s: EXI node not found\n", __func__);
0246 goto out;
0247 }
0248
0249 exi_io_base = ug_udbg_setup_exi_io_base(np);
0250 if (!exi_io_base) {
0251 udbg_printf("%s: failed to setup EXI io base\n", __func__);
0252 goto done;
0253 }
0254
0255 if (!ug_udbg_probe(exi_io_base)) {
0256 udbg_printf("usbgecko_udbg: not found\n");
0257 iounmap(exi_io_base);
0258 } else {
0259 udbg_putc = ug_udbg_putc;
0260 udbg_getc = ug_udbg_getc;
0261 udbg_getc_poll = ug_udbg_getc_poll;
0262 udbg_printf("usbgecko_udbg: ready\n");
0263 }
0264
0265 done:
0266 of_node_put(np);
0267 out:
0268 return;
0269 }
0270
0271 #ifdef CONFIG_PPC_EARLY_DEBUG_USBGECKO
0272
0273 static phys_addr_t __init ug_early_grab_io_addr(void)
0274 {
0275 #if defined(CONFIG_GAMECUBE)
0276 return 0x0c000000;
0277 #elif defined(CONFIG_WII)
0278 return 0x0d000000;
0279 #else
0280 #error Invalid platform for USB Gecko based early debugging.
0281 #endif
0282 }
0283
0284
0285
0286
0287 void __init udbg_init_usbgecko(void)
0288 {
0289 void __iomem *early_debug_area;
0290 void __iomem *exi_io_base;
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300 early_debug_area = (void __iomem *)__fix_to_virt(FIX_EARLY_DEBUG_BASE);
0301 exi_io_base = early_debug_area + 0x00006800;
0302
0303
0304 if (!ug_udbg_probe(exi_io_base))
0305 return;
0306
0307
0308 udbg_putc = ug_udbg_putc;
0309 udbg_getc = ug_udbg_getc;
0310 udbg_getc_poll = ug_udbg_getc_poll;
0311
0312
0313
0314
0315
0316
0317
0318
0319 setbat(1, (unsigned long)early_debug_area,
0320 ug_early_grab_io_addr(), 128*1024, PAGE_KERNEL_NCG);
0321 }
0322
0323 #endif
0324