1 /* 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 #define UNIPHIER_PXS3_USB_DESC_BASE 0x30014000 20 21 #define UNIPHIER_SRB_OCM_CONT 0x61200000 22 23 struct uniphier_ld11_trans_op { 24 uint8_t __pad[48]; 25 }; 26 27 struct 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 34 struct uniphier_ld20_trans_op { 35 uint8_t __pad[40]; 36 }; 37 38 struct 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 45 struct 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 52 static int (*__uniphier_usb_read)(int lba, uintptr_t buf, size_t size); 53 54 static 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 63 static 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 75 static 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 84 static 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 102 static 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 111 static int uniphier_pxs3_usb_read(int lba, uintptr_t buf, size_t size) 112 { 113 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; 118 119 /* ROM-API - return 1 on success, 0 on error */ 120 ret = rom_usb_read(UNIPHIER_PXS3_USB_DESC_BASE, lba, size, buf); 121 122 return ret ? 0 : -1; 123 } 124 125 struct uniphier_usb_rom_param { 126 void (*init)(void); 127 int (*read)(int lba, uintptr_t buf, size_t size); 128 }; 129 130 static 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] = { 140 .init = uniphier_pxs3_usb_init, 141 .read = uniphier_pxs3_usb_read, 142 }, 143 }; 144 145 static 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 158 static 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 169 int 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 } 185