xref: /rk3399_ARM-atf/plat/socionext/uniphier/uniphier_usb.c (revision 0281e60c3d59d7552a589ecae1b1223b9dededd1)
1d8e919c7SMasahiro Yamada /*
2*b79b3177SMasahiro Yamada  * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
3d8e919c7SMasahiro Yamada  *
4d8e919c7SMasahiro Yamada  * SPDX-License-Identifier: BSD-3-Clause
5d8e919c7SMasahiro Yamada  */
6d8e919c7SMasahiro Yamada 
7d8e919c7SMasahiro Yamada #include <assert.h>
893c78ed2SAntonio Nino Diaz #include <stdint.h>
909d40e0eSAntonio Nino Diaz 
1009d40e0eSAntonio Nino Diaz #include <platform_def.h>
1109d40e0eSAntonio Nino Diaz 
1209d40e0eSAntonio Nino Diaz #include <arch_helpers.h>
1309d40e0eSAntonio Nino Diaz #include <drivers/io/io_block.h>
1409d40e0eSAntonio Nino Diaz #include <lib/mmio.h>
1509d40e0eSAntonio Nino Diaz #include <lib/utils_def.h>
16d8e919c7SMasahiro Yamada 
17d8e919c7SMasahiro Yamada #include "uniphier.h"
18d8e919c7SMasahiro Yamada 
19d8e919c7SMasahiro Yamada #define UNIPHIER_LD11_USB_DESC_BASE	0x30010000
20d8e919c7SMasahiro Yamada #define UNIPHIER_LD20_USB_DESC_BASE	0x30014000
219bdccff4SMasahiro Yamada #define UNIPHIER_PXS3_USB_DESC_BASE	0x30014000
22d8e919c7SMasahiro Yamada 
23d8e919c7SMasahiro Yamada #define UNIPHIER_SRB_OCM_CONT		0x61200000
24d8e919c7SMasahiro Yamada 
25d8e919c7SMasahiro Yamada struct uniphier_ld11_trans_op {
26d8e919c7SMasahiro Yamada 	uint8_t __pad[48];
27d8e919c7SMasahiro Yamada };
28d8e919c7SMasahiro Yamada 
29d8e919c7SMasahiro Yamada struct uniphier_ld11_op {
30d8e919c7SMasahiro Yamada 	uint8_t __pad[56];
31d8e919c7SMasahiro Yamada 	struct uniphier_ld11_trans_op *trans_op;
32d8e919c7SMasahiro Yamada 	void *__pad2;
33d8e919c7SMasahiro Yamada 	void *dev_desc;
34d8e919c7SMasahiro Yamada };
35d8e919c7SMasahiro Yamada 
36d8e919c7SMasahiro Yamada struct uniphier_ld20_trans_op {
37d8e919c7SMasahiro Yamada 	uint8_t __pad[40];
38d8e919c7SMasahiro Yamada };
39d8e919c7SMasahiro Yamada 
40d8e919c7SMasahiro Yamada struct uniphier_ld20_op {
41d8e919c7SMasahiro Yamada 	uint8_t __pad[192];
42d8e919c7SMasahiro Yamada 	struct uniphier_ld20_trans_op *trans_op;
43d8e919c7SMasahiro Yamada 	void *__pad2;
44d8e919c7SMasahiro Yamada 	void *dev_desc;
45d8e919c7SMasahiro Yamada };
46d8e919c7SMasahiro Yamada 
479bdccff4SMasahiro Yamada struct uniphier_pxs3_op {
489bdccff4SMasahiro Yamada 	uint8_t __pad[184];
499bdccff4SMasahiro Yamada 	struct uniphier_ld20_trans_op *trans_op;
509bdccff4SMasahiro Yamada 	void *__pad2;
519bdccff4SMasahiro Yamada 	void *dev_desc;
529bdccff4SMasahiro Yamada };
539bdccff4SMasahiro Yamada 
54d8e919c7SMasahiro Yamada static int (*__uniphier_usb_read)(int lba, uintptr_t buf, size_t size);
55d8e919c7SMasahiro Yamada 
uniphier_ld11_usb_init(void)56d8e919c7SMasahiro Yamada static void uniphier_ld11_usb_init(void)
57d8e919c7SMasahiro Yamada {
58d8e919c7SMasahiro Yamada 	struct uniphier_ld11_op *op = (void *)UNIPHIER_LD11_USB_DESC_BASE;
59d8e919c7SMasahiro Yamada 
60d8e919c7SMasahiro Yamada 	op->trans_op = (void *)(op + 1);
61d8e919c7SMasahiro Yamada 
62d8e919c7SMasahiro Yamada 	op->dev_desc = op->trans_op + 1;
63d8e919c7SMasahiro Yamada }
64d8e919c7SMasahiro Yamada 
uniphier_ld11_usb_read(int lba,uintptr_t buf,size_t size)65d8e919c7SMasahiro Yamada static int uniphier_ld11_usb_read(int lba, uintptr_t buf, size_t size)
66d8e919c7SMasahiro Yamada {
67d8e919c7SMasahiro Yamada 	static int (*rom_usb_read)(uintptr_t desc, unsigned int lba,
68d8e919c7SMasahiro Yamada 				   unsigned int size, uintptr_t buf);
69d8e919c7SMasahiro Yamada 	uintptr_t func_addr;
70d8e919c7SMasahiro Yamada 
71d8e919c7SMasahiro Yamada 	func_addr = uniphier_get_soc_revision() == 1 ? 0x3880 : 0x3958;
72d8e919c7SMasahiro Yamada 	rom_usb_read = (__typeof(rom_usb_read))func_addr;
73d8e919c7SMasahiro Yamada 
74d8e919c7SMasahiro Yamada 	return rom_usb_read(UNIPHIER_LD11_USB_DESC_BASE, lba, size, buf);
75d8e919c7SMasahiro Yamada }
76d8e919c7SMasahiro Yamada 
uniphier_ld20_usb_init(void)77d8e919c7SMasahiro Yamada static void uniphier_ld20_usb_init(void)
78d8e919c7SMasahiro Yamada {
79d8e919c7SMasahiro Yamada 	struct uniphier_ld20_op *op = (void *)UNIPHIER_LD20_USB_DESC_BASE;
80d8e919c7SMasahiro Yamada 
81d8e919c7SMasahiro Yamada 	op->trans_op = (void *)(op + 1);
82d8e919c7SMasahiro Yamada 
83d8e919c7SMasahiro Yamada 	op->dev_desc = op->trans_op + 1;
84d8e919c7SMasahiro Yamada }
85d8e919c7SMasahiro Yamada 
uniphier_ld20_usb_read(int lba,uintptr_t buf,size_t size)86d8e919c7SMasahiro Yamada static int uniphier_ld20_usb_read(int lba, uintptr_t buf, size_t size)
87d8e919c7SMasahiro Yamada {
88d8e919c7SMasahiro Yamada 	static int (*rom_usb_read)(uintptr_t desc, unsigned int lba,
89d8e919c7SMasahiro Yamada 				   unsigned int size, uintptr_t buf);
90d8e919c7SMasahiro Yamada 	int ret;
91d8e919c7SMasahiro Yamada 
92d8e919c7SMasahiro Yamada 	rom_usb_read = (__typeof(rom_usb_read))0x37f0;
93d8e919c7SMasahiro Yamada 
94d8e919c7SMasahiro Yamada 	mmio_write_32(UNIPHIER_SRB_OCM_CONT, 0x1ff);
95d8e919c7SMasahiro Yamada 
96d8e919c7SMasahiro Yamada 	/* ROM-API - return 1 on success, 0 on error */
97d8e919c7SMasahiro Yamada 	ret = rom_usb_read(UNIPHIER_LD20_USB_DESC_BASE, lba, size, buf);
98d8e919c7SMasahiro Yamada 
99d8e919c7SMasahiro Yamada 	mmio_write_32(UNIPHIER_SRB_OCM_CONT, 0);
100d8e919c7SMasahiro Yamada 
101d8e919c7SMasahiro Yamada 	return ret ? 0 : -1;
102d8e919c7SMasahiro Yamada }
103d8e919c7SMasahiro Yamada 
uniphier_pxs3_usb_init(void)1049bdccff4SMasahiro Yamada static void uniphier_pxs3_usb_init(void)
1059bdccff4SMasahiro Yamada {
1069bdccff4SMasahiro Yamada 	struct uniphier_pxs3_op *op = (void *)UNIPHIER_PXS3_USB_DESC_BASE;
1079bdccff4SMasahiro Yamada 
1089bdccff4SMasahiro Yamada 	op->trans_op = (void *)(op + 1);
1099bdccff4SMasahiro Yamada 
1109bdccff4SMasahiro Yamada 	op->dev_desc = op->trans_op + 1;
1119bdccff4SMasahiro Yamada }
1129bdccff4SMasahiro Yamada 
uniphier_pxs3_usb_read(int lba,uintptr_t buf,size_t size)113d8e919c7SMasahiro Yamada static int uniphier_pxs3_usb_read(int lba, uintptr_t buf, size_t size)
114d8e919c7SMasahiro Yamada {
1159bdccff4SMasahiro Yamada 	static int (*rom_usb_read)(uintptr_t desc, unsigned int lba,
1169bdccff4SMasahiro Yamada 				   unsigned int size, uintptr_t buf);
1179bdccff4SMasahiro Yamada 	int ret;
118d8e919c7SMasahiro Yamada 
1199bdccff4SMasahiro Yamada 	rom_usb_read = (__typeof(rom_usb_read))0x39e8;
120d8e919c7SMasahiro Yamada 
1219bdccff4SMasahiro Yamada 	/* ROM-API - return 1 on success, 0 on error */
1229bdccff4SMasahiro Yamada 	ret = rom_usb_read(UNIPHIER_PXS3_USB_DESC_BASE, lba, size, buf);
1239bdccff4SMasahiro Yamada 
1249bdccff4SMasahiro Yamada 	return ret ? 0 : -1;
125d8e919c7SMasahiro Yamada }
126d8e919c7SMasahiro Yamada 
127d8e919c7SMasahiro Yamada struct uniphier_usb_rom_param {
128d8e919c7SMasahiro Yamada 	void (*init)(void);
129d8e919c7SMasahiro Yamada 	int (*read)(int lba, uintptr_t buf, size_t size);
130d8e919c7SMasahiro Yamada };
131d8e919c7SMasahiro Yamada 
132d8e919c7SMasahiro Yamada static const struct uniphier_usb_rom_param uniphier_usb_rom_params[] = {
133d8e919c7SMasahiro Yamada 	[UNIPHIER_SOC_LD11] = {
134d8e919c7SMasahiro Yamada 		.init = uniphier_ld11_usb_init,
135d8e919c7SMasahiro Yamada 		.read = uniphier_ld11_usb_read,
136d8e919c7SMasahiro Yamada 	},
137d8e919c7SMasahiro Yamada 	[UNIPHIER_SOC_LD20] = {
138d8e919c7SMasahiro Yamada 		.init = uniphier_ld20_usb_init,
139d8e919c7SMasahiro Yamada 		.read = uniphier_ld20_usb_read,
140d8e919c7SMasahiro Yamada 	},
141d8e919c7SMasahiro Yamada 	[UNIPHIER_SOC_PXS3] = {
1429bdccff4SMasahiro Yamada 		.init = uniphier_pxs3_usb_init,
143d8e919c7SMasahiro Yamada 		.read = uniphier_pxs3_usb_read,
144d8e919c7SMasahiro Yamada 	},
145d8e919c7SMasahiro Yamada };
146d8e919c7SMasahiro Yamada 
uniphier_usb_read(int lba,uintptr_t buf,size_t size)147d8e919c7SMasahiro Yamada static size_t uniphier_usb_read(int lba, uintptr_t buf, size_t size)
148d8e919c7SMasahiro Yamada {
149d8e919c7SMasahiro Yamada 	int ret;
150d8e919c7SMasahiro Yamada 
151d8e919c7SMasahiro Yamada 	inv_dcache_range(buf, size);
152d8e919c7SMasahiro Yamada 
153d8e919c7SMasahiro Yamada 	ret = __uniphier_usb_read(lba, buf, size);
154d8e919c7SMasahiro Yamada 
155d8e919c7SMasahiro Yamada 	inv_dcache_range(buf, size);
156d8e919c7SMasahiro Yamada 
157d8e919c7SMasahiro Yamada 	return ret ? 0 : size;
158d8e919c7SMasahiro Yamada }
159d8e919c7SMasahiro Yamada 
160d8e919c7SMasahiro Yamada static struct io_block_dev_spec uniphier_usb_dev_spec = {
161d8e919c7SMasahiro Yamada 	.ops = {
162d8e919c7SMasahiro Yamada 		.read = uniphier_usb_read,
163d8e919c7SMasahiro Yamada 	},
164d8e919c7SMasahiro Yamada 	.block_size = 512,
165d8e919c7SMasahiro Yamada };
166d8e919c7SMasahiro Yamada 
uniphier_usb_init(unsigned int soc,struct io_block_dev_spec ** block_dev_spec)167*b79b3177SMasahiro Yamada int uniphier_usb_init(unsigned int soc,
168*b79b3177SMasahiro Yamada 		      struct io_block_dev_spec **block_dev_spec)
169d8e919c7SMasahiro Yamada {
170d8e919c7SMasahiro Yamada 	const struct uniphier_usb_rom_param *param;
171d8e919c7SMasahiro Yamada 
172d8e919c7SMasahiro Yamada 	assert(soc < ARRAY_SIZE(uniphier_usb_rom_params));
173d8e919c7SMasahiro Yamada 	param = &uniphier_usb_rom_params[soc];
174d8e919c7SMasahiro Yamada 
175d8e919c7SMasahiro Yamada 	if (param->init)
176d8e919c7SMasahiro Yamada 		param->init();
177d8e919c7SMasahiro Yamada 
178d8e919c7SMasahiro Yamada 	__uniphier_usb_read = param->read;
179d8e919c7SMasahiro Yamada 
180*b79b3177SMasahiro Yamada 	*block_dev_spec = &uniphier_usb_dev_spec;
181d8e919c7SMasahiro Yamada 
182d8e919c7SMasahiro Yamada 	return 0;
183d8e919c7SMasahiro Yamada }
184