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