xref: /aosp_15_r20/external/arm-trusted-firmware/plat/socionext/uniphier/uniphier_usb.c (revision 54fd6939e177f8ff529b10183254802c76df6d08)
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