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