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