1d8e919c7SMasahiro Yamada /* 2*b79b3177SMasahiro Yamada * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. 3d8e919c7SMasahiro Yamada * 4d8e919c7SMasahiro Yamada * SPDX-License-Identifier: BSD-3-Clause 5d8e919c7SMasahiro Yamada */ 6d8e919c7SMasahiro Yamada 7d8e919c7SMasahiro Yamada #include <assert.h> 893c78ed2SAntonio Nino Diaz #include <stdint.h> 909d40e0eSAntonio Nino Diaz 1009d40e0eSAntonio Nino Diaz #include <platform_def.h> 1109d40e0eSAntonio Nino Diaz 1209d40e0eSAntonio Nino Diaz #include <arch_helpers.h> 1309d40e0eSAntonio Nino Diaz #include <drivers/io/io_block.h> 1409d40e0eSAntonio Nino Diaz #include <lib/mmio.h> 1509d40e0eSAntonio Nino Diaz #include <lib/utils_def.h> 16d8e919c7SMasahiro Yamada 17d8e919c7SMasahiro Yamada #include "uniphier.h" 18d8e919c7SMasahiro Yamada 19d8e919c7SMasahiro Yamada #define UNIPHIER_LD11_USB_DESC_BASE 0x30010000 20d8e919c7SMasahiro Yamada #define UNIPHIER_LD20_USB_DESC_BASE 0x30014000 219bdccff4SMasahiro Yamada #define UNIPHIER_PXS3_USB_DESC_BASE 0x30014000 22d8e919c7SMasahiro Yamada 23d8e919c7SMasahiro Yamada #define UNIPHIER_SRB_OCM_CONT 0x61200000 24d8e919c7SMasahiro Yamada 25d8e919c7SMasahiro Yamada struct uniphier_ld11_trans_op { 26d8e919c7SMasahiro Yamada uint8_t __pad[48]; 27d8e919c7SMasahiro Yamada }; 28d8e919c7SMasahiro Yamada 29d8e919c7SMasahiro Yamada struct uniphier_ld11_op { 30d8e919c7SMasahiro Yamada uint8_t __pad[56]; 31d8e919c7SMasahiro Yamada struct uniphier_ld11_trans_op *trans_op; 32d8e919c7SMasahiro Yamada void *__pad2; 33d8e919c7SMasahiro Yamada void *dev_desc; 34d8e919c7SMasahiro Yamada }; 35d8e919c7SMasahiro Yamada 36d8e919c7SMasahiro Yamada struct uniphier_ld20_trans_op { 37d8e919c7SMasahiro Yamada uint8_t __pad[40]; 38d8e919c7SMasahiro Yamada }; 39d8e919c7SMasahiro Yamada 40d8e919c7SMasahiro Yamada struct uniphier_ld20_op { 41d8e919c7SMasahiro Yamada uint8_t __pad[192]; 42d8e919c7SMasahiro Yamada struct uniphier_ld20_trans_op *trans_op; 43d8e919c7SMasahiro Yamada void *__pad2; 44d8e919c7SMasahiro Yamada void *dev_desc; 45d8e919c7SMasahiro Yamada }; 46d8e919c7SMasahiro Yamada 479bdccff4SMasahiro Yamada struct uniphier_pxs3_op { 489bdccff4SMasahiro Yamada uint8_t __pad[184]; 499bdccff4SMasahiro Yamada struct uniphier_ld20_trans_op *trans_op; 509bdccff4SMasahiro Yamada void *__pad2; 519bdccff4SMasahiro Yamada void *dev_desc; 529bdccff4SMasahiro Yamada }; 539bdccff4SMasahiro Yamada 54d8e919c7SMasahiro Yamada static int (*__uniphier_usb_read)(int lba, uintptr_t buf, size_t size); 55d8e919c7SMasahiro Yamada 56d8e919c7SMasahiro Yamada static void uniphier_ld11_usb_init(void) 57d8e919c7SMasahiro Yamada { 58d8e919c7SMasahiro Yamada struct uniphier_ld11_op *op = (void *)UNIPHIER_LD11_USB_DESC_BASE; 59d8e919c7SMasahiro Yamada 60d8e919c7SMasahiro Yamada op->trans_op = (void *)(op + 1); 61d8e919c7SMasahiro Yamada 62d8e919c7SMasahiro Yamada op->dev_desc = op->trans_op + 1; 63d8e919c7SMasahiro Yamada } 64d8e919c7SMasahiro Yamada 65d8e919c7SMasahiro Yamada static int uniphier_ld11_usb_read(int lba, uintptr_t buf, size_t size) 66d8e919c7SMasahiro Yamada { 67d8e919c7SMasahiro Yamada static int (*rom_usb_read)(uintptr_t desc, unsigned int lba, 68d8e919c7SMasahiro Yamada unsigned int size, uintptr_t buf); 69d8e919c7SMasahiro Yamada uintptr_t func_addr; 70d8e919c7SMasahiro Yamada 71d8e919c7SMasahiro Yamada func_addr = uniphier_get_soc_revision() == 1 ? 0x3880 : 0x3958; 72d8e919c7SMasahiro Yamada rom_usb_read = (__typeof(rom_usb_read))func_addr; 73d8e919c7SMasahiro Yamada 74d8e919c7SMasahiro Yamada return rom_usb_read(UNIPHIER_LD11_USB_DESC_BASE, lba, size, buf); 75d8e919c7SMasahiro Yamada } 76d8e919c7SMasahiro Yamada 77d8e919c7SMasahiro Yamada static void uniphier_ld20_usb_init(void) 78d8e919c7SMasahiro Yamada { 79d8e919c7SMasahiro Yamada struct uniphier_ld20_op *op = (void *)UNIPHIER_LD20_USB_DESC_BASE; 80d8e919c7SMasahiro Yamada 81d8e919c7SMasahiro Yamada op->trans_op = (void *)(op + 1); 82d8e919c7SMasahiro Yamada 83d8e919c7SMasahiro Yamada op->dev_desc = op->trans_op + 1; 84d8e919c7SMasahiro Yamada } 85d8e919c7SMasahiro Yamada 86d8e919c7SMasahiro Yamada static int uniphier_ld20_usb_read(int lba, uintptr_t buf, size_t size) 87d8e919c7SMasahiro Yamada { 88d8e919c7SMasahiro Yamada static int (*rom_usb_read)(uintptr_t desc, unsigned int lba, 89d8e919c7SMasahiro Yamada unsigned int size, uintptr_t buf); 90d8e919c7SMasahiro Yamada int ret; 91d8e919c7SMasahiro Yamada 92d8e919c7SMasahiro Yamada rom_usb_read = (__typeof(rom_usb_read))0x37f0; 93d8e919c7SMasahiro Yamada 94d8e919c7SMasahiro Yamada mmio_write_32(UNIPHIER_SRB_OCM_CONT, 0x1ff); 95d8e919c7SMasahiro Yamada 96d8e919c7SMasahiro Yamada /* ROM-API - return 1 on success, 0 on error */ 97d8e919c7SMasahiro Yamada ret = rom_usb_read(UNIPHIER_LD20_USB_DESC_BASE, lba, size, buf); 98d8e919c7SMasahiro Yamada 99d8e919c7SMasahiro Yamada mmio_write_32(UNIPHIER_SRB_OCM_CONT, 0); 100d8e919c7SMasahiro Yamada 101d8e919c7SMasahiro Yamada return ret ? 0 : -1; 102d8e919c7SMasahiro Yamada } 103d8e919c7SMasahiro Yamada 1049bdccff4SMasahiro Yamada static void uniphier_pxs3_usb_init(void) 1059bdccff4SMasahiro Yamada { 1069bdccff4SMasahiro Yamada struct uniphier_pxs3_op *op = (void *)UNIPHIER_PXS3_USB_DESC_BASE; 1079bdccff4SMasahiro Yamada 1089bdccff4SMasahiro Yamada op->trans_op = (void *)(op + 1); 1099bdccff4SMasahiro Yamada 1109bdccff4SMasahiro Yamada op->dev_desc = op->trans_op + 1; 1119bdccff4SMasahiro Yamada } 1129bdccff4SMasahiro Yamada 113d8e919c7SMasahiro Yamada static int uniphier_pxs3_usb_read(int lba, uintptr_t buf, size_t size) 114d8e919c7SMasahiro Yamada { 1159bdccff4SMasahiro Yamada static int (*rom_usb_read)(uintptr_t desc, unsigned int lba, 1169bdccff4SMasahiro Yamada unsigned int size, uintptr_t buf); 1179bdccff4SMasahiro Yamada int ret; 118d8e919c7SMasahiro Yamada 1199bdccff4SMasahiro Yamada rom_usb_read = (__typeof(rom_usb_read))0x39e8; 120d8e919c7SMasahiro Yamada 1219bdccff4SMasahiro Yamada /* ROM-API - return 1 on success, 0 on error */ 1229bdccff4SMasahiro Yamada ret = rom_usb_read(UNIPHIER_PXS3_USB_DESC_BASE, lba, size, buf); 1239bdccff4SMasahiro Yamada 1249bdccff4SMasahiro Yamada return ret ? 0 : -1; 125d8e919c7SMasahiro Yamada } 126d8e919c7SMasahiro Yamada 127d8e919c7SMasahiro Yamada struct uniphier_usb_rom_param { 128d8e919c7SMasahiro Yamada void (*init)(void); 129d8e919c7SMasahiro Yamada int (*read)(int lba, uintptr_t buf, size_t size); 130d8e919c7SMasahiro Yamada }; 131d8e919c7SMasahiro Yamada 132d8e919c7SMasahiro Yamada static const struct uniphier_usb_rom_param uniphier_usb_rom_params[] = { 133d8e919c7SMasahiro Yamada [UNIPHIER_SOC_LD11] = { 134d8e919c7SMasahiro Yamada .init = uniphier_ld11_usb_init, 135d8e919c7SMasahiro Yamada .read = uniphier_ld11_usb_read, 136d8e919c7SMasahiro Yamada }, 137d8e919c7SMasahiro Yamada [UNIPHIER_SOC_LD20] = { 138d8e919c7SMasahiro Yamada .init = uniphier_ld20_usb_init, 139d8e919c7SMasahiro Yamada .read = uniphier_ld20_usb_read, 140d8e919c7SMasahiro Yamada }, 141d8e919c7SMasahiro Yamada [UNIPHIER_SOC_PXS3] = { 1429bdccff4SMasahiro Yamada .init = uniphier_pxs3_usb_init, 143d8e919c7SMasahiro Yamada .read = uniphier_pxs3_usb_read, 144d8e919c7SMasahiro Yamada }, 145d8e919c7SMasahiro Yamada }; 146d8e919c7SMasahiro Yamada 147d8e919c7SMasahiro Yamada static size_t uniphier_usb_read(int lba, uintptr_t buf, size_t size) 148d8e919c7SMasahiro Yamada { 149d8e919c7SMasahiro Yamada int ret; 150d8e919c7SMasahiro Yamada 151d8e919c7SMasahiro Yamada inv_dcache_range(buf, size); 152d8e919c7SMasahiro Yamada 153d8e919c7SMasahiro Yamada ret = __uniphier_usb_read(lba, buf, size); 154d8e919c7SMasahiro Yamada 155d8e919c7SMasahiro Yamada inv_dcache_range(buf, size); 156d8e919c7SMasahiro Yamada 157d8e919c7SMasahiro Yamada return ret ? 0 : size; 158d8e919c7SMasahiro Yamada } 159d8e919c7SMasahiro Yamada 160d8e919c7SMasahiro Yamada static struct io_block_dev_spec uniphier_usb_dev_spec = { 161d8e919c7SMasahiro Yamada .ops = { 162d8e919c7SMasahiro Yamada .read = uniphier_usb_read, 163d8e919c7SMasahiro Yamada }, 164d8e919c7SMasahiro Yamada .block_size = 512, 165d8e919c7SMasahiro Yamada }; 166d8e919c7SMasahiro Yamada 167*b79b3177SMasahiro Yamada int uniphier_usb_init(unsigned int soc, 168*b79b3177SMasahiro Yamada struct io_block_dev_spec **block_dev_spec) 169d8e919c7SMasahiro Yamada { 170d8e919c7SMasahiro Yamada const struct uniphier_usb_rom_param *param; 171d8e919c7SMasahiro Yamada 172d8e919c7SMasahiro Yamada assert(soc < ARRAY_SIZE(uniphier_usb_rom_params)); 173d8e919c7SMasahiro Yamada param = &uniphier_usb_rom_params[soc]; 174d8e919c7SMasahiro Yamada 175d8e919c7SMasahiro Yamada if (param->init) 176d8e919c7SMasahiro Yamada param->init(); 177d8e919c7SMasahiro Yamada 178d8e919c7SMasahiro Yamada __uniphier_usb_read = param->read; 179d8e919c7SMasahiro Yamada 180*b79b3177SMasahiro Yamada *block_dev_spec = &uniphier_usb_dev_spec; 181d8e919c7SMasahiro Yamada 182d8e919c7SMasahiro Yamada return 0; 183d8e919c7SMasahiro Yamada } 184