blob: 49ca8e5096f74fab55d5e8bd4cdda322a9087dbf [file] [log] [blame]
Masahiro Yamada574388c2016-09-03 11:37:40 +09001/*
2 * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
3 *
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>
12#include <sys/types.h>
13#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
19
20#define UNIPHIER_SRB_OCM_CONT 0x61200000
21
22struct uniphier_ld11_trans_op {
23 uint8_t __pad[48];
24};
25
26struct uniphier_ld11_op {
27 uint8_t __pad[56];
28 struct uniphier_ld11_trans_op *trans_op;
29 void *__pad2;
30 void *dev_desc;
31};
32
33struct uniphier_ld20_trans_op {
34 uint8_t __pad[40];
35};
36
37struct uniphier_ld20_op {
38 uint8_t __pad[192];
39 struct uniphier_ld20_trans_op *trans_op;
40 void *__pad2;
41 void *dev_desc;
42};
43
44static int (*__uniphier_usb_read)(int lba, uintptr_t buf, size_t size);
45
46static void uniphier_ld11_usb_init(void)
47{
48 struct uniphier_ld11_op *op = (void *)UNIPHIER_LD11_USB_DESC_BASE;
49
50 op->trans_op = (void *)(op + 1);
51
52 op->dev_desc = op->trans_op + 1;
53}
54
55static int uniphier_ld11_usb_read(int lba, uintptr_t buf, size_t size)
56{
57 static int (*rom_usb_read)(uintptr_t desc, unsigned int lba,
58 unsigned int size, uintptr_t buf);
59 uintptr_t func_addr;
60
61 func_addr = uniphier_get_soc_revision() == 1 ? 0x3880 : 0x3958;
62 rom_usb_read = (__typeof(rom_usb_read))func_addr;
63
64 return rom_usb_read(UNIPHIER_LD11_USB_DESC_BASE, lba, size, buf);
65}
66
67static void uniphier_ld20_usb_init(void)
68{
69 struct uniphier_ld20_op *op = (void *)UNIPHIER_LD20_USB_DESC_BASE;
70
71 op->trans_op = (void *)(op + 1);
72
73 op->dev_desc = op->trans_op + 1;
74}
75
76static int uniphier_ld20_usb_read(int lba, uintptr_t buf, size_t size)
77{
78 static int (*rom_usb_read)(uintptr_t desc, unsigned int lba,
79 unsigned int size, uintptr_t buf);
80 int ret;
81
82 rom_usb_read = (__typeof(rom_usb_read))0x37f0;
83
84 mmio_write_32(UNIPHIER_SRB_OCM_CONT, 0x1ff);
85
86 /* ROM-API - return 1 on success, 0 on error */
87 ret = rom_usb_read(UNIPHIER_LD20_USB_DESC_BASE, lba, size, buf);
88
89 mmio_write_32(UNIPHIER_SRB_OCM_CONT, 0);
90
91 return ret ? 0 : -1;
92}
93
94static int uniphier_pxs3_usb_read(int lba, uintptr_t buf, size_t size)
95{
96 static int (*rom_usb_read)(unsigned int lba, unsigned int size,
97 uintptr_t buf);
98
99 rom_usb_read = (__typeof(rom_usb_read))0x100c;
100
101 return rom_usb_read(lba, size, buf);
102}
103
104struct uniphier_usb_rom_param {
105 void (*init)(void);
106 int (*read)(int lba, uintptr_t buf, size_t size);
107};
108
109static const struct uniphier_usb_rom_param uniphier_usb_rom_params[] = {
110 [UNIPHIER_SOC_LD11] = {
111 .init = uniphier_ld11_usb_init,
112 .read = uniphier_ld11_usb_read,
113 },
114 [UNIPHIER_SOC_LD20] = {
115 .init = uniphier_ld20_usb_init,
116 .read = uniphier_ld20_usb_read,
117 },
118 [UNIPHIER_SOC_PXS3] = {
119 .read = uniphier_pxs3_usb_read,
120 },
121};
122
123static size_t uniphier_usb_read(int lba, uintptr_t buf, size_t size)
124{
125 int ret;
126
127 inv_dcache_range(buf, size);
128
129 ret = __uniphier_usb_read(lba, buf, size);
130
131 inv_dcache_range(buf, size);
132
133 return ret ? 0 : size;
134}
135
136static struct io_block_dev_spec uniphier_usb_dev_spec = {
137 .buffer = {
138 .offset = UNIPHIER_BLOCK_BUF_BASE,
139 .length = UNIPHIER_BLOCK_BUF_SIZE,
140 },
141 .ops = {
142 .read = uniphier_usb_read,
143 },
144 .block_size = 512,
145};
146
147int uniphier_usb_init(unsigned int soc, uintptr_t *block_dev_spec)
148{
149 const struct uniphier_usb_rom_param *param;
150
151 assert(soc < ARRAY_SIZE(uniphier_usb_rom_params));
152 param = &uniphier_usb_rom_params[soc];
153
154 if (param->init)
155 param->init();
156
157 __uniphier_usb_read = param->read;
158
159 *block_dev_spec = (uintptr_t)&uniphier_usb_dev_spec;
160
161 return 0;
162}