Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
Arm Trusted Firmware
Commits
1502c4e1
Commit
1502c4e1
authored
Jun 13, 2017
by
davidcunado-arm
Committed by
GitHub
Jun 13, 2017
Browse files
Merge pull request #974 from masahir0y/uniphier
UniPhier Initial Support
parents
42fb35a8
63b3a28e
Changes
30
Show whitespace changes
Inline
Side-by-side
plat/socionext/uniphier/uniphier_nand.c
0 → 100644
View file @
1502c4e1
/*
* 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
;
}
plat/socionext/uniphier/uniphier_psci.c
0 → 100644
View file @
1502c4e1
/*
* 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
;
}
plat/socionext/uniphier/uniphier_scp.c
0 → 100644
View file @
1502c4e1
/*
* 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
)
plat/socionext/uniphier/uniphier_smp.S
0 → 100644
View file @
1502c4e1
/*
*
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
1
f
0
:
wfe
1
:
ldr
x1
,
uniphier_holding_pen_release
cmp
x1
,
x0
b.ne
0
b
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
plat/socionext/uniphier/uniphier_soc_info.c
0 → 100644
View file @
1502c4e1
/*
* 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
;
}
}
plat/socionext/uniphier/uniphier_syscnt.c
0 → 100644
View file @
1502c4e1
/*
* 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
;
}
plat/socionext/uniphier/uniphier_tbbr.c
0 → 100644
View file @
1502c4e1
/*
* 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
;
}
plat/socionext/uniphier/uniphier_topology.c
0 → 100644
View file @
1502c4e1
/*
* 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
);
}
plat/socionext/uniphier/uniphier_usb.c
0 → 100644
View file @
1502c4e1
/*
* 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
;
}
plat/socionext/uniphier/uniphier_xlat_setup.c
0 → 100644
View file @
1502c4e1
/*
* 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
();
}
Prev
1
2
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment