1*54fd6939SJiyong Park /*
2*54fd6939SJiyong Park * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
3*54fd6939SJiyong Park *
4*54fd6939SJiyong Park * SPDX-License-Identifier: BSD-3-Clause
5*54fd6939SJiyong Park */
6*54fd6939SJiyong Park
7*54fd6939SJiyong Park #include <assert.h>
8*54fd6939SJiyong Park #include <stdint.h>
9*54fd6939SJiyong Park
10*54fd6939SJiyong Park #include <platform_def.h>
11*54fd6939SJiyong Park
12*54fd6939SJiyong Park #include <arch_helpers.h>
13*54fd6939SJiyong Park #include <drivers/io/io_block.h>
14*54fd6939SJiyong Park #include <lib/mmio.h>
15*54fd6939SJiyong Park #include <lib/utils_def.h>
16*54fd6939SJiyong Park
17*54fd6939SJiyong Park #include "uniphier.h"
18*54fd6939SJiyong Park
19*54fd6939SJiyong Park #define UNIPHIER_LD11_USB_DESC_BASE 0x30010000
20*54fd6939SJiyong Park #define UNIPHIER_LD20_USB_DESC_BASE 0x30014000
21*54fd6939SJiyong Park #define UNIPHIER_PXS3_USB_DESC_BASE 0x30014000
22*54fd6939SJiyong Park
23*54fd6939SJiyong Park #define UNIPHIER_SRB_OCM_CONT 0x61200000
24*54fd6939SJiyong Park
25*54fd6939SJiyong Park struct uniphier_ld11_trans_op {
26*54fd6939SJiyong Park uint8_t __pad[48];
27*54fd6939SJiyong Park };
28*54fd6939SJiyong Park
29*54fd6939SJiyong Park struct uniphier_ld11_op {
30*54fd6939SJiyong Park uint8_t __pad[56];
31*54fd6939SJiyong Park struct uniphier_ld11_trans_op *trans_op;
32*54fd6939SJiyong Park void *__pad2;
33*54fd6939SJiyong Park void *dev_desc;
34*54fd6939SJiyong Park };
35*54fd6939SJiyong Park
36*54fd6939SJiyong Park struct uniphier_ld20_trans_op {
37*54fd6939SJiyong Park uint8_t __pad[40];
38*54fd6939SJiyong Park };
39*54fd6939SJiyong Park
40*54fd6939SJiyong Park struct uniphier_ld20_op {
41*54fd6939SJiyong Park uint8_t __pad[192];
42*54fd6939SJiyong Park struct uniphier_ld20_trans_op *trans_op;
43*54fd6939SJiyong Park void *__pad2;
44*54fd6939SJiyong Park void *dev_desc;
45*54fd6939SJiyong Park };
46*54fd6939SJiyong Park
47*54fd6939SJiyong Park struct uniphier_pxs3_op {
48*54fd6939SJiyong Park uint8_t __pad[184];
49*54fd6939SJiyong Park struct uniphier_ld20_trans_op *trans_op;
50*54fd6939SJiyong Park void *__pad2;
51*54fd6939SJiyong Park void *dev_desc;
52*54fd6939SJiyong Park };
53*54fd6939SJiyong Park
54*54fd6939SJiyong Park static int (*__uniphier_usb_read)(int lba, uintptr_t buf, size_t size);
55*54fd6939SJiyong Park
uniphier_ld11_usb_init(void)56*54fd6939SJiyong Park static void uniphier_ld11_usb_init(void)
57*54fd6939SJiyong Park {
58*54fd6939SJiyong Park struct uniphier_ld11_op *op = (void *)UNIPHIER_LD11_USB_DESC_BASE;
59*54fd6939SJiyong Park
60*54fd6939SJiyong Park op->trans_op = (void *)(op + 1);
61*54fd6939SJiyong Park
62*54fd6939SJiyong Park op->dev_desc = op->trans_op + 1;
63*54fd6939SJiyong Park }
64*54fd6939SJiyong Park
uniphier_ld11_usb_read(int lba,uintptr_t buf,size_t size)65*54fd6939SJiyong Park static int uniphier_ld11_usb_read(int lba, uintptr_t buf, size_t size)
66*54fd6939SJiyong Park {
67*54fd6939SJiyong Park static int (*rom_usb_read)(uintptr_t desc, unsigned int lba,
68*54fd6939SJiyong Park unsigned int size, uintptr_t buf);
69*54fd6939SJiyong Park uintptr_t func_addr;
70*54fd6939SJiyong Park
71*54fd6939SJiyong Park func_addr = uniphier_get_soc_revision() == 1 ? 0x3880 : 0x3958;
72*54fd6939SJiyong Park rom_usb_read = (__typeof(rom_usb_read))func_addr;
73*54fd6939SJiyong Park
74*54fd6939SJiyong Park return rom_usb_read(UNIPHIER_LD11_USB_DESC_BASE, lba, size, buf);
75*54fd6939SJiyong Park }
76*54fd6939SJiyong Park
uniphier_ld20_usb_init(void)77*54fd6939SJiyong Park static void uniphier_ld20_usb_init(void)
78*54fd6939SJiyong Park {
79*54fd6939SJiyong Park struct uniphier_ld20_op *op = (void *)UNIPHIER_LD20_USB_DESC_BASE;
80*54fd6939SJiyong Park
81*54fd6939SJiyong Park op->trans_op = (void *)(op + 1);
82*54fd6939SJiyong Park
83*54fd6939SJiyong Park op->dev_desc = op->trans_op + 1;
84*54fd6939SJiyong Park }
85*54fd6939SJiyong Park
uniphier_ld20_usb_read(int lba,uintptr_t buf,size_t size)86*54fd6939SJiyong Park static int uniphier_ld20_usb_read(int lba, uintptr_t buf, size_t size)
87*54fd6939SJiyong Park {
88*54fd6939SJiyong Park static int (*rom_usb_read)(uintptr_t desc, unsigned int lba,
89*54fd6939SJiyong Park unsigned int size, uintptr_t buf);
90*54fd6939SJiyong Park int ret;
91*54fd6939SJiyong Park
92*54fd6939SJiyong Park rom_usb_read = (__typeof(rom_usb_read))0x37f0;
93*54fd6939SJiyong Park
94*54fd6939SJiyong Park mmio_write_32(UNIPHIER_SRB_OCM_CONT, 0x1ff);
95*54fd6939SJiyong Park
96*54fd6939SJiyong Park /* ROM-API - return 1 on success, 0 on error */
97*54fd6939SJiyong Park ret = rom_usb_read(UNIPHIER_LD20_USB_DESC_BASE, lba, size, buf);
98*54fd6939SJiyong Park
99*54fd6939SJiyong Park mmio_write_32(UNIPHIER_SRB_OCM_CONT, 0);
100*54fd6939SJiyong Park
101*54fd6939SJiyong Park return ret ? 0 : -1;
102*54fd6939SJiyong Park }
103*54fd6939SJiyong Park
uniphier_pxs3_usb_init(void)104*54fd6939SJiyong Park static void uniphier_pxs3_usb_init(void)
105*54fd6939SJiyong Park {
106*54fd6939SJiyong Park struct uniphier_pxs3_op *op = (void *)UNIPHIER_PXS3_USB_DESC_BASE;
107*54fd6939SJiyong Park
108*54fd6939SJiyong Park op->trans_op = (void *)(op + 1);
109*54fd6939SJiyong Park
110*54fd6939SJiyong Park op->dev_desc = op->trans_op + 1;
111*54fd6939SJiyong Park }
112*54fd6939SJiyong Park
uniphier_pxs3_usb_read(int lba,uintptr_t buf,size_t size)113*54fd6939SJiyong Park static int uniphier_pxs3_usb_read(int lba, uintptr_t buf, size_t size)
114*54fd6939SJiyong Park {
115*54fd6939SJiyong Park static int (*rom_usb_read)(uintptr_t desc, unsigned int lba,
116*54fd6939SJiyong Park unsigned int size, uintptr_t buf);
117*54fd6939SJiyong Park int ret;
118*54fd6939SJiyong Park
119*54fd6939SJiyong Park rom_usb_read = (__typeof(rom_usb_read))0x39e8;
120*54fd6939SJiyong Park
121*54fd6939SJiyong Park /* ROM-API - return 1 on success, 0 on error */
122*54fd6939SJiyong Park ret = rom_usb_read(UNIPHIER_PXS3_USB_DESC_BASE, lba, size, buf);
123*54fd6939SJiyong Park
124*54fd6939SJiyong Park return ret ? 0 : -1;
125*54fd6939SJiyong Park }
126*54fd6939SJiyong Park
127*54fd6939SJiyong Park struct uniphier_usb_rom_param {
128*54fd6939SJiyong Park void (*init)(void);
129*54fd6939SJiyong Park int (*read)(int lba, uintptr_t buf, size_t size);
130*54fd6939SJiyong Park };
131*54fd6939SJiyong Park
132*54fd6939SJiyong Park static const struct uniphier_usb_rom_param uniphier_usb_rom_params[] = {
133*54fd6939SJiyong Park [UNIPHIER_SOC_LD11] = {
134*54fd6939SJiyong Park .init = uniphier_ld11_usb_init,
135*54fd6939SJiyong Park .read = uniphier_ld11_usb_read,
136*54fd6939SJiyong Park },
137*54fd6939SJiyong Park [UNIPHIER_SOC_LD20] = {
138*54fd6939SJiyong Park .init = uniphier_ld20_usb_init,
139*54fd6939SJiyong Park .read = uniphier_ld20_usb_read,
140*54fd6939SJiyong Park },
141*54fd6939SJiyong Park [UNIPHIER_SOC_PXS3] = {
142*54fd6939SJiyong Park .init = uniphier_pxs3_usb_init,
143*54fd6939SJiyong Park .read = uniphier_pxs3_usb_read,
144*54fd6939SJiyong Park },
145*54fd6939SJiyong Park };
146*54fd6939SJiyong Park
uniphier_usb_read(int lba,uintptr_t buf,size_t size)147*54fd6939SJiyong Park static size_t uniphier_usb_read(int lba, uintptr_t buf, size_t size)
148*54fd6939SJiyong Park {
149*54fd6939SJiyong Park int ret;
150*54fd6939SJiyong Park
151*54fd6939SJiyong Park inv_dcache_range(buf, size);
152*54fd6939SJiyong Park
153*54fd6939SJiyong Park ret = __uniphier_usb_read(lba, buf, size);
154*54fd6939SJiyong Park
155*54fd6939SJiyong Park inv_dcache_range(buf, size);
156*54fd6939SJiyong Park
157*54fd6939SJiyong Park return ret ? 0 : size;
158*54fd6939SJiyong Park }
159*54fd6939SJiyong Park
160*54fd6939SJiyong Park static struct io_block_dev_spec uniphier_usb_dev_spec = {
161*54fd6939SJiyong Park .ops = {
162*54fd6939SJiyong Park .read = uniphier_usb_read,
163*54fd6939SJiyong Park },
164*54fd6939SJiyong Park .block_size = 512,
165*54fd6939SJiyong Park };
166*54fd6939SJiyong Park
uniphier_usb_init(unsigned int soc,struct io_block_dev_spec ** block_dev_spec)167*54fd6939SJiyong Park int uniphier_usb_init(unsigned int soc,
168*54fd6939SJiyong Park struct io_block_dev_spec **block_dev_spec)
169*54fd6939SJiyong Park {
170*54fd6939SJiyong Park const struct uniphier_usb_rom_param *param;
171*54fd6939SJiyong Park
172*54fd6939SJiyong Park assert(soc < ARRAY_SIZE(uniphier_usb_rom_params));
173*54fd6939SJiyong Park param = &uniphier_usb_rom_params[soc];
174*54fd6939SJiyong Park
175*54fd6939SJiyong Park if (param->init)
176*54fd6939SJiyong Park param->init();
177*54fd6939SJiyong Park
178*54fd6939SJiyong Park __uniphier_usb_read = param->read;
179*54fd6939SJiyong Park
180*54fd6939SJiyong Park *block_dev_spec = &uniphier_usb_dev_spec;
181*54fd6939SJiyong Park
182*54fd6939SJiyong Park return 0;
183*54fd6939SJiyong Park }
184