Commit 1502c4e1 authored by davidcunado-arm's avatar davidcunado-arm Committed by GitHub
Browse files

Merge pull request #974 from masahir0y/uniphier

UniPhier Initial Support
parents 42fb35a8 63b3a28e
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <debug.h>
#include <io/io_block.h>
#include <mmio.h>
#include <platform_def.h>
#include <sys/types.h>
#include <utils_def.h>
#include "uniphier.h"
#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
#define NAND_CMD_READ0 0
#define NAND_CMD_READSTART 0x30
#define DENALI_ECC_ENABLE 0x0e0
#define DENALI_PAGES_PER_BLOCK 0x150
#define DENALI_DEVICE_MAIN_AREA_SIZE 0x170
#define DENALI_DEVICE_SPARE_AREA_SIZE 0x180
#define DENALI_TWO_ROW_ADDR_CYCLES 0x190
#define DENALI_INTR_STATUS0 0x410
#define DENALI_INTR_ECC_UNCOR_ERR BIT(1)
#define DENALI_INTR_DMA_CMD_COMP BIT(2)
#define DENALI_INTR_INT_ACT BIT(12)
#define DENALI_DMA_ENABLE 0x700
#define DENALI_HOST_ADDR 0x00
#define DENALI_HOST_DATA 0x10
#define DENALI_MAP01 (1 << 26)
#define DENALI_MAP10 (2 << 26)
#define DENALI_MAP11 (3 << 26)
#define DENALI_MAP11_CMD ((DENALI_MAP11) | 0)
#define DENALI_MAP11_ADDR ((DENALI_MAP11) | 1)
#define DENALI_MAP11_DATA ((DENALI_MAP11) | 2)
#define DENALI_ACCESS_DEFAULT_AREA 0x42
#define UNIPHIER_NAND_BBT_UNKNOWN 0xff
struct uniphier_nand {
uintptr_t host_base;
uintptr_t reg_base;
int pages_per_block;
int page_size;
int two_row_addr_cycles;
uint8_t bbt[16];
};
struct uniphier_nand uniphier_nand;
static void uniphier_nand_host_write(struct uniphier_nand *nand,
uint32_t addr, uint32_t data)
{
mmio_write_32(nand->host_base + DENALI_HOST_ADDR, addr);
mmio_write_32(nand->host_base + DENALI_HOST_DATA, data);
}
static uint32_t uniphier_nand_host_read(struct uniphier_nand *nand,
uint32_t addr)
{
mmio_write_32(nand->host_base + DENALI_HOST_ADDR, addr);
return mmio_read_32(nand->host_base + DENALI_HOST_DATA);
}
static int uniphier_nand_block_isbad(struct uniphier_nand *nand, int block)
{
int page = nand->pages_per_block * block;
int column = nand->page_size;
uint8_t bbm;
uint32_t status;
int is_bad;
/* use cache if available */
if (block < ARRAY_SIZE(nand->bbt) &&
nand->bbt[block] != UNIPHIER_NAND_BBT_UNKNOWN)
return nand->bbt[block];
mmio_write_32(nand->reg_base + DENALI_ECC_ENABLE, 0);
mmio_write_32(nand->reg_base + DENALI_INTR_STATUS0, -1);
uniphier_nand_host_write(nand, DENALI_MAP11_CMD, NAND_CMD_READ0);
uniphier_nand_host_write(nand, DENALI_MAP11_ADDR, column & 0xff);
uniphier_nand_host_write(nand, DENALI_MAP11_ADDR, (column >> 8) & 0xff);
uniphier_nand_host_write(nand, DENALI_MAP11_ADDR, page & 0xff);
uniphier_nand_host_write(nand, DENALI_MAP11_ADDR, (page >> 8) & 0xff);
if (!nand->two_row_addr_cycles)
uniphier_nand_host_write(nand, DENALI_MAP11_ADDR,
(page >> 16) & 0xff);
uniphier_nand_host_write(nand, DENALI_MAP11_CMD, NAND_CMD_READSTART);
do {
status = mmio_read_32(nand->reg_base + DENALI_INTR_STATUS0);
} while (!(status & DENALI_INTR_INT_ACT));
bbm = uniphier_nand_host_read(nand, DENALI_MAP11_DATA);
is_bad = bbm != 0xff;
/* save the result for future re-use */
nand->bbt[block] = is_bad;
if (is_bad)
WARN("found bad block at %d. skip.\n", block);
return is_bad;
}
static int uniphier_nand_read_pages(struct uniphier_nand *nand, uintptr_t buf,
int page_start, int page_count)
{
uint32_t status;
mmio_write_32(nand->reg_base + DENALI_ECC_ENABLE, 1);
mmio_write_32(nand->reg_base + DENALI_DMA_ENABLE, 1);
mmio_write_32(nand->reg_base + DENALI_INTR_STATUS0, -1);
/* use Data DMA (64bit) */
mmio_write_32(nand->host_base + DENALI_HOST_ADDR,
DENALI_MAP10 | page_start);
/*
* 1. setup transfer type, interrupt when complete,
* burst len = 64 bytes, the number of pages
*/
mmio_write_32(nand->host_base + DENALI_HOST_DATA,
0x01002000 | (64 << 16) | page_count);
/* 2. set memory low address */
mmio_write_32(nand->host_base + DENALI_HOST_DATA, buf);
/* 3. set memory high address */
mmio_write_32(nand->host_base + DENALI_HOST_DATA, buf >> 32);
do {
status = mmio_read_32(nand->reg_base + DENALI_INTR_STATUS0);
} while (!(status & DENALI_INTR_DMA_CMD_COMP));
mmio_write_32(nand->reg_base + DENALI_DMA_ENABLE, 0);
if (status & DENALI_INTR_ECC_UNCOR_ERR) {
ERROR("uncorrectable error in page range %d-%d",
page_start, page_start + page_count - 1);
return -EBADMSG;
}
return 0;
}
static size_t __uniphier_nand_read(struct uniphier_nand *nand, int lba,
uintptr_t buf, size_t size)
{
int pages_per_block = nand->pages_per_block;
int page_size = nand->page_size;
int blocks_to_skip = lba / pages_per_block;
int pages_to_read = DIV_ROUND_UP(size, page_size);
int page = lba % pages_per_block;
int block = 0;
uintptr_t p = buf;
int page_count, ret;
while (blocks_to_skip) {
ret = uniphier_nand_block_isbad(nand, block);
if (ret < 0)
goto out;
if (!ret)
blocks_to_skip--;
block++;
}
while (pages_to_read) {
ret = uniphier_nand_block_isbad(nand, block);
if (ret < 0)
goto out;
if (ret) {
block++;
continue;
}
page_count = MIN(pages_per_block - page, pages_to_read);
ret = uniphier_nand_read_pages(nand, p,
block * pages_per_block + page,
page_count);
if (ret)
goto out;
block++;
page = 0;
p += page_size * page_count;
pages_to_read -= page_count;
}
out:
/* number of read bytes */
return MIN(size, p - buf);
}
static size_t uniphier_nand_read(int lba, uintptr_t buf, size_t size)
{
size_t count;
inv_dcache_range(buf, size);
count = __uniphier_nand_read(&uniphier_nand, lba, buf, size);
inv_dcache_range(buf, size);
return count;
}
static struct io_block_dev_spec uniphier_nand_dev_spec = {
.buffer = {
.offset = UNIPHIER_BLOCK_BUF_BASE,
.length = UNIPHIER_BLOCK_BUF_SIZE,
},
.ops = {
.read = uniphier_nand_read,
},
/* fill .block_size at run-time */
};
static int uniphier_nand_hw_init(struct uniphier_nand *nand)
{
int i;
for (i = 0; i < ARRAY_SIZE(nand->bbt); i++)
nand->bbt[i] = UNIPHIER_NAND_BBT_UNKNOWN;
nand->host_base = 0x68000000;
nand->reg_base = 0x68100000;
nand->pages_per_block =
mmio_read_32(nand->reg_base + DENALI_PAGES_PER_BLOCK);
nand->page_size =
mmio_read_32(nand->reg_base + DENALI_DEVICE_MAIN_AREA_SIZE);
if (mmio_read_32(nand->reg_base + DENALI_TWO_ROW_ADDR_CYCLES) & BIT(0))
nand->two_row_addr_cycles = 1;
uniphier_nand_host_write(nand, DENALI_MAP10,
DENALI_ACCESS_DEFAULT_AREA);
return 0;
}
int uniphier_nand_init(uintptr_t *block_dev_spec)
{
int ret;
ret = uniphier_nand_hw_init(&uniphier_nand);
if (ret)
return ret;
uniphier_nand_dev_spec.block_size = uniphier_nand.page_size;
*block_dev_spec = (uintptr_t)&uniphier_nand_dev_spec;
return 0;
}
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <debug.h>
#include <mmio.h>
#include <psci.h>
#include "uniphier.h"
#define UNIPHIER_ROM_RSV0 0x59801200
#define UNIPHIER_SLFRSTSEL 0x61843010
#define UNIPHIER_SLFRSTSEL_MASK (0x3 << 0)
#define UNIPHIER_SLFRSTCTL 0x61843014
#define UNIPHIER_SLFRSTCTL_RST (1 << 0)
#define MPIDR_AFFINITY_INVALID ((u_register_t)-1)
uintptr_t uniphier_sec_entrypoint;
void uniphier_warmboot_entrypoint(void);
void __dead2 uniphier_fake_pwr_down(void);
u_register_t uniphier_holding_pen_release;
static int uniphier_psci_scp_mode;
static int uniphier_psci_pwr_domain_on(u_register_t mpidr)
{
uniphier_holding_pen_release = mpidr;
flush_dcache_range((uint64_t)&uniphier_holding_pen_release,
sizeof(uniphier_holding_pen_release));
mmio_write_64(UNIPHIER_ROM_RSV0,
(uint64_t)&uniphier_warmboot_entrypoint);
sev();
return PSCI_E_SUCCESS;
}
static void uniphier_psci_pwr_domain_off(const psci_power_state_t *target_state)
{
uniphier_gic_cpuif_disable();
}
static void uniphier_psci_pwr_domain_on_finish(
const psci_power_state_t *target_state)
{
uniphier_gic_pcpu_init();
uniphier_gic_cpuif_enable();
uniphier_cci_enable();
}
static void __dead2 uniphier_psci_pwr_domain_pwr_down_wfi(
const psci_power_state_t *target_state)
{
/*
* The Boot ROM cannot distinguish warn and cold resets.
* Instead of the CPU reset, fake it.
*/
uniphier_holding_pen_release = MPIDR_AFFINITY_INVALID;
flush_dcache_range((uint64_t)&uniphier_holding_pen_release,
sizeof(uniphier_holding_pen_release));
uniphier_fake_pwr_down();
}
static void uniphier_self_system_reset(void)
{
mmio_clrbits_32(UNIPHIER_SLFRSTSEL, UNIPHIER_SLFRSTSEL_MASK);
mmio_setbits_32(UNIPHIER_SLFRSTCTL, UNIPHIER_SLFRSTCTL_RST);
}
static void __dead2 uniphier_psci_system_off(void)
{
if (uniphier_psci_scp_mode) {
uniphier_scp_system_off();
} else {
NOTICE("SCP is disabled; can't shutdown the system.\n");
NOTICE("Resetting the system instead.\n");
uniphier_self_system_reset();
}
wfi();
ERROR("UniPhier System Off: operation not handled.\n");
panic();
}
static void __dead2 uniphier_psci_system_reset(void)
{
if (uniphier_psci_scp_mode)
uniphier_scp_system_reset();
else
uniphier_self_system_reset();
wfi();
ERROR("UniPhier System Reset: operation not handled.\n");
panic();
}
static const struct plat_psci_ops uniphier_psci_ops = {
.pwr_domain_on = uniphier_psci_pwr_domain_on,
.pwr_domain_off = uniphier_psci_pwr_domain_off,
.pwr_domain_on_finish = uniphier_psci_pwr_domain_on_finish,
.pwr_domain_pwr_down_wfi = uniphier_psci_pwr_domain_pwr_down_wfi,
.system_off = uniphier_psci_system_off,
.system_reset = uniphier_psci_system_reset,
};
int plat_setup_psci_ops(uintptr_t sec_entrypoint,
const struct plat_psci_ops **psci_ops)
{
uniphier_sec_entrypoint = sec_entrypoint;
flush_dcache_range((uint64_t)&uniphier_sec_entrypoint,
sizeof(uniphier_sec_entrypoint));
uniphier_psci_scp_mode = uniphier_scp_is_running();
flush_dcache_range((uint64_t)&uniphier_psci_scp_mode,
sizeof(uniphier_psci_scp_mode));
if (uniphier_psci_scp_mode)
uniphier_scp_open_com();
*psci_ops = &uniphier_psci_ops;
return 0;
}
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <mmio.h>
#include <utils_def.h>
#include "uniphier.h"
#define UNIPHIER_ROM_RSV3 0x5980120c
#define UNIPHIER_STMBE2COM 0x5f800030
#define UNIPHIER_BETOSTMIRQ0PT 0x5f800070
#define UNIPHIER_SCP_READY_MAGIC 0x0000b6a5
#define UNIPHIER_SCP_PACKET_START 0xA0
#define UNIPHIER_SCP_PACKET_END 0xA5
#define UNIPHIER_SCP_PACKET_ESC 0xA6
#define UNIPHIER_SCP_IS_CTRL_CODE(c) (0xA0 <= (c) && (c) <= 0xA6)
int uniphier_scp_is_running(void)
{
return mmio_read_32(UNIPHIER_STMBE2COM) == UNIPHIER_SCP_READY_MAGIC;
}
void uniphier_scp_start(void)
{
uint32_t tmp;
mmio_write_32(UNIPHIER_STMBE2COM + 4, UNIPHIER_SCP_BASE);
mmio_write_32(UNIPHIER_STMBE2COM, UNIPHIER_SCP_READY_MAGIC);
do {
tmp = mmio_read_32(UNIPHIER_ROM_RSV3);
} while (!(tmp & BIT(8)));
mmio_write_32(UNIPHIER_ROM_RSV3, tmp | BIT(9));
}
static void uniphier_scp_send_packet(const uint8_t *packet, int packet_len)
{
uintptr_t reg = UNIPHIER_STMBE2COM;
uint32_t word;
int len, i;
while (packet_len) {
len = MIN(packet_len, 4);
word = 0;
for (i = 0; i < len; i++)
word |= *packet++ << (8 * i);
mmio_write_32(reg, word);
reg += 4;
packet_len -= len;
}
mmio_write_8(UNIPHIER_BETOSTMIRQ0PT, 0x55);
}
static void uniphier_scp_send_cmd(const uint8_t *cmd, int cmd_len)
{
uint8_t packet[32]; /* long enough */
uint8_t *p = packet;
uint8_t c;
int i;
*p++ = UNIPHIER_SCP_PACKET_START;
*p++ = cmd_len;
for (i = 0; i < cmd_len; i++) {
c = *cmd++;
if (UNIPHIER_SCP_IS_CTRL_CODE(c)) {
*p++ = UNIPHIER_SCP_PACKET_ESC;
*p++ = c ^ BIT(7);
} else {
*p++ = c;
}
}
*p++ = UNIPHIER_SCP_PACKET_END;
uniphier_scp_send_packet(packet, p - packet);
}
#define UNIPHIER_SCP_CMD(name, ...) \
static const uint8_t __uniphier_scp_##name##_cmd[] = { \
__VA_ARGS__ \
}; \
void uniphier_scp_##name(void) \
{ \
uniphier_scp_send_cmd(__uniphier_scp_##name##_cmd, \
ARRAY_SIZE(__uniphier_scp_##name##_cmd)); \
}
UNIPHIER_SCP_CMD(open_com, 0x00, 0x00, 0x05)
UNIPHIER_SCP_CMD(system_off, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01)
UNIPHIER_SCP_CMD(system_reset, 0x00, 0x02, 0x00)
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <asm_macros.S>
.globl uniphier_warmboot_entrypoint
.globl uniphier_fake_pwr_down
func uniphier_warmboot_entrypoint
mrs x0, mpidr_el1
mov_imm x1, MPIDR_AFFINITY_MASK
and x0, x0, x1
b 1f
0: wfe
1: ldr x1, uniphier_holding_pen_release
cmp x1, x0
b.ne 0b
ldr x0, uniphier_sec_entrypoint
br x0
endfunc uniphier_warmboot_entrypoint
func uniphier_fake_pwr_down
bl disable_mmu_icache_el3
b uniphier_warmboot_entrypoint
endfunc uniphier_fake_pwr_down
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <mmio.h>
#include "uniphier.h"
#define UNIPHIER_REVISION 0x5f800000
static unsigned int uniphier_get_revision_field(unsigned int mask,
unsigned int shift)
{
uint32_t revision = mmio_read_32(UNIPHIER_REVISION);
return (revision >> shift) & mask;
}
unsigned int uniphier_get_soc_type(void)
{
return uniphier_get_revision_field(0xff, 16);
}
unsigned int uniphier_get_soc_model(void)
{
return uniphier_get_revision_field(0x07, 8);
}
unsigned int uniphier_get_soc_revision(void)
{
return uniphier_get_revision_field(0x1f, 0);
}
unsigned int uniphier_get_soc_id(void)
{
uint32_t type = uniphier_get_soc_type();
switch (type) {
case 0x31:
return UNIPHIER_SOC_LD11;
case 0x32:
return UNIPHIER_SOC_LD20;
case 0x35:
return UNIPHIER_SOC_PXS3;
default:
return UNIPHIER_SOC_UNKNOWN;
}
}
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <platform.h>
unsigned int plat_get_syscnt_freq2(void)
{
return 50000000;
}
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <platform.h>
int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
unsigned int *flags)
{
*flags = ROTPK_NOT_DEPLOYED;
return 0;
}
int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
{
/*
* No support for non-volatile counter. Update the ROT key to protect
* the system against rollback.
*/
*nv_ctr = 0;
return 0;
}
int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
{
return 0;
}
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <platform.h>
#include "uniphier.h"
static unsigned char uniphier_power_domain_tree_desc[UNIPHIER_CLUSTER_COUNT + 1];
const unsigned char *plat_get_power_domain_tree_desc(void)
{
int i;
uniphier_power_domain_tree_desc[0] = UNIPHIER_CLUSTER_COUNT;
for (i = 0; i < UNIPHIER_CLUSTER_COUNT; i++)
uniphier_power_domain_tree_desc[i + 1] =
UNIPHIER_MAX_CPUS_PER_CLUSTER;
return uniphier_power_domain_tree_desc;
}
int plat_core_pos_by_mpidr(u_register_t mpidr)
{
unsigned int cluster_id, cpu_id;
cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
if (cluster_id >= UNIPHIER_CLUSTER_COUNT)
return -1;
cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
if (cpu_id >= UNIPHIER_MAX_CPUS_PER_CLUSTER)
return -1;
return uniphier_calc_core_pos(mpidr);
}
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <assert.h>
#include <io/io_block.h>
#include <mmio.h>
#include <platform_def.h>
#include <sys/types.h>
#include <utils_def.h>
#include "uniphier.h"
#define UNIPHIER_LD11_USB_DESC_BASE 0x30010000
#define UNIPHIER_LD20_USB_DESC_BASE 0x30014000
#define UNIPHIER_SRB_OCM_CONT 0x61200000
struct uniphier_ld11_trans_op {
uint8_t __pad[48];
};
struct uniphier_ld11_op {
uint8_t __pad[56];
struct uniphier_ld11_trans_op *trans_op;
void *__pad2;
void *dev_desc;
};
struct uniphier_ld20_trans_op {
uint8_t __pad[40];
};
struct uniphier_ld20_op {
uint8_t __pad[192];
struct uniphier_ld20_trans_op *trans_op;
void *__pad2;
void *dev_desc;
};
static int (*__uniphier_usb_read)(int lba, uintptr_t buf, size_t size);
static void uniphier_ld11_usb_init(void)
{
struct uniphier_ld11_op *op = (void *)UNIPHIER_LD11_USB_DESC_BASE;
op->trans_op = (void *)(op + 1);
op->dev_desc = op->trans_op + 1;
}
static int uniphier_ld11_usb_read(int lba, uintptr_t buf, size_t size)
{
static int (*rom_usb_read)(uintptr_t desc, unsigned int lba,
unsigned int size, uintptr_t buf);
uintptr_t func_addr;
func_addr = uniphier_get_soc_revision() == 1 ? 0x3880 : 0x3958;
rom_usb_read = (__typeof(rom_usb_read))func_addr;
return rom_usb_read(UNIPHIER_LD11_USB_DESC_BASE, lba, size, buf);
}
static void uniphier_ld20_usb_init(void)
{
struct uniphier_ld20_op *op = (void *)UNIPHIER_LD20_USB_DESC_BASE;
op->trans_op = (void *)(op + 1);
op->dev_desc = op->trans_op + 1;
}
static int uniphier_ld20_usb_read(int lba, uintptr_t buf, size_t size)
{
static int (*rom_usb_read)(uintptr_t desc, unsigned int lba,
unsigned int size, uintptr_t buf);
int ret;
rom_usb_read = (__typeof(rom_usb_read))0x37f0;
mmio_write_32(UNIPHIER_SRB_OCM_CONT, 0x1ff);
/* ROM-API - return 1 on success, 0 on error */
ret = rom_usb_read(UNIPHIER_LD20_USB_DESC_BASE, lba, size, buf);
mmio_write_32(UNIPHIER_SRB_OCM_CONT, 0);
return ret ? 0 : -1;
}
static int uniphier_pxs3_usb_read(int lba, uintptr_t buf, size_t size)
{
static int (*rom_usb_read)(unsigned int lba, unsigned int size,
uintptr_t buf);
rom_usb_read = (__typeof(rom_usb_read))0x100c;
return rom_usb_read(lba, size, buf);
}
struct uniphier_usb_rom_param {
void (*init)(void);
int (*read)(int lba, uintptr_t buf, size_t size);
};
static const struct uniphier_usb_rom_param uniphier_usb_rom_params[] = {
[UNIPHIER_SOC_LD11] = {
.init = uniphier_ld11_usb_init,
.read = uniphier_ld11_usb_read,
},
[UNIPHIER_SOC_LD20] = {
.init = uniphier_ld20_usb_init,
.read = uniphier_ld20_usb_read,
},
[UNIPHIER_SOC_PXS3] = {
.read = uniphier_pxs3_usb_read,
},
};
static size_t uniphier_usb_read(int lba, uintptr_t buf, size_t size)
{
int ret;
inv_dcache_range(buf, size);
ret = __uniphier_usb_read(lba, buf, size);
inv_dcache_range(buf, size);
return ret ? 0 : size;
}
static struct io_block_dev_spec uniphier_usb_dev_spec = {
.buffer = {
.offset = UNIPHIER_BLOCK_BUF_BASE,
.length = UNIPHIER_BLOCK_BUF_SIZE,
},
.ops = {
.read = uniphier_usb_read,
},
.block_size = 512,
};
int uniphier_usb_init(unsigned int soc, uintptr_t *block_dev_spec)
{
const struct uniphier_usb_rom_param *param;
assert(soc < ARRAY_SIZE(uniphier_usb_rom_params));
param = &uniphier_usb_rom_params[soc];
if (param->init)
param->init();
__uniphier_usb_read = param->read;
*block_dev_spec = (uintptr_t)&uniphier_usb_dev_spec;
return 0;
}
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <debug.h>
#include <platform_def.h>
#include <xlat_tables_v2.h>
#define UNIPHIER_OCM_REGION_BASE 0x30000000
#define UNIPHIER_OCM_REGION_SIZE 0x00040000
#define UNIPHIER_REG_REGION_BASE 0x50000000
#define UNIPHIER_REG_REGION_SIZE 0x20000000
void uniphier_mmap_setup(uintptr_t total_base, size_t total_size,
const struct mmap_region *mmap)
{
VERBOSE("Trusted RAM seen by this BL image: %p - %p\n",
(void *)total_base, (void *)(total_base + total_size));
mmap_add_region(total_base, total_base,
total_size,
MT_MEMORY | MT_RW | MT_SECURE);
/* remap the code section */
VERBOSE("Code region: %p - %p\n",
(void *)BL_CODE_BASE, (void *)BL_CODE_END);
mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
round_up(BL_CODE_END, PAGE_SIZE) - BL_CODE_BASE,
MT_CODE | MT_SECURE);
/* remap the coherent memory region */
VERBOSE("Coherent region: %p - %p\n",
(void *)BL_COHERENT_RAM_BASE, (void *)BL_COHERENT_RAM_END);
mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE,
BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
MT_DEVICE | MT_RW | MT_SECURE);
/*
* on-chip SRAM region: should be DEVICE attribute because the USB
* load functions provided by the ROM use this memory region as a work
* area, but do not cater to cache coherency.
*/
mmap_add_region(UNIPHIER_OCM_REGION_BASE, UNIPHIER_OCM_REGION_BASE,
UNIPHIER_OCM_REGION_SIZE,
MT_DEVICE | MT_RW | MT_SECURE);
/* register region */
mmap_add_region(UNIPHIER_REG_REGION_BASE, UNIPHIER_REG_REGION_BASE,
UNIPHIER_REG_REGION_SIZE,
MT_DEVICE | MT_RW | MT_SECURE);
/* additional regions if needed */
if (mmap)
mmap_add(mmap);
init_xlat_tables();
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment