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