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