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