blob: b51b601208391774b8c8aaa598794103ee07d682 [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
7#include <arch_helpers.h>
8#include <assert.h>
9#include <io/io_block.h>
10#include <mmio.h>
11#include <platform_def.h>
Antonio Nino Diaz4b32e622018-08-16 16:52:57 +010012#include <stdint.h>
Masahiro Yamada574388c2016-09-03 11:37:40 +090013#include <utils_def.h>
14
15#include "uniphier.h"
16
17#define UNIPHIER_LD11_USB_DESC_BASE 0x30010000
18#define UNIPHIER_LD20_USB_DESC_BASE 0x30014000
Masahiro Yamadac9266882017-08-31 16:30:47 +090019#define UNIPHIER_PXS3_USB_DESC_BASE 0x30014000
Masahiro Yamada574388c2016-09-03 11:37:40 +090020
21#define UNIPHIER_SRB_OCM_CONT 0x61200000
22
23struct uniphier_ld11_trans_op {
24 uint8_t __pad[48];
25};
26
27struct uniphier_ld11_op {
28 uint8_t __pad[56];
29 struct uniphier_ld11_trans_op *trans_op;
30 void *__pad2;
31 void *dev_desc;
32};
33
34struct uniphier_ld20_trans_op {
35 uint8_t __pad[40];
36};
37
38struct uniphier_ld20_op {
39 uint8_t __pad[192];
40 struct uniphier_ld20_trans_op *trans_op;
41 void *__pad2;
42 void *dev_desc;
43};
44
Masahiro Yamadac9266882017-08-31 16:30:47 +090045struct uniphier_pxs3_op {
46 uint8_t __pad[184];
47 struct uniphier_ld20_trans_op *trans_op;
48 void *__pad2;
49 void *dev_desc;
50};
51
Masahiro Yamada574388c2016-09-03 11:37:40 +090052static int (*__uniphier_usb_read)(int lba, uintptr_t buf, size_t size);
53
54static void uniphier_ld11_usb_init(void)
55{
56 struct uniphier_ld11_op *op = (void *)UNIPHIER_LD11_USB_DESC_BASE;
57
58 op->trans_op = (void *)(op + 1);
59
60 op->dev_desc = op->trans_op + 1;
61}
62
63static int uniphier_ld11_usb_read(int lba, uintptr_t buf, size_t size)
64{
65 static int (*rom_usb_read)(uintptr_t desc, unsigned int lba,
66 unsigned int size, uintptr_t buf);
67 uintptr_t func_addr;
68
69 func_addr = uniphier_get_soc_revision() == 1 ? 0x3880 : 0x3958;
70 rom_usb_read = (__typeof(rom_usb_read))func_addr;
71
72 return rom_usb_read(UNIPHIER_LD11_USB_DESC_BASE, lba, size, buf);
73}
74
75static void uniphier_ld20_usb_init(void)
76{
77 struct uniphier_ld20_op *op = (void *)UNIPHIER_LD20_USB_DESC_BASE;
78
79 op->trans_op = (void *)(op + 1);
80
81 op->dev_desc = op->trans_op + 1;
82}
83
84static int uniphier_ld20_usb_read(int lba, uintptr_t buf, size_t size)
85{
86 static int (*rom_usb_read)(uintptr_t desc, unsigned int lba,
87 unsigned int size, uintptr_t buf);
88 int ret;
89
90 rom_usb_read = (__typeof(rom_usb_read))0x37f0;
91
92 mmio_write_32(UNIPHIER_SRB_OCM_CONT, 0x1ff);
93
94 /* ROM-API - return 1 on success, 0 on error */
95 ret = rom_usb_read(UNIPHIER_LD20_USB_DESC_BASE, lba, size, buf);
96
97 mmio_write_32(UNIPHIER_SRB_OCM_CONT, 0);
98
99 return ret ? 0 : -1;
100}
101
Masahiro Yamadac9266882017-08-31 16:30:47 +0900102static void uniphier_pxs3_usb_init(void)
103{
104 struct uniphier_pxs3_op *op = (void *)UNIPHIER_PXS3_USB_DESC_BASE;
105
106 op->trans_op = (void *)(op + 1);
107
108 op->dev_desc = op->trans_op + 1;
109}
110
Masahiro Yamada574388c2016-09-03 11:37:40 +0900111static int uniphier_pxs3_usb_read(int lba, uintptr_t buf, size_t size)
112{
Masahiro Yamadac9266882017-08-31 16:30:47 +0900113 static int (*rom_usb_read)(uintptr_t desc, unsigned int lba,
114 unsigned int size, uintptr_t buf);
115 int ret;
116
117 rom_usb_read = (__typeof(rom_usb_read))0x39e8;
Masahiro Yamada574388c2016-09-03 11:37:40 +0900118
Masahiro Yamadac9266882017-08-31 16:30:47 +0900119 /* ROM-API - return 1 on success, 0 on error */
120 ret = rom_usb_read(UNIPHIER_PXS3_USB_DESC_BASE, lba, size, buf);
Masahiro Yamada574388c2016-09-03 11:37:40 +0900121
Masahiro Yamadac9266882017-08-31 16:30:47 +0900122 return ret ? 0 : -1;
Masahiro Yamada574388c2016-09-03 11:37:40 +0900123}
124
125struct uniphier_usb_rom_param {
126 void (*init)(void);
127 int (*read)(int lba, uintptr_t buf, size_t size);
128};
129
130static const struct uniphier_usb_rom_param uniphier_usb_rom_params[] = {
131 [UNIPHIER_SOC_LD11] = {
132 .init = uniphier_ld11_usb_init,
133 .read = uniphier_ld11_usb_read,
134 },
135 [UNIPHIER_SOC_LD20] = {
136 .init = uniphier_ld20_usb_init,
137 .read = uniphier_ld20_usb_read,
138 },
139 [UNIPHIER_SOC_PXS3] = {
Masahiro Yamadac9266882017-08-31 16:30:47 +0900140 .init = uniphier_pxs3_usb_init,
Masahiro Yamada574388c2016-09-03 11:37:40 +0900141 .read = uniphier_pxs3_usb_read,
142 },
143};
144
145static size_t uniphier_usb_read(int lba, uintptr_t buf, size_t size)
146{
147 int ret;
148
149 inv_dcache_range(buf, size);
150
151 ret = __uniphier_usb_read(lba, buf, size);
152
153 inv_dcache_range(buf, size);
154
155 return ret ? 0 : size;
156}
157
158static struct io_block_dev_spec uniphier_usb_dev_spec = {
159 .buffer = {
160 .offset = UNIPHIER_BLOCK_BUF_BASE,
161 .length = UNIPHIER_BLOCK_BUF_SIZE,
162 },
163 .ops = {
164 .read = uniphier_usb_read,
165 },
166 .block_size = 512,
167};
168
169int uniphier_usb_init(unsigned int soc, uintptr_t *block_dev_spec)
170{
171 const struct uniphier_usb_rom_param *param;
172
173 assert(soc < ARRAY_SIZE(uniphier_usb_rom_params));
174 param = &uniphier_usb_rom_params[soc];
175
176 if (param->init)
177 param->init();
178
179 __uniphier_usb_read = param->read;
180
181 *block_dev_spec = (uintptr_t)&uniphier_usb_dev_spec;
182
183 return 0;
184}