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 20 #define UNIPHIER_SRB_OCM_CONT 0x61200000 21 22 struct uniphier_ld11_trans_op { 23 uint8_t __pad[48]; 24 }; 25 26 struct 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 33 struct uniphier_ld20_trans_op { 34 uint8_t __pad[40]; 35 }; 36 37 struct 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 44 static int (*__uniphier_usb_read)(int lba, uintptr_t buf, size_t size); 45 46 static 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 55 static 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 67 static 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 76 static 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 94 static 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 104 struct uniphier_usb_rom_param { 105 void (*init)(void); 106 int (*read)(int lba, uintptr_t buf, size_t size); 107 }; 108 109 static 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 123 static 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 136 static 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 147 int 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 } 163