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