1 /* 2 * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <stdint.h> 9 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> 16 17 #include "uniphier.h" 18 19 #define UNIPHIER_LD11_USB_DESC_BASE 0x30010000 20 #define UNIPHIER_LD20_USB_DESC_BASE 0x30014000 21 #define UNIPHIER_PXS3_USB_DESC_BASE 0x30014000 22 23 #define UNIPHIER_SRB_OCM_CONT 0x61200000 24 25 struct uniphier_ld11_trans_op { 26 uint8_t __pad[48]; 27 }; 28 29 struct 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 36 struct uniphier_ld20_trans_op { 37 uint8_t __pad[40]; 38 }; 39 40 struct 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 47 struct 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 54 static int (*__uniphier_usb_read)(int lba, uintptr_t buf, size_t size); 55 56 static 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 65 static 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 77 static 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 86 static 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 104 static 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 113 static int uniphier_pxs3_usb_read(int lba, uintptr_t buf, size_t size) 114 { 115 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; 120 121 /* ROM-API - return 1 on success, 0 on error */ 122 ret = rom_usb_read(UNIPHIER_PXS3_USB_DESC_BASE, lba, size, buf); 123 124 return ret ? 0 : -1; 125 } 126 127 struct uniphier_usb_rom_param { 128 void (*init)(void); 129 int (*read)(int lba, uintptr_t buf, size_t size); 130 }; 131 132 static 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] = { 142 .init = uniphier_pxs3_usb_init, 143 .read = uniphier_pxs3_usb_read, 144 }, 145 }; 146 147 static 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 160 static struct io_block_dev_spec uniphier_usb_dev_spec = { 161 .ops = { 162 .read = uniphier_usb_read, 163 }, 164 .block_size = 512, 165 }; 166 167 int uniphier_usb_init(unsigned int soc, 168 struct io_block_dev_spec **block_dev_spec) 169 { 170 const struct uniphier_usb_rom_param *param; 171 172 assert(soc < ARRAY_SIZE(uniphier_usb_rom_params)); 173 param = &uniphier_usb_rom_params[soc]; 174 175 if (param->init) 176 param->init(); 177 178 __uniphier_usb_read = param->read; 179 180 *block_dev_spec = &uniphier_usb_dev_spec; 181 182 return 0; 183 } 184