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