Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
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
b514ee86
Commit
b514ee86
authored
5 years ago
by
Soby Mathew
Committed by
TrustedFirmware Code Review
5 years ago
Browse files
Options
Download
Plain Diff
Merge "intel: Adds support for Agilex platform" into integration
parents
59e3df6e
2f11d548
master
v2.5
v2.5-rc1
v2.5-rc0
v2.4
v2.4-rc2
v2.4-rc1
v2.4-rc0
v2.3
v2.3-rc2
v2.3-rc1
v2.3-rc0
v2.2
v2.2-rc2
v2.2-rc1
v2.2-rc0
arm_cca_v0.2
arm_cca_v0.1
No related merge requests found
Changes
33
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
plat/intel/soc/agilex/soc/agilex_clock_manager.c
+293
-0
plat/intel/soc/agilex/soc/agilex_clock_manager.c
plat/intel/soc/agilex/soc/agilex_handoff.c
+40
-0
plat/intel/soc/agilex/soc/agilex_handoff.c
plat/intel/soc/agilex/soc/agilex_mailbox.c
+280
-0
plat/intel/soc/agilex/soc/agilex_mailbox.c
plat/intel/soc/agilex/soc/agilex_memory_controller.c
+395
-0
plat/intel/soc/agilex/soc/agilex_memory_controller.c
plat/intel/soc/agilex/soc/agilex_pinmux.c
+217
-0
plat/intel/soc/agilex/soc/agilex_pinmux.c
plat/intel/soc/agilex/soc/agilex_reset_manager.c
+82
-0
plat/intel/soc/agilex/soc/agilex_reset_manager.c
plat/intel/soc/agilex/soc/agilex_system_manager.c
+93
-0
plat/intel/soc/agilex/soc/agilex_system_manager.c
plat/intel/soc/agilex/socfpga_delay_timer.c
+39
-0
plat/intel/soc/agilex/socfpga_delay_timer.c
plat/intel/soc/agilex/socfpga_image_load.c
+32
-0
plat/intel/soc/agilex/socfpga_image_load.c
plat/intel/soc/agilex/socfpga_psci.c
+204
-0
plat/intel/soc/agilex/socfpga_psci.c
plat/intel/soc/agilex/socfpga_sip_svc.c
+378
-0
plat/intel/soc/agilex/socfpga_sip_svc.c
plat/intel/soc/agilex/socfpga_storage.c
+193
-0
plat/intel/soc/agilex/socfpga_storage.c
plat/intel/soc/agilex/socfpga_topology.c
+51
-0
plat/intel/soc/agilex/socfpga_topology.c
with
2297 additions
and
0 deletions
+2297
-0
plat/intel/soc/agilex/soc/agilex_clock_manager.c
0 → 100644
View file @
b514ee86
/*
* Copyright (c) 2019, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <common/debug.h>
#include <drivers/delay_timer.h>
#include <errno.h>
#include <lib/mmio.h>
#include "agilex_clock_manager.h"
#include "agilex_handoff.h"
static
const
CLOCK_SOURCE_CONFIG
clk_source
=
{
/* clk_freq_of_eosc1 */
(
uint32_t
)
25000000
,
/* clk_freq_of_f2h_free */
(
uint32_t
)
400000000
,
/* clk_freq_of_cb_intosc_ls */
(
uint32_t
)
50000000
,
};
uint32_t
wait_pll_lock
(
void
)
{
uint32_t
data
;
uint32_t
count
=
0
;
do
{
data
=
mmio_read_32
(
CLKMGR_OFFSET
+
CLKMGR_STAT
);
count
++
;
if
(
count
>=
1000
)
return
-
ETIMEDOUT
;
}
while
((
CLKMGR_STAT_MAINPLLLOCKED
(
data
)
==
0
)
||
(
CLKMGR_STAT_PERPLLLOCKED
(
data
)
==
0
));
return
0
;
}
uint32_t
wait_fsm
(
void
)
{
uint32_t
data
;
uint32_t
count
=
0
;
do
{
data
=
mmio_read_32
(
CLKMGR_OFFSET
+
CLKMGR_STAT
);
count
++
;
if
(
count
>=
1000
)
return
-
ETIMEDOUT
;
}
while
(
CLKMGR_STAT_BUSY
(
data
)
==
CLKMGR_STAT_BUSY_E_BUSY
);
return
0
;
}
uint32_t
pll_source_sync_config
(
uint32_t
pll_mem_offset
)
{
uint32_t
val
=
0
;
uint32_t
count
=
0
;
uint32_t
req_status
=
0
;
val
=
(
CLKMGR_MEM_WR
|
CLKMGR_MEM_REQ
|
CLKMGR_MEM_WDAT
<<
CLKMGR_MEM_WDAT_OFFSET
|
CLKMGR_MEM_ADDR
);
mmio_write_32
(
pll_mem_offset
,
val
);
do
{
req_status
=
mmio_read_32
(
pll_mem_offset
);
count
++
;
}
while
((
req_status
&
CLKMGR_MEM_REQ
)
&&
(
count
<
10
));
if
(
count
>=
100
)
return
-
ETIMEDOUT
;
return
0
;
}
uint32_t
pll_source_sync_read
(
uint32_t
pll_mem_offset
)
{
uint32_t
val
=
0
;
uint32_t
rdata
=
0
;
uint32_t
count
=
0
;
uint32_t
req_status
=
0
;
val
=
(
CLKMGR_MEM_REQ
|
CLKMGR_MEM_ADDR
);
mmio_write_32
(
pll_mem_offset
,
val
);
do
{
req_status
=
mmio_read_32
(
pll_mem_offset
);
count
++
;
}
while
((
req_status
&
CLKMGR_MEM_REQ
)
&&
(
count
<
10
));
if
(
count
>=
100
)
return
-
ETIMEDOUT
;
rdata
=
mmio_read_32
(
pll_mem_offset
+
0x4
);
INFO
(
"rdata (%x) = %x
\n
"
,
pll_mem_offset
+
0x4
,
rdata
);
return
0
;
}
void
config_clkmgr_handoff
(
handoff
*
hoff_ptr
)
{
uint32_t
mdiv
,
mscnt
,
hscnt
;
uint32_t
arefclk_div
,
drefclk_div
;
/* Bypass all mainpllgrp's clocks */
mmio_write_32
(
CLKMGR_MAINPLL
+
CLKMGR_MAINPLL_BYPASS
,
0x7
);
wait_fsm
();
/* Bypass all perpllgrp's clocks */
mmio_write_32
(
CLKMGR_PERPLL
+
CLKMGR_PERPLL_BYPASS
,
0x7f
);
wait_fsm
();
/* Put both PLL in reset and power down */
mmio_clrbits_32
(
CLKMGR_MAINPLL
+
CLKMGR_MAINPLL_PLLGLOB
,
CLKMGR_MAINPLL_PLLGLOB_PD_SET_MSK
|
CLKMGR_MAINPLL_PLLGLOB_RST_SET_MSK
);
mmio_clrbits_32
(
CLKMGR_PERPLL
+
CLKMGR_PERPLL_PLLGLOB
,
CLKMGR_PERPLL_PLLGLOB_PD_SET_MSK
|
CLKMGR_PERPLL_PLLGLOB_RST_SET_MSK
);
/* Setup main PLL dividers */
mdiv
=
CLKMGR_MAINPLL_PLLM_MDIV
(
hoff_ptr
->
main_pll_pllm
);
arefclk_div
=
CLKMGR_MAINPLL_PLLGLOB_AREFCLKDIV
(
hoff_ptr
->
main_pll_pllglob
);
drefclk_div
=
CLKMGR_MAINPLL_PLLGLOB_DREFCLKDIV
(
hoff_ptr
->
main_pll_pllglob
);
mscnt
=
100
/
(
mdiv
/
BIT
(
drefclk_div
));
if
(
!
mscnt
)
mscnt
=
1
;
hscnt
=
(
mdiv
*
mscnt
*
BIT
(
drefclk_div
)
/
arefclk_div
)
-
4
;
mmio_write_32
(
CLKMGR_MAINPLL
+
CLKMGR_MAINPLL_VCOCALIB
,
CLKMGR_MAINPLL_VCOCALIB_HSCNT_SET
(
hscnt
)
|
CLKMGR_MAINPLL_VCOCALIB_MSCNT_SET
(
mscnt
));
mmio_write_32
(
CLKMGR_MAINPLL
+
CLKMGR_MAINPLL_NOCDIV
,
hoff_ptr
->
main_pll_nocdiv
);
mmio_write_32
(
CLKMGR_MAINPLL
+
CLKMGR_MAINPLL_PLLGLOB
,
hoff_ptr
->
main_pll_pllglob
);
mmio_write_32
(
CLKMGR_MAINPLL
+
CLKMGR_MAINPLL_FDBCK
,
hoff_ptr
->
main_pll_fdbck
);
mmio_write_32
(
CLKMGR_MAINPLL
+
CLKMGR_MAINPLL_PLLC0
,
hoff_ptr
->
main_pll_pllc0
);
mmio_write_32
(
CLKMGR_MAINPLL
+
CLKMGR_MAINPLL_PLLC1
,
hoff_ptr
->
main_pll_pllc1
);
mmio_write_32
(
CLKMGR_MAINPLL
+
CLKMGR_MAINPLL_PLLC2
,
hoff_ptr
->
main_pll_pllc2
);
mmio_write_32
(
CLKMGR_MAINPLL
+
CLKMGR_MAINPLL_PLLC3
,
hoff_ptr
->
main_pll_pllc3
);
mmio_write_32
(
CLKMGR_MAINPLL
+
CLKMGR_MAINPLL_PLLM
,
hoff_ptr
->
main_pll_pllm
);
mmio_write_32
(
CLKMGR_MAINPLL
+
CLKMGR_MAINPLL_MPUCLK
,
hoff_ptr
->
main_pll_mpuclk
);
mmio_write_32
(
CLKMGR_MAINPLL
+
CLKMGR_MAINPLL_NOCCLK
,
hoff_ptr
->
main_pll_nocclk
);
/* Setup peripheral PLL dividers */
mdiv
=
CLKMGR_PERPLL_PLLM_MDIV
(
hoff_ptr
->
per_pll_pllm
);
arefclk_div
=
CLKMGR_PERPLL_PLLGLOB_AREFCLKDIV
(
hoff_ptr
->
per_pll_pllglob
);
drefclk_div
=
CLKMGR_PERPLL_PLLGLOB_DREFCLKDIV
(
hoff_ptr
->
per_pll_pllglob
);
mscnt
=
100
/
(
mdiv
/
BIT
(
drefclk_div
));
if
(
!
mscnt
)
mscnt
=
1
;
hscnt
=
(
mdiv
*
mscnt
*
BIT
(
drefclk_div
)
/
arefclk_div
)
-
4
;
mmio_write_32
(
CLKMGR_PERPLL
+
CLKMGR_PERPLL_VCOCALIB
,
CLKMGR_PERPLL_VCOCALIB_HSCNT_SET
(
hscnt
)
|
CLKMGR_PERPLL_VCOCALIB_MSCNT_SET
(
mscnt
));
mmio_write_32
(
CLKMGR_PERPLL
+
CLKMGR_PERPLL_EMACCTL
,
hoff_ptr
->
per_pll_emacctl
);
mmio_write_32
(
CLKMGR_PERPLL
+
CLKMGR_PERPLL_GPIODIV
,
CLKMGR_PERPLL_GPIODIV_GPIODBCLK_SET
(
hoff_ptr
->
per_pll_gpiodiv
));
mmio_write_32
(
CLKMGR_PERPLL
+
CLKMGR_PERPLL_PLLGLOB
,
hoff_ptr
->
per_pll_pllglob
);
mmio_write_32
(
CLKMGR_PERPLL
+
CLKMGR_PERPLL_FDBCK
,
hoff_ptr
->
per_pll_fdbck
);
mmio_write_32
(
CLKMGR_PERPLL
+
CLKMGR_PERPLL_PLLC0
,
hoff_ptr
->
per_pll_pllc0
);
mmio_write_32
(
CLKMGR_PERPLL
+
CLKMGR_PERPLL_PLLC1
,
hoff_ptr
->
per_pll_pllc1
);
mmio_write_32
(
CLKMGR_PERPLL
+
CLKMGR_PERPLL_PLLC2
,
hoff_ptr
->
per_pll_pllc2
);
mmio_write_32
(
CLKMGR_PERPLL
+
CLKMGR_PERPLL_PLLC3
,
hoff_ptr
->
per_pll_pllc3
);
mmio_write_32
(
CLKMGR_PERPLL
+
CLKMGR_PERPLL_PLLM
,
hoff_ptr
->
per_pll_pllm
);
/* Take both PLL out of reset and power up */
mmio_setbits_32
(
CLKMGR_MAINPLL
+
CLKMGR_MAINPLL_PLLGLOB
,
CLKMGR_MAINPLL_PLLGLOB_PD_SET_MSK
|
CLKMGR_MAINPLL_PLLGLOB_RST_SET_MSK
);
mmio_setbits_32
(
CLKMGR_PERPLL
+
CLKMGR_PERPLL_PLLGLOB
,
CLKMGR_PERPLL_PLLGLOB_PD_SET_MSK
|
CLKMGR_PERPLL_PLLGLOB_RST_SET_MSK
);
wait_pll_lock
();
pll_source_sync_config
(
CLKMGR_MAINPLL
+
CLKMGR_MAINPLL_MEM
);
pll_source_sync_read
(
CLKMGR_MAINPLL
+
CLKMGR_MAINPLL_MEM
);
pll_source_sync_config
(
CLKMGR_PERPLL
+
CLKMGR_PERPLL_MEM
);
pll_source_sync_read
(
CLKMGR_PERPLL
+
CLKMGR_PERPLL_MEM
);
/*Configure Ping Pong counters in altera group */
mmio_write_32
(
CLKMGR_ALTERA
+
CLKMGR_ALTERA_EMACACTR
,
hoff_ptr
->
alt_emacactr
);
mmio_write_32
(
CLKMGR_ALTERA
+
CLKMGR_ALTERA_EMACBCTR
,
hoff_ptr
->
alt_emacbctr
);
mmio_write_32
(
CLKMGR_ALTERA
+
CLKMGR_ALTERA_EMACPTPCTR
,
hoff_ptr
->
alt_emacptpctr
);
mmio_write_32
(
CLKMGR_ALTERA
+
CLKMGR_ALTERA_GPIODBCTR
,
hoff_ptr
->
alt_gpiodbctr
);
mmio_write_32
(
CLKMGR_ALTERA
+
CLKMGR_ALTERA_SDMMCCTR
,
hoff_ptr
->
alt_sdmmcctr
);
mmio_write_32
(
CLKMGR_ALTERA
+
CLKMGR_ALTERA_S2FUSER0CTR
,
hoff_ptr
->
alt_s2fuser0ctr
);
mmio_write_32
(
CLKMGR_ALTERA
+
CLKMGR_ALTERA_S2FUSER1CTR
,
hoff_ptr
->
alt_s2fuser1ctr
);
mmio_write_32
(
CLKMGR_ALTERA
+
CLKMGR_ALTERA_PSIREFCTR
,
hoff_ptr
->
alt_psirefctr
);
/* Take all PLLs out of bypass */
mmio_write_32
(
CLKMGR_MAINPLL
+
CLKMGR_MAINPLL_BYPASS
,
0
);
wait_fsm
();
mmio_write_32
(
CLKMGR_PERPLL
+
CLKMGR_PERPLL_BYPASS
,
0
);
wait_fsm
();
/* Clear loss lock interrupt status register that */
/* might be set during configuration */
mmio_setbits_32
(
CLKMGR_OFFSET
+
CLKMGR_INTRCLR
,
CLKMGR_INTRCLR_MAINLOCKLOST_SET_MSK
|
CLKMGR_INTRCLR_PERLOCKLOST_SET_MSK
);
/* Take all ping pong counters out of reset */
mmio_clrbits_32
(
CLKMGR_ALTERA
+
CLKMGR_ALTERA_EXTCNTRST
,
CLKMGR_ALTERA_EXTCNTRST_RESET
);
/* Set safe mode / out of boot mode */
mmio_clrbits_32
(
CLKMGR_OFFSET
+
CLKMGR_CTRL
,
CLKMGR_CTRL_BOOTMODE_SET_MSK
);
wait_fsm
();
/* Enable mainpllgrp's software-managed clock */
mmio_write_32
(
CLKMGR_MAINPLL
+
CLKMGR_MAINPLL_EN
,
CLKMGR_MAINPLL_EN_RESET
);
mmio_write_32
(
CLKMGR_PERPLL
+
CLKMGR_PERPLL_EN
,
CLKMGR_PERPLL_EN_RESET
);
}
int
get_wdt_clk
(
handoff
*
hoff_ptr
)
{
int
main_noc_base_clk
,
l3_main_free_clk
,
l4_sys_free_clk
;
int
data32
,
mdiv
,
arefclkdiv
,
ref_clk
;
data32
=
mmio_read_32
(
CLKMGR_MAINPLL
+
CLKMGR_MAINPLL_PLLGLOB
);
switch
(
CLKMGR_MAINPLL_PLLGLOB_PSRC
(
data32
))
{
case
CLKMGR_MAINPLL_PLLGLOB_PSRC_EOSC1
:
ref_clk
=
clk_source
.
clk_freq_of_eosc1
;
break
;
case
CLKMGR_MAINPLL_PLLGLOB_PSRC_INTOSC
:
ref_clk
=
clk_source
.
clk_freq_of_cb_intosc_ls
;
break
;
case
CLKMGR_MAINPLL_PLLGLOB_PSRC_F2S
:
ref_clk
=
clk_source
.
clk_freq_of_f2h_free
;
break
;
default:
ref_clk
=
0
;
assert
(
0
);
break
;
}
arefclkdiv
=
CLKMGR_MAINPLL_PLLGLOB_AREFCLKDIV
(
data32
);
mdiv
=
CLKMGR_MAINPLL_PLLM_MDIV
(
hoff_ptr
->
main_pll_pllm
);
ref_clk
=
(
ref_clk
/
arefclkdiv
)
*
mdiv
;
main_noc_base_clk
=
ref_clk
/
(
hoff_ptr
->
main_pll_pllc1
&
0x7ff
);
l3_main_free_clk
=
main_noc_base_clk
/
(
hoff_ptr
->
main_pll_nocclk
+
1
);
l4_sys_free_clk
=
l3_main_free_clk
/
4
;
return
l4_sys_free_clk
;
}
This diff is collapsed.
Click to expand it.
plat/intel/soc/agilex/soc/agilex_handoff.c
0 → 100644
View file @
b514ee86
/*
* Copyright (c) 2019, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <platform_def.h>
#include <string.h>
#include "agilex_handoff.h"
#define SWAP_UINT32(x) (((x) >> 24) | (((x) & 0x00FF0000) >> 8) | \
(((x) & 0x0000FF00) << 8) | ((x) << 24))
int
agilex_get_handoff
(
handoff
*
reverse_hoff_ptr
)
{
int
i
;
uint32_t
*
buffer
;
handoff
*
handoff_ptr
=
(
handoff
*
)
PLAT_HANDOFF_OFFSET
;
memcpy
(
reverse_hoff_ptr
,
handoff_ptr
,
sizeof
(
handoff
));
buffer
=
(
uint32_t
*
)
reverse_hoff_ptr
;
/* convert big endian to little endian */
for
(
i
=
0
;
i
<
sizeof
(
handoff
)
/
4
;
i
++
)
buffer
[
i
]
=
SWAP_UINT32
(
buffer
[
i
]);
if
(
reverse_hoff_ptr
->
header_magic
!=
HANDOFF_MAGIC_HEADER
)
return
-
1
;
if
(
reverse_hoff_ptr
->
pinmux_sel_magic
!=
HANDOFF_MAGIC_PINMUX_SEL
)
return
-
1
;
if
(
reverse_hoff_ptr
->
pinmux_io_magic
!=
HANDOFF_MAGIC_IOCTLR
)
return
-
1
;
if
(
reverse_hoff_ptr
->
pinmux_fpga_magic
!=
HANDOFF_MAGIC_FPGA
)
return
-
1
;
if
(
reverse_hoff_ptr
->
pinmux_delay_magic
!=
HANDOFF_MAGIC_IODELAY
)
return
-
1
;
return
0
;
}
This diff is collapsed.
Click to expand it.
plat/intel/soc/agilex/soc/agilex_mailbox.c
0 → 100644
View file @
b514ee86
/*
* Copyright (c) 2019, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <lib/mmio.h>
#include <common/debug.h>
#include "agilex_mailbox.h"
static
int
fill_mailbox_circular_buffer
(
uint32_t
header_cmd
,
uint32_t
*
args
,
int
len
)
{
uint32_t
cmd_free_offset
;
int
i
;
cmd_free_offset
=
mmio_read_32
(
MBOX_OFFSET
+
MBOX_CIN
);
if
(
cmd_free_offset
>=
MBOX_CMD_BUFFER_SIZE
)
{
INFO
(
"Insufficient buffer in mailbox
\n
"
);
return
MBOX_INSUFFICIENT_BUFFER
;
}
mmio_write_32
(
MBOX_OFFSET
+
MBOX_CMD_BUFFER
+
(
cmd_free_offset
++
*
4
),
header_cmd
);
for
(
i
=
0
;
i
<
len
;
i
++
)
{
cmd_free_offset
%=
MBOX_CMD_BUFFER_SIZE
;
mmio_write_32
(
MBOX_OFFSET
+
MBOX_CMD_BUFFER
+
(
cmd_free_offset
++
*
4
),
args
[
i
]);
}
cmd_free_offset
%=
MBOX_CMD_BUFFER_SIZE
;
mmio_write_32
(
MBOX_OFFSET
+
MBOX_CIN
,
cmd_free_offset
);
return
0
;
}
int
mailbox_read_response
(
int
job_id
,
uint32_t
*
response
)
{
int
rin
=
0
;
int
rout
=
0
;
int
response_length
=
0
;
int
resp
=
0
;
int
total_resp_len
=
0
;
int
timeout
=
100000
;
mmio_write_32
(
MBOX_OFFSET
+
MBOX_DOORBELL_TO_SDM
,
1
);
while
(
mmio_read_32
(
MBOX_OFFSET
+
MBOX_DOORBELL_FROM_SDM
)
!=
1
)
{
if
(
timeout
--
<
0
)
return
MBOX_NO_RESPONSE
;
}
mmio_write_32
(
MBOX_OFFSET
+
MBOX_DOORBELL_FROM_SDM
,
0
);
rin
=
mmio_read_32
(
MBOX_OFFSET
+
MBOX_RIN
);
rout
=
mmio_read_32
(
MBOX_OFFSET
+
MBOX_ROUT
);
while
(
rout
!=
rin
)
{
resp
=
mmio_read_32
(
MBOX_OFFSET
+
MBOX_RESP_BUFFER
+
((
rout
++
)
*
4
));
rout
%=
MBOX_RESP_BUFFER_SIZE
;
mmio_write_32
(
MBOX_OFFSET
+
MBOX_ROUT
,
rout
);
if
(
MBOX_RESP_CLIENT_ID
(
resp
)
!=
MBOX_ATF_CLIENT_ID
||
MBOX_RESP_JOB_ID
(
resp
)
!=
job_id
)
{
return
MBOX_WRONG_ID
;
}
if
(
MBOX_RESP_ERR
(
resp
)
>
0
)
{
INFO
(
"Error in response: %x
\n
"
,
resp
);
return
-
resp
;
}
response_length
=
MBOX_RESP_LEN
(
resp
);
while
(
response_length
)
{
response_length
--
;
resp
=
mmio_read_32
(
MBOX_OFFSET
+
MBOX_RESP_BUFFER
+
(
rout
)
*
4
);
if
(
response
)
{
*
(
response
+
total_resp_len
)
=
resp
;
total_resp_len
++
;
}
rout
++
;
rout
%=
MBOX_RESP_BUFFER_SIZE
;
mmio_write_32
(
MBOX_OFFSET
+
MBOX_ROUT
,
rout
);
}
return
total_resp_len
;
}
return
MBOX_NO_RESPONSE
;
}
int
mailbox_poll_response
(
int
job_id
,
int
urgent
,
uint32_t
*
response
)
{
int
timeout
=
80000
;
int
rin
=
0
;
int
rout
=
0
;
int
response_length
=
0
;
int
resp
=
0
;
int
total_resp_len
=
0
;
mmio_write_32
(
MBOX_OFFSET
+
MBOX_DOORBELL_TO_SDM
,
1
);
while
(
1
)
{
while
(
timeout
>
0
&&
mmio_read_32
(
MBOX_OFFSET
+
MBOX_DOORBELL_FROM_SDM
)
!=
1
)
{
timeout
--
;
}
if
(
mmio_read_32
(
MBOX_OFFSET
+
MBOX_DOORBELL_FROM_SDM
)
!=
1
)
{
INFO
(
"Timed out waiting for SDM"
);
return
MBOX_TIMEOUT
;
}
mmio_write_32
(
MBOX_OFFSET
+
MBOX_DOORBELL_FROM_SDM
,
0
);
if
(
urgent
&
1
)
{
if
((
mmio_read_32
(
MBOX_OFFSET
+
MBOX_STATUS
)
&
MBOX_STATUS_UA_MASK
)
^
(
urgent
&
MBOX_STATUS_UA_MASK
))
{
mmio_write_32
(
MBOX_OFFSET
+
MBOX_URG
,
0
);
return
0
;
}
mmio_write_32
(
MBOX_OFFSET
+
MBOX_URG
,
0
);
INFO
(
"Error: Mailbox did not get UA"
);
return
-
1
;
}
rin
=
mmio_read_32
(
MBOX_OFFSET
+
MBOX_RIN
);
rout
=
mmio_read_32
(
MBOX_OFFSET
+
MBOX_ROUT
);
while
(
rout
!=
rin
)
{
resp
=
mmio_read_32
(
MBOX_OFFSET
+
MBOX_RESP_BUFFER
+
((
rout
++
)
*
4
));
rout
%=
MBOX_RESP_BUFFER_SIZE
;
mmio_write_32
(
MBOX_OFFSET
+
MBOX_ROUT
,
rout
);
if
(
MBOX_RESP_CLIENT_ID
(
resp
)
!=
MBOX_ATF_CLIENT_ID
||
MBOX_RESP_JOB_ID
(
resp
)
!=
job_id
)
continue
;
if
(
MBOX_RESP_ERR
(
resp
)
>
0
)
{
INFO
(
"Error in response: %x
\n
"
,
resp
);
return
-
MBOX_RESP_ERR
(
resp
);
}
response_length
=
MBOX_RESP_LEN
(
resp
);
while
(
response_length
)
{
response_length
--
;
resp
=
mmio_read_32
(
MBOX_OFFSET
+
MBOX_RESP_BUFFER
+
(
rout
)
*
4
);
if
(
response
)
{
*
(
response
+
total_resp_len
)
=
resp
;
total_resp_len
++
;
}
rout
++
;
rout
%=
MBOX_RESP_BUFFER_SIZE
;
mmio_write_32
(
MBOX_OFFSET
+
MBOX_ROUT
,
rout
);
}
return
total_resp_len
;
}
}
}
void
mailbox_send_cmd_async
(
int
job_id
,
unsigned
int
cmd
,
uint32_t
*
args
,
int
len
,
int
urgent
)
{
if
(
urgent
)
mmio_write_32
(
MBOX_OFFSET
+
MBOX_URG
,
1
);
fill_mailbox_circular_buffer
(
MBOX_CLIENT_ID_CMD
(
MBOX_ATF_CLIENT_ID
)
|
MBOX_JOB_ID_CMD
(
job_id
)
|
MBOX_CMD_LEN_CMD
(
len
)
|
MBOX_INDIRECT
|
cmd
,
args
,
len
);
}
int
mailbox_send_cmd
(
int
job_id
,
unsigned
int
cmd
,
uint32_t
*
args
,
int
len
,
int
urgent
,
uint32_t
*
response
)
{
int
status
;
if
(
urgent
)
{
urgent
|=
mmio_read_32
(
MBOX_OFFSET
+
MBOX_STATUS
)
&
MBOX_STATUS_UA_MASK
;
mmio_write_32
(
MBOX_OFFSET
+
MBOX_URG
,
cmd
);
status
=
0
;
}
else
{
status
=
fill_mailbox_circular_buffer
(
MBOX_CLIENT_ID_CMD
(
MBOX_ATF_CLIENT_ID
)
|
MBOX_JOB_ID_CMD
(
job_id
)
|
cmd
,
args
,
len
);
}
if
(
status
)
return
status
;
return
mailbox_poll_response
(
job_id
,
urgent
,
response
);
}
void
mailbox_set_int
(
int
interrupt
)
{
mmio_write_32
(
MBOX_OFFSET
+
MBOX_INT
,
MBOX_COE_BIT
(
interrupt
)
|
MBOX_UAE_BIT
(
interrupt
));
}
void
mailbox_set_qspi_open
(
void
)
{
mailbox_set_int
(
MBOX_INT_FLAG_COE
|
MBOX_INT_FLAG_RIE
);
mailbox_send_cmd
(
MBOX_JOB_ID
,
MBOX_CMD_QSPI_OPEN
,
0
,
0
,
0
,
0
);
}
void
mailbox_set_qspi_direct
(
void
)
{
mailbox_send_cmd
(
MBOX_JOB_ID
,
MBOX_CMD_QSPI_DIRECT
,
0
,
0
,
0
,
0
);
}
void
mailbox_set_qspi_close
(
void
)
{
mailbox_set_int
(
MBOX_INT_FLAG_COE
|
MBOX_INT_FLAG_RIE
);
mailbox_send_cmd
(
MBOX_JOB_ID
,
MBOX_CMD_QSPI_CLOSE
,
0
,
0
,
0
,
0
);
}
int
mailbox_get_qspi_clock
(
void
)
{
mailbox_set_int
(
MBOX_INT_FLAG_COE
|
MBOX_INT_FLAG_RIE
);
return
mailbox_send_cmd
(
MBOX_JOB_ID
,
MBOX_CMD_QSPI_DIRECT
,
0
,
0
,
0
,
0
);
}
void
mailbox_qspi_set_cs
(
int
device_select
)
{
uint32_t
cs_setting
=
device_select
;
/* QSPI device select settings at 31:28 */
cs_setting
=
(
cs_setting
<<
28
);
mailbox_set_int
(
MBOX_INT_FLAG_COE
|
MBOX_INT_FLAG_RIE
);
mailbox_send_cmd
(
MBOX_JOB_ID
,
MBOX_CMD_QSPI_SET_CS
,
&
cs_setting
,
1
,
0
,
0
);
}
void
mailbox_reset_cold
(
void
)
{
mailbox_set_int
(
MBOX_INT_FLAG_COE
|
MBOX_INT_FLAG_RIE
);
mailbox_send_cmd
(
MBOX_JOB_ID
,
MBOX_CMD_REBOOT_HPS
,
0
,
0
,
0
,
0
);
}
int
mailbox_init
(
void
)
{
int
status
=
0
;
mailbox_set_int
(
MBOX_INT_FLAG_COE
|
MBOX_INT_FLAG_RIE
|
MBOX_INT_FLAG_UAE
);
mmio_write_32
(
MBOX_OFFSET
+
MBOX_URG
,
0
);
mmio_write_32
(
MBOX_OFFSET
+
MBOX_DOORBELL_FROM_SDM
,
0
);
status
=
mailbox_send_cmd
(
0
,
MBOX_CMD_RESTART
,
0
,
0
,
1
,
0
);
if
(
status
)
return
status
;
mailbox_set_int
(
MBOX_INT_FLAG_COE
|
MBOX_INT_FLAG_RIE
);
return
0
;
}
This diff is collapsed.
Click to expand it.
plat/intel/soc/agilex/soc/agilex_memory_controller.c
0 → 100644
View file @
b514ee86
/*
* Copyright (c) 2019, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <errno.h>
#include <lib/mmio.h>
#include <lib/utils.h>
#include <common/debug.h>
#include <drivers/delay_timer.h>
#include <platform_def.h>
#include "agilex_memory_controller.h"
#define ALT_CCU_NOC_DI_SET_MSK 0x10
#define DDR_READ_LATENCY_DELAY 40
#define MAX_MEM_CAL_RETRY 3
#define PRE_CALIBRATION_DELAY 1
#define POST_CALIBRATION_DELAY 1
#define TIMEOUT_EMIF_CALIBRATION 100
#define CLEAR_EMIF_DELAY 50000
#define CLEAR_EMIF_TIMEOUT 0x100000
#define TIMEOUT_INT_RESP 10000
#define DDR_CONFIG(A, B, C, R) (((A) << 24) | ((B) << 16) | ((C) << 8) | (R))
#define DDR_CONFIG_ELEMENTS (sizeof(ddr_config)/sizeof(uint32_t))
/* tWR = Min. 15ns constant, see JEDEC standard eg. DDR4 is JESD79-4.pdf */
#define tWR_IN_NS 15
void
configure_hmc_adaptor_regs
(
void
);
void
configure_ddr_sched_ctrl_regs
(
void
);
/* The followring are the supported configurations */
uint32_t
ddr_config
[]
=
{
/* DDR_CONFIG(Address order,Bank,Column,Row) */
/* List for DDR3 or LPDDR3 (pinout order > chip, row, bank, column) */
DDR_CONFIG
(
0
,
3
,
10
,
12
),
DDR_CONFIG
(
0
,
3
,
9
,
13
),
DDR_CONFIG
(
0
,
3
,
10
,
13
),
DDR_CONFIG
(
0
,
3
,
9
,
14
),
DDR_CONFIG
(
0
,
3
,
10
,
14
),
DDR_CONFIG
(
0
,
3
,
10
,
15
),
DDR_CONFIG
(
0
,
3
,
11
,
14
),
DDR_CONFIG
(
0
,
3
,
11
,
15
),
DDR_CONFIG
(
0
,
3
,
10
,
16
),
DDR_CONFIG
(
0
,
3
,
11
,
16
),
DDR_CONFIG
(
0
,
3
,
12
,
15
),
/* 0xa */
/* List for DDR4 only (pinout order > chip, bank, row, column) */
DDR_CONFIG
(
1
,
3
,
10
,
14
),
DDR_CONFIG
(
1
,
4
,
10
,
14
),
DDR_CONFIG
(
1
,
3
,
10
,
15
),
DDR_CONFIG
(
1
,
4
,
10
,
15
),
DDR_CONFIG
(
1
,
3
,
10
,
16
),
DDR_CONFIG
(
1
,
4
,
10
,
16
),
DDR_CONFIG
(
1
,
3
,
10
,
17
),
DDR_CONFIG
(
1
,
4
,
10
,
17
),
};
static
int
match_ddr_conf
(
uint32_t
ddr_conf
)
{
int
i
;
for
(
i
=
0
;
i
<
DDR_CONFIG_ELEMENTS
;
i
++
)
{
if
(
ddr_conf
==
ddr_config
[
i
])
return
i
;
}
return
0
;
}
static
int
check_hmc_clk
(
void
)
{
unsigned
long
timeout
=
0
;
uint32_t
hmc_clk
;
do
{
hmc_clk
=
mmio_read_32
(
AGX_SYSMGR_CORE_HMC_CLK
);
if
(
hmc_clk
&
AGX_SYSMGR_CORE_HMC_CLK_STATUS
)
break
;
udelay
(
1
);
}
while
(
++
timeout
<
1000
);
if
(
timeout
>=
1000
)
return
-
ETIMEDOUT
;
return
0
;
}
static
int
clear_emif
(
void
)
{
uint32_t
data
;
unsigned
long
timeout
;
mmio_write_32
(
AGX_MPFE_HMC_ADP_RSTHANDSHAKECTRL
,
0
);
timeout
=
0
;
do
{
data
=
mmio_read_32
(
AGX_MPFE_HMC_ADP_RSTHANDSHAKESTAT
);
if
((
data
&
AGX_MPFE_HMC_ADP_RSTHANDSHAKESTAT_SEQ2CORE
)
==
0
)
break
;
udelay
(
CLEAR_EMIF_DELAY
);
}
while
(
++
timeout
<
CLEAR_EMIF_TIMEOUT
);
if
(
timeout
>=
CLEAR_EMIF_TIMEOUT
)
return
-
ETIMEDOUT
;
return
0
;
}
static
int
mem_calibration
(
void
)
{
int
status
=
0
;
uint32_t
data
;
unsigned
long
timeout
;
unsigned
long
retry
=
0
;
udelay
(
PRE_CALIBRATION_DELAY
);
do
{
if
(
retry
!=
0
)
INFO
(
"DDR: Retrying DRAM calibration
\n
"
);
timeout
=
0
;
do
{
data
=
mmio_read_32
(
AGX_MPFE_HMC_ADP_DDRCALSTAT
);
if
(
AGX_MPFE_HMC_ADP_DDRCALSTAT_CAL
(
data
)
==
1
)
break
;
udelay
(
1
);
}
while
(
++
timeout
<
TIMEOUT_EMIF_CALIBRATION
);
if
(
AGX_MPFE_HMC_ADP_DDRCALSTAT_CAL
(
data
)
==
0
)
{
status
=
clear_emif
();
if
(
status
)
ERROR
(
"Failed to clear Emif
\n
"
);
}
else
{
break
;
}
}
while
(
++
retry
<
MAX_MEM_CAL_RETRY
);
if
(
AGX_MPFE_HMC_ADP_DDRCALSTAT_CAL
(
data
)
==
0
)
{
ERROR
(
"DDR: DRAM calibration failed.
\n
"
);
status
=
-
EIO
;
}
else
{
INFO
(
"DDR: DRAM calibration success.
\n
"
);
status
=
0
;
}
udelay
(
POST_CALIBRATION_DELAY
);
return
status
;
}
int
init_hard_memory_controller
(
void
)
{
int
status
;
status
=
check_hmc_clk
();
if
(
status
)
{
ERROR
(
"DDR: Error, HMC clock not running
\n
"
);
return
status
;
}
/* mmio_clrbits_32(AGX_RSTMGR_BRGMODRST, AGX_RSTMGR_BRGMODRST_DDRSCH);*/
status
=
mem_calibration
();
if
(
status
)
{
ERROR
(
"DDR: Memory Calibration Failed
\n
"
);
return
status
;
}
configure_hmc_adaptor_regs
();
/* configure_ddr_sched_ctrl_regs();*/
return
0
;
}
void
configure_ddr_sched_ctrl_regs
(
void
)
{
uint32_t
data
,
dram_addr_order
,
ddr_conf
,
bank
,
row
,
col
,
rd_to_miss
,
wr_to_miss
,
burst_len
,
burst_len_ddr_clk
,
burst_len_sched_clk
,
act_to_act
,
rd_to_wr
,
wr_to_rd
,
bw_ratio
,
t_rtp
,
t_rp
,
t_rcd
,
rd_latency
,
tw_rin_clk_cycles
,
bw_ratio_extended
,
auto_precharge
=
0
,
act_to_act_bank
,
faw
,
faw_bank
,
bus_rd_to_rd
,
bus_rd_to_wr
,
bus_wr_to_rd
;
INFO
(
"Init HPS NOC's DDR Scheduler.
\n
"
);
data
=
mmio_read_32
(
AGX_MPFE_IOHMC_CTRLCFG1
);
dram_addr_order
=
AGX_MPFE_IOHMC_CTRLCFG1_CFG_ADDR_ORDER
(
data
);
data
=
mmio_read_32
(
AGX_MPFE_IOHMC_DRAMADDRW
);
col
=
IOHMC_DRAMADDRW_COL_ADDR_WIDTH
(
data
);
row
=
IOHMC_DRAMADDRW_ROW_ADDR_WIDTH
(
data
);
bank
=
IOHMC_DRAMADDRW_BANK_ADDR_WIDTH
(
data
)
+
IOHMC_DRAMADDRW_BANK_GRP_ADDR_WIDTH
(
data
);
ddr_conf
=
match_ddr_conf
(
DDR_CONFIG
(
dram_addr_order
,
bank
,
col
,
row
));
if
(
ddr_conf
)
{
mmio_clrsetbits_32
(
AGX_MPFE_DDR_MAIN_SCHED_DDRCONF
,
AGX_MPFE_DDR_MAIN_SCHED_DDRCONF_SET_MSK
,
AGX_MPFE_DDR_MAIN_SCHED_DDRCONF_SET
(
ddr_conf
));
}
else
{
ERROR
(
"DDR: Cannot find predefined ddrConf configuration.
\n
"
);
}
mmio_write_32
(
AGX_MPFE_HMC_ADP
(
ADP_DRAMADDRWIDTH
),
data
);
data
=
mmio_read_32
(
AGX_MPFE_IOHMC_DRAMTIMING0
);
rd_latency
=
AGX_MPFE_IOHMC_REG_DRAMTIMING0_CFG_TCL
(
data
);
data
=
mmio_read_32
(
AGX_MPFE_IOHMC_CALTIMING0
);
act_to_act
=
ACT_TO_ACT
(
data
);
t_rcd
=
ACT_TO_RDWR
(
data
);
act_to_act_bank
=
ACT_TO_ACT_DIFF_BANK
(
data
);
data
=
mmio_read_32
(
AGX_MPFE_IOHMC_CALTIMING1
);
rd_to_wr
=
RD_TO_WR
(
data
);
bus_rd_to_rd
=
RD_TO_RD_DIFF_CHIP
(
data
);
bus_rd_to_wr
=
RD_TO_WR_DIFF_CHIP
(
data
);
data
=
mmio_read_32
(
AGX_MPFE_IOHMC_CALTIMING2
);
t_rtp
=
RD_TO_PCH
(
data
);
data
=
mmio_read_32
(
AGX_MPFE_IOHMC_CALTIMING3
);
wr_to_rd
=
CALTIMING3_WR_TO_RD
(
data
);
bus_wr_to_rd
=
CALTIMING3_WR_TO_RD_DIFF_CHIP
(
data
);
data
=
mmio_read_32
(
AGX_MPFE_IOHMC_CALTIMING4
);
t_rp
=
PCH_TO_VALID
(
data
);
data
=
mmio_read_32
(
AGX_MPFE_HMC_ADP
(
HMC_ADP_DDRIOCTRL
));
bw_ratio
=
((
HMC_ADP_DDRIOCTRL_IO_SIZE
(
data
)
==
0
)
?
0
:
1
);
data
=
mmio_read_32
(
AGX_MPFE_IOHMC_CTRLCFG0
);
burst_len
=
HMC_ADP_DDRIOCTRL_CTRL_BURST_LENGTH
(
data
);
burst_len_ddr_clk
=
burst_len
/
2
;
burst_len_sched_clk
=
((
burst_len
/
2
)
/
2
);
data
=
mmio_read_32
(
AGX_MPFE_IOHMC_CTRLCFG0
);
switch
(
AGX_MPFE_IOHMC_REG_CTRLCFG0_CFG_MEM_TYPE
(
data
))
{
case
1
:
/* DDR4 - 1333MHz */
/* 20 (19.995) clock cycles = 15ns */
/* Calculate with rounding */
tw_rin_clk_cycles
=
(((
tWR_IN_NS
*
1333
)
%
1000
)
>=
500
)
?
((
tWR_IN_NS
*
1333
)
/
1000
)
+
1
:
((
tWR_IN_NS
*
1333
)
/
1000
);
break
;
default:
/* Others - 1066MHz or slower */
/* 16 (15.990) clock cycles = 15ns */
/* Calculate with rounding */
tw_rin_clk_cycles
=
(((
tWR_IN_NS
*
1066
)
%
1000
)
>=
500
)
?
((
tWR_IN_NS
*
1066
)
/
1000
)
+
1
:
((
tWR_IN_NS
*
1066
)
/
1000
);
break
;
}
rd_to_miss
=
t_rtp
+
t_rp
+
t_rcd
-
burst_len_sched_clk
;
wr_to_miss
=
((
rd_latency
+
burst_len_ddr_clk
+
2
+
tw_rin_clk_cycles
)
/
2
)
-
rd_to_wr
+
t_rp
+
t_rcd
;
mmio_write_32
(
AGX_MPFE_DDR_MAIN_SCHED_DDRTIMING
,
bw_ratio
<<
DDRTIMING_BWRATIO_OFST
|
wr_to_rd
<<
DDRTIMING_WRTORD_OFST
|
rd_to_wr
<<
DDRTIMING_RDTOWR_OFST
|
burst_len_sched_clk
<<
DDRTIMING_BURSTLEN_OFST
|
wr_to_miss
<<
DDRTIMING_WRTOMISS_OFST
|
rd_to_miss
<<
DDRTIMING_RDTOMISS_OFST
|
act_to_act
<<
DDRTIMING_ACTTOACT_OFST
);
data
=
mmio_read_32
(
AGX_MPFE_HMC_ADP
(
HMC_ADP_DDRIOCTRL
));
bw_ratio_extended
=
((
ADP_DDRIOCTRL_IO_SIZE
(
data
)
==
0
)
?
1
:
0
);
mmio_write_32
(
AGX_MPFE_DDR_MAIN_SCHED_DDRMODE
,
bw_ratio_extended
<<
DDRMODE_BWRATIOEXTENDED_OFST
|
auto_precharge
<<
DDRMODE_AUTOPRECHARGE_OFST
);
mmio_write_32
(
AGX_MPFE_DDR_MAIN_SCHED_READLATENCY
,
(
rd_latency
/
2
)
+
DDR_READ_LATENCY_DELAY
);
data
=
mmio_read_32
(
AGX_MPFE_IOHMC_CALTIMING9
);
faw
=
AGX_MPFE_IOHMC_CALTIMING9_ACT_TO_ACT
(
data
);
faw_bank
=
1
;
// always 1 because we always have 4 bank DDR.
mmio_write_32
(
AGX_MPFE_DDR_MAIN_SCHED_ACTIVATE
,
faw_bank
<<
AGX_MPFE_DDR_MAIN_SCHED_ACTIVATE_FAWBANK_OFST
|
faw
<<
AGX_MPFE_DDR_MAIN_SCHED_ACTIVATE_FAW_OFST
|
act_to_act_bank
<<
AGX_MPFE_DDR_MAIN_SCHED_ACTIVATE_RRD_OFST
);
mmio_write_32
(
AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV
,
((
bus_rd_to_rd
<<
AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSRDTORD_OFST
)
&
AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSRDTORD_MSK
)
|
((
bus_rd_to_wr
<<
AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSRDTOWR_OFST
)
&
AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSRDTOWR_MSK
)
|
((
bus_wr_to_rd
<<
AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSWRTORD_OFST
)
&
AGX_MPFE_DDR_MAIN_SCHED_DEVTODEV_BUSWRTORD_MSK
));
}
unsigned
long
get_physical_dram_size
(
void
)
{
uint32_t
data
;
unsigned
long
ram_addr_width
,
ram_ext_if_io_width
;
data
=
mmio_read_32
(
AGX_MPFE_HMC_ADP_DDRIOCTRL
);
switch
(
AGX_MPFE_HMC_ADP_DDRIOCTRL_IO_SIZE
(
data
))
{
case
0
:
ram_ext_if_io_width
=
16
;
break
;
case
1
:
ram_ext_if_io_width
=
32
;
break
;
case
2
:
ram_ext_if_io_width
=
64
;
break
;
default:
ram_ext_if_io_width
=
0
;
break
;
}
data
=
mmio_read_32
(
AGX_MPFE_IOHMC_REG_DRAMADDRW
);
ram_addr_width
=
IOHMC_DRAMADDRW_CFG_COL_ADDR_WIDTH
(
data
)
+
IOHMC_DRAMADDRW_CFG_ROW_ADDR_WIDTH
(
data
)
+
IOHMC_DRAMADDRW_CFG_BANK_ADDR_WIDTH
(
data
)
+
IOHMC_DRAMADDRW_CFG_BANK_GROUP_ADDR_WIDTH
(
data
)
+
IOHMC_DRAMADDRW_CFG_CS_ADDR_WIDTH
(
data
);
return
(
1
<<
ram_addr_width
)
*
(
ram_ext_if_io_width
/
8
);
}
void
configure_hmc_adaptor_regs
(
void
)
{
uint32_t
data
;
uint32_t
dram_io_width
;
/* Configure DDR data rate */
dram_io_width
=
AGX_MPFE_IOHMC_NIOSRESERVE0_NIOS_RESERVE0
(
mmio_read_32
(
AGX_MPFE_IOHMC_REG_NIOSRESERVE0_OFST
));
dram_io_width
=
(
dram_io_width
&
0xFF
)
>>
5
;
mmio_clrsetbits_32
(
AGX_MPFE_HMC_ADP_DDRIOCTRL
,
AGX_MPFE_HMC_ADP_DDRIOCTRL_IO_SIZE_MSK
,
dram_io_width
<<
AGX_MPFE_HMC_ADP_DDRIOCTRL_IO_SIZE_OFST
);
/* Copy dram addr width from IOHMC to HMC ADP */
data
=
mmio_read_32
(
AGX_MPFE_IOHMC_DRAMADDRW
);
mmio_write_32
(
AGX_MPFE_HMC_ADP
(
ADP_DRAMADDRWIDTH
),
data
);
/* Enable nonsecure access to DDR */
mmio_write_32
(
AGX_NOC_FW_DDR_SCR_MPUREGION0ADDR_LIMIT
,
0x4000000
-
1
);
mmio_write_32
(
AGX_NOC_FW_DDR_SCR_NONMPUREGION0ADDR_LIMIT
,
0x4000000
-
1
);
mmio_write_32
(
AGX_SOC_NOC_FW_DDR_SCR_ENABLE
,
BIT
(
0
)
|
BIT
(
8
));
/* ECC enablement */
data
=
mmio_read_32
(
AGX_MPFE_IOHMC_REG_CTRLCFG1
);
if
(
data
&
(
1
<<
AGX_IOHMC_CTRLCFG1_ENABLE_ECC_OFST
))
{
mmio_clrsetbits_32
(
AGX_MPFE_HMC_ADP_ECCCTRL1
,
AGX_MPFE_HMC_ADP_ECCCTRL1_AUTOWB_CNT_RST_SET_MSK
|
AGX_MPFE_HMC_ADP_ECCCTRL1_CNT_RST_SET_MSK
|
AGX_MPFE_HMC_ADP_ECCCTRL1_ECC_EN_SET_MSK
,
AGX_MPFE_HMC_ADP_ECCCTRL1_AUTOWB_CNT_RST_SET_MSK
|
AGX_MPFE_HMC_ADP_ECCCTRL1_CNT_RST_SET_MSK
);
mmio_clrsetbits_32
(
AGX_MPFE_HMC_ADP_ECCCTRL2
,
AGX_MPFE_HMC_ADP_ECCCTRL2_OVRW_RB_ECC_EN_SET_MSK
|
AGX_MPFE_HMC_ADP_ECCCTRL2_RMW_EN_SET_MSK
|
AGX_MPFE_HMC_ADP_ECCCTRL2_AUTOWB_EN_SET_MSK
,
AGX_MPFE_HMC_ADP_ECCCTRL2_RMW_EN_SET_MSK
|
AGX_MPFE_HMC_ADP_ECCCTRL2_AUTOWB_EN_SET_MSK
);
mmio_clrsetbits_32
(
AGX_MPFE_HMC_ADP_ECCCTRL1
,
AGX_MPFE_HMC_ADP_ECCCTRL1_AUTOWB_CNT_RST_SET_MSK
|
AGX_MPFE_HMC_ADP_ECCCTRL1_CNT_RST_SET_MSK
|
AGX_MPFE_HMC_ADP_ECCCTRL1_ECC_EN_SET_MSK
,
AGX_MPFE_HMC_ADP_ECCCTRL1_ECC_EN_SET_MSK
);
INFO
(
"Scrubbing ECC
\n
"
);
/* ECC Scrubbing */
zeromem
(
DRAM_BASE
,
DRAM_SIZE
);
}
else
{
INFO
(
"ECC is disabled.
\n
"
);
}
}
This diff is collapsed.
Click to expand it.
plat/intel/soc/agilex/soc/agilex_pinmux.c
0 → 100644
View file @
b514ee86
/*
* Copyright (c) 2019, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <lib/mmio.h>
#include "agilex_pinmux.h"
const
uint32_t
sysmgr_pinmux_array_sel
[]
=
{
0x00000000
,
0x00000001
,
/* usb */
0x00000004
,
0x00000001
,
0x00000008
,
0x00000001
,
0x0000000c
,
0x00000001
,
0x00000010
,
0x00000001
,
0x00000014
,
0x00000001
,
0x00000018
,
0x00000001
,
0x0000001c
,
0x00000001
,
0x00000020
,
0x00000001
,
0x00000024
,
0x00000001
,
0x00000028
,
0x00000001
,
0x0000002c
,
0x00000001
,
0x00000030
,
0x00000000
,
/* emac0 */
0x00000034
,
0x00000000
,
0x00000038
,
0x00000000
,
0x0000003c
,
0x00000000
,
0x00000040
,
0x00000000
,
0x00000044
,
0x00000000
,
0x00000048
,
0x00000000
,
0x0000004c
,
0x00000000
,
0x00000050
,
0x00000000
,
0x00000054
,
0x00000000
,
0x00000058
,
0x00000000
,
0x0000005c
,
0x00000000
,
0x00000060
,
0x00000008
,
/* gpio1 */
0x00000064
,
0x00000008
,
0x00000068
,
0x00000005
,
/* uart0 tx */
0x0000006c
,
0x00000005
,
/* uart 0 rx */
0x00000070
,
0x00000008
,
/* gpio */
0x00000074
,
0x00000008
,
0x00000078
,
0x00000004
,
/* i2c1 */
0x0000007c
,
0x00000004
,
0x00000080
,
0x00000007
,
/* jtag */
0x00000084
,
0x00000007
,
0x00000088
,
0x00000007
,
0x0000008c
,
0x00000007
,
0x00000090
,
0x00000001
,
/* sdmmc data0 */
0x00000094
,
0x00000001
,
0x00000098
,
0x00000001
,
0x0000009c
,
0x00000001
,
0x00000100
,
0x00000001
,
0x00000104
,
0x00000001
,
/* sdmmc.data3 */
0x00000108
,
0x00000008
,
/* loan */
0x0000010c
,
0x00000008
,
/* gpio */
0x00000110
,
0x00000008
,
0x00000114
,
0x00000008
,
/* gpio1.io21 */
0x00000118
,
0x00000005
,
/* mdio0.mdio */
0x0000011c
,
0x00000005
/* mdio0.mdc */
};
const
uint32_t
sysmgr_pinmux_array_ctrl
[]
=
{
0x00000000
,
0x00502c38
,
/* Q1_1 */
0x00000004
,
0x00102c38
,
0x00000008
,
0x00502c38
,
0x0000000c
,
0x00502c38
,
0x00000010
,
0x00502c38
,
0x00000014
,
0x00502c38
,
0x00000018
,
0x00502c38
,
0x0000001c
,
0x00502c38
,
0x00000020
,
0x00502c38
,
0x00000024
,
0x00502c38
,
0x00000028
,
0x00502c38
,
0x0000002c
,
0x00502c38
,
0x00000030
,
0x00102c38
,
/* Q2_1 */
0x00000034
,
0x00102c38
,
0x00000038
,
0x00502c38
,
0x0000003c
,
0x00502c38
,
0x00000040
,
0x00102c38
,
0x00000044
,
0x00102c38
,
0x00000048
,
0x00502c38
,
0x0000004c
,
0x00502c38
,
0x00000050
,
0x00102c38
,
0x00000054
,
0x00102c38
,
0x00000058
,
0x00502c38
,
0x0000005c
,
0x00502c38
,
0x00000060
,
0x00502c38
,
/* Q3_1 */
0x00000064
,
0x00502c38
,
0x00000068
,
0x00102c38
,
0x0000006c
,
0x00502c38
,
0x000000d0
,
0x00502c38
,
0x000000d4
,
0x00502c38
,
0x000000d8
,
0x00542c38
,
0x000000dc
,
0x00542c38
,
0x000000e0
,
0x00502c38
,
0x000000e4
,
0x00502c38
,
0x000000e8
,
0x00102c38
,
0x000000ec
,
0x00502c38
,
0x000000f0
,
0x00502c38
,
/* Q4_1 */
0x000000f4
,
0x00502c38
,
0x000000f8
,
0x00102c38
,
0x000000fc
,
0x00502c38
,
0x00000100
,
0x00502c38
,
0x00000104
,
0x00502c38
,
0x00000108
,
0x00102c38
,
0x0000010c
,
0x00502c38
,
0x00000110
,
0x00502c38
,
0x00000114
,
0x00502c38
,
0x00000118
,
0x00542c38
,
0x0000011c
,
0x00102c38
};
const
uint32_t
sysmgr_pinmux_array_fpga
[]
=
{
0x00000000
,
0x00000000
,
0x00000004
,
0x00000000
,
0x00000008
,
0x00000000
,
0x0000000c
,
0x00000000
,
0x00000010
,
0x00000000
,
0x00000014
,
0x00000000
,
0x00000018
,
0x00000000
,
0x0000001c
,
0x00000000
,
0x00000020
,
0x00000000
,
0x00000028
,
0x00000000
,
0x0000002c
,
0x00000000
,
0x00000030
,
0x00000000
,
0x00000034
,
0x00000000
,
0x00000038
,
0x00000000
,
0x0000003c
,
0x00000000
,
0x00000040
,
0x00000000
,
0x00000044
,
0x00000000
,
0x00000048
,
0x00000000
,
0x00000050
,
0x00000000
,
0x00000054
,
0x00000000
,
0x00000058
,
0x0000002a
};
const
uint32_t
sysmgr_pinmux_array_iodelay
[]
=
{
0x00000000
,
0x00000000
,
0x00000004
,
0x00000000
,
0x00000008
,
0x00000000
,
0x0000000c
,
0x00000000
,
0x00000010
,
0x00000000
,
0x00000014
,
0x00000000
,
0x00000018
,
0x00000000
,
0x0000001c
,
0x00000000
,
0x00000020
,
0x00000000
,
0x00000024
,
0x00000000
,
0x00000028
,
0x00000000
,
0x0000002c
,
0x00000000
,
0x00000030
,
0x00000000
,
0x00000034
,
0x00000000
,
0x00000038
,
0x00000000
,
0x0000003c
,
0x00000000
,
0x00000040
,
0x00000000
,
0x00000044
,
0x00000000
,
0x00000048
,
0x00000000
,
0x0000004c
,
0x00000000
,
0x00000050
,
0x00000000
,
0x00000054
,
0x00000000
,
0x00000058
,
0x00000000
,
0x0000005c
,
0x00000000
,
0x00000060
,
0x00000000
,
0x00000064
,
0x00000000
,
0x00000068
,
0x00000000
,
0x0000006c
,
0x00000000
,
0x00000070
,
0x00000000
,
0x00000074
,
0x00000000
,
0x00000078
,
0x00000000
,
0x0000007c
,
0x00000000
,
0x00000080
,
0x00000000
,
0x00000084
,
0x00000000
,
0x00000088
,
0x00000000
,
0x0000008c
,
0x00000000
,
0x00000090
,
0x00000000
,
0x00000094
,
0x00000000
,
0x00000098
,
0x00000000
,
0x0000009c
,
0x00000000
,
0x00000100
,
0x00000000
,
0x00000104
,
0x00000000
,
0x00000108
,
0x00000000
,
0x0000010c
,
0x00000000
,
0x00000110
,
0x00000000
,
0x00000114
,
0x00000000
,
0x00000118
,
0x00000000
,
0x0000011c
,
0x00000000
};
void
config_pinmux
(
handoff
*
hoff_ptr
)
{
unsigned
int
i
;
for
(
i
=
0
;
i
<
96
;
i
+=
2
)
{
mmio_write_32
(
AGX_PINMUX_PIN0SEL
+
hoff_ptr
->
pinmux_sel_array
[
i
],
hoff_ptr
->
pinmux_sel_array
[
i
+
1
]);
}
for
(
i
=
0
;
i
<
96
;
i
+=
2
)
{
mmio_write_32
(
AGX_PINMUX_IO0CTRL
+
hoff_ptr
->
pinmux_io_array
[
i
],
hoff_ptr
->
pinmux_io_array
[
i
+
1
]);
}
for
(
i
=
0
;
i
<
42
;
i
+=
2
)
{
mmio_write_32
(
AGX_PINMUX_PINMUX_EMAC0_USEFPGA
+
hoff_ptr
->
pinmux_fpga_array
[
i
],
hoff_ptr
->
pinmux_fpga_array
[
i
+
1
]);
}
for
(
i
=
0
;
i
<
96
;
i
+=
2
)
{
mmio_write_32
(
AGX_PINMUX_IO0_DELAY
+
hoff_ptr
->
pinmux_iodelay_array
[
i
],
hoff_ptr
->
pinmux_iodelay_array
[
i
+
1
]);
}
}
This diff is collapsed.
Click to expand it.
plat/intel/soc/agilex/soc/agilex_reset_manager.c
0 → 100644
View file @
b514ee86
/*
* Copyright (c) 2019, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <lib/mmio.h>
#include "agilex_reset_manager.h"
void
deassert_peripheral_reset
(
void
)
{
mmio_clrbits_32
(
AGX_RSTMGR_PER1MODRST
,
AGX_RSTMGR_PER1MODRST_WATCHDOG0
|
AGX_RSTMGR_PER1MODRST_WATCHDOG1
|
AGX_RSTMGR_PER1MODRST_WATCHDOG2
|
AGX_RSTMGR_PER1MODRST_WATCHDOG3
|
AGX_RSTMGR_PER1MODRST_L4SYSTIMER0
|
AGX_RSTMGR_PER1MODRST_L4SYSTIMER1
|
AGX_RSTMGR_PER1MODRST_SPTIMER0
|
AGX_RSTMGR_PER1MODRST_SPTIMER1
|
AGX_RSTMGR_PER1MODRST_I2C0
|
AGX_RSTMGR_PER1MODRST_I2C1
|
AGX_RSTMGR_PER1MODRST_I2C2
|
AGX_RSTMGR_PER1MODRST_I2C3
|
AGX_RSTMGR_PER1MODRST_I2C4
|
AGX_RSTMGR_PER1MODRST_UART0
|
AGX_RSTMGR_PER1MODRST_UART1
|
AGX_RSTMGR_PER1MODRST_GPIO0
|
AGX_RSTMGR_PER1MODRST_GPIO1
);
mmio_clrbits_32
(
AGX_RSTMGR_PER0MODRST
,
AGX_RSTMGR_PER0MODRST_EMAC0OCP
|
AGX_RSTMGR_PER0MODRST_EMAC1OCP
|
AGX_RSTMGR_PER0MODRST_EMAC2OCP
|
AGX_RSTMGR_PER0MODRST_USB0OCP
|
AGX_RSTMGR_PER0MODRST_USB1OCP
|
AGX_RSTMGR_PER0MODRST_NANDOCP
|
AGX_RSTMGR_PER0MODRST_SDMMCOCP
|
AGX_RSTMGR_PER0MODRST_DMAOCP
);
mmio_clrbits_32
(
AGX_RSTMGR_PER0MODRST
,
AGX_RSTMGR_PER0MODRST_EMAC0
|
AGX_RSTMGR_PER0MODRST_EMAC1
|
AGX_RSTMGR_PER0MODRST_EMAC2
|
AGX_RSTMGR_PER0MODRST_USB0
|
AGX_RSTMGR_PER0MODRST_USB1
|
AGX_RSTMGR_PER0MODRST_NAND
|
AGX_RSTMGR_PER0MODRST_SDMMC
|
AGX_RSTMGR_PER0MODRST_DMA
|
AGX_RSTMGR_PER0MODRST_SPIM0
|
AGX_RSTMGR_PER0MODRST_SPIM1
|
AGX_RSTMGR_PER0MODRST_SPIS0
|
AGX_RSTMGR_PER0MODRST_SPIS1
|
AGX_RSTMGR_PER0MODRST_EMACPTP
|
AGX_RSTMGR_PER0MODRST_DMAIF0
|
AGX_RSTMGR_PER0MODRST_DMAIF1
|
AGX_RSTMGR_PER0MODRST_DMAIF2
|
AGX_RSTMGR_PER0MODRST_DMAIF3
|
AGX_RSTMGR_PER0MODRST_DMAIF4
|
AGX_RSTMGR_PER0MODRST_DMAIF5
|
AGX_RSTMGR_PER0MODRST_DMAIF6
|
AGX_RSTMGR_PER0MODRST_DMAIF7
);
mmio_clrbits_32
(
AGX_RSTMGR_BRGMODRST
,
AGX_RSTMGR_BRGMODRST_MPFE
);
}
void
config_hps_hs_before_warm_reset
(
void
)
{
uint32_t
or_mask
=
0
;
or_mask
|=
AGX_RSTMGR_HDSKEN_SDRSELFREFEN
;
or_mask
|=
AGX_RSTMGR_HDSKEN_FPGAHSEN
;
or_mask
|=
AGX_RSTMGR_HDSKEN_ETRSTALLEN
;
or_mask
|=
AGX_RSTMGR_HDSKEN_L2FLUSHEN
;
or_mask
|=
AGX_RSTMGR_HDSKEN_L3NOC_DBG
;
or_mask
|=
AGX_RSTMGR_HDSKEN_DEBUG_L3NOC
;
mmio_setbits_32
(
AGX_RSTMGR_HDSKEN
,
or_mask
);
}
This diff is collapsed.
Click to expand it.
plat/intel/soc/agilex/soc/agilex_system_manager.c
0 → 100644
View file @
b514ee86
/*
* Copyright (c) 2019, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <lib/mmio.h>
#include <lib/utils_def.h>
#include "agilex_system_manager.h"
void
enable_nonsecure_access
(
void
)
{
mmio_write_32
(
AGX_NOC_FW_L4_PER_SCR_NAND_REGISTER
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_PER_SCR_NAND_DATA
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_SYS_SCR_NAND_ECC
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_SYS_SCR_NAND_READ_ECC
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_SYS_SCR_NAND_WRITE_ECC
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_PER_SCR_USB0_REGISTER
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_PER_SCR_USB1_REGISTER
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_SYS_SCR_USB0_ECC
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_SYS_SCR_USB1_ECC
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_PER_SCR_SPI_MASTER0
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_PER_SCR_SPI_MASTER1
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_PER_SCR_SPI_SLAVE0
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_PER_SCR_SPI_SLAVE1
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_PER_SCR_EMAC0
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_PER_SCR_EMAC1
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_PER_SCR_EMAC2
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_SYS_SCR_EMAC0RX_ECC
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_SYS_SCR_EMAC0TX_ECC
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_SYS_SCR_EMAC1RX_ECC
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_SYS_SCR_EMAC1TX_ECC
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_SYS_SCR_EMAC2RX_ECC
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_SYS_SCR_EMAC2TX_ECC
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_PER_SCR_SDMMC
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_SYS_SCR_SDMMC_ECC
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_PER_SCR_GPIO0
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_PER_SCR_GPIO1
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_PER_SCR_I2C0
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_PER_SCR_I2C1
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_PER_SCR_I2C2
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_PER_SCR_I2C3
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_PER_SCR_I2C4
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_PER_SCR_SP_TIMER1
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_PER_SCR_UART0
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_PER_SCR_UART1
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_SYS_SCR_DMA_ECC
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_SYS_SCR_OCRAM_ECC
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_SYS_SCR_CLK_MGR
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_SYS_SCR_IO_MGR
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_SYS_SCR_RST_MGR
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_SYS_SCR_SYS_MGR
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_SYS_SCR_OSC0_TIMER
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_SYS_SCR_OSC1_TIMER
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_SYS_SCR_WATCHDOG0
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_SYS_SCR_WATCHDOG1
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_SYS_SCR_WATCHDOG2
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_SYS_SCR_WATCHDOG3
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_SYS_SCR_DAP
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_SYS_SCR_L4_NOC_PROBES
,
DISABLE_L4_FIREWALL
);
mmio_write_32
(
AGX_NOC_FW_L4_SYS_SCR_L4_NOC_QOS
,
DISABLE_L4_FIREWALL
);
}
void
enable_ns_bridge_access
(
void
)
{
mmio_write_32
(
AGX_FIREWALL_SOC2FPGA
,
DISABLE_BRIDGE_FIREWALL
);
mmio_write_32
(
AGX_FIREWALL_LWSOC2FPGA
,
DISABLE_BRIDGE_FIREWALL
);
}
This diff is collapsed.
Click to expand it.
plat/intel/soc/agilex/socfpga_delay_timer.c
0 → 100644
View file @
b514ee86
/*
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <arch_helpers.h>
#include <drivers/delay_timer.h>
#include <lib/mmio.h>
#define AGX_GLOBAL_TIMER 0xffd01000
#define AGX_GLOBAL_TIMER_EN 0x3
/********************************************************************
* The timer delay function
********************************************************************/
static
uint32_t
socfpga_get_timer_value
(
void
)
{
/*
* Generic delay timer implementation expects the timer to be a down
* counter. We apply bitwise NOT operator to the tick values returned
* by read_cntpct_el0() to simulate the down counter. The value is
* clipped from 64 to 32 bits.
*/
return
(
uint32_t
)(
~
read_cntpct_el0
());
}
static
const
timer_ops_t
plat_timer_ops
=
{
.
get_timer_value
=
socfpga_get_timer_value
,
.
clk_mult
=
1
,
.
clk_div
=
PLAT_SYS_COUNTER_FREQ_IN_MHZ
,
};
void
socfpga_delay_timer_init
(
void
)
{
timer_init
(
&
plat_timer_ops
);
mmio_write_32
(
AGX_GLOBAL_TIMER
,
AGX_GLOBAL_TIMER_EN
);
}
This diff is collapsed.
Click to expand it.
plat/intel/soc/agilex/socfpga_image_load.c
0 → 100644
View file @
b514ee86
/*
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/desc_image_load.h>
/*******************************************************************************
* This function flushes the data structures so that they are visible
* in memory for the next BL image.
******************************************************************************/
void
plat_flush_next_bl_params
(
void
)
{
flush_bl_params_desc
();
}
/*******************************************************************************
* This function returns the list of loadable images.
******************************************************************************/
bl_load_info_t
*
plat_get_bl_image_load_info
(
void
)
{
return
get_bl_load_info_from_mem_params_desc
();
}
/*******************************************************************************
* This function returns the list of executable images.
******************************************************************************/
bl_params_t
*
plat_get_next_bl_params
(
void
)
{
return
get_next_bl_params_from_mem_params_desc
();
}
This diff is collapsed.
Click to expand it.
plat/intel/soc/agilex/socfpga_psci.c
0 → 100644
View file @
b514ee86
/*
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/arm/gicv2.h>
#include <lib/mmio.h>
#include <lib/psci/psci.h>
#include <plat/common/platform.h>
#include "agilex_reset_manager.h"
#include "agilex_mailbox.h"
#define AGX_RSTMGR_OFST 0xffd11000
#define AGX_RSTMGR_MPUMODRST_OFST 0x20
uintptr_t
*
agilex_sec_entry
=
(
uintptr_t
*
)
PLAT_AGX_SEC_ENTRY
;
uintptr_t
*
cpuid_release
=
(
uintptr_t
*
)
PLAT_CPUID_RELEASE
;
/*******************************************************************************
* plat handler called when a CPU is about to enter standby.
******************************************************************************/
void
socfpga_cpu_standby
(
plat_local_state_t
cpu_state
)
{
/*
* Enter standby state
* dsb is good practice before using wfi to enter low power states
*/
VERBOSE
(
"%s: cpu_state: 0x%x
\n
"
,
__func__
,
cpu_state
);
dsb
();
wfi
();
}
/*******************************************************************************
* plat handler called when a power domain is about to be turned on. The
* mpidr determines the CPU to be turned on.
******************************************************************************/
int
socfpga_pwr_domain_on
(
u_register_t
mpidr
)
{
unsigned
int
cpu_id
=
plat_core_pos_by_mpidr
(
mpidr
);
VERBOSE
(
"%s: mpidr: 0x%lx
\n
"
,
__func__
,
mpidr
);
if
(
cpu_id
==
-
1
)
return
PSCI_E_INTERN_FAIL
;
*
cpuid_release
=
cpu_id
;
/* release core reset */
mmio_setbits_32
(
AGX_RSTMGR_OFST
+
AGX_RSTMGR_MPUMODRST_OFST
,
1
<<
cpu_id
);
return
PSCI_E_SUCCESS
;
}
/*******************************************************************************
* plat handler called when a power domain is about to be turned off. The
* target_state encodes the power state that each level should transition to.
******************************************************************************/
void
socfpga_pwr_domain_off
(
const
psci_power_state_t
*
target_state
)
{
unsigned
int
cpu_id
=
plat_my_core_pos
();
for
(
size_t
i
=
0
;
i
<=
PLAT_MAX_PWR_LVL
;
i
++
)
VERBOSE
(
"%s: target_state->pwr_domain_state[%lu]=%x
\n
"
,
__func__
,
i
,
target_state
->
pwr_domain_state
[
i
]);
/* TODO: Prevent interrupts from spuriously waking up this cpu */
/* gicv2_cpuif_disable(); */
/* assert core reset */
mmio_setbits_32
(
AGX_RSTMGR_OFST
+
AGX_RSTMGR_MPUMODRST_OFST
,
1
<<
cpu_id
);
}
/*******************************************************************************
* plat handler called when a power domain is about to be suspended. The
* target_state encodes the power state that each level should transition to.
******************************************************************************/
void
socfpga_pwr_domain_suspend
(
const
psci_power_state_t
*
target_state
)
{
unsigned
int
cpu_id
=
plat_my_core_pos
();
for
(
size_t
i
=
0
;
i
<=
PLAT_MAX_PWR_LVL
;
i
++
)
VERBOSE
(
"%s: target_state->pwr_domain_state[%lu]=%x
\n
"
,
__func__
,
i
,
target_state
->
pwr_domain_state
[
i
]);
/* assert core reset */
mmio_setbits_32
(
AGX_RSTMGR_OFST
+
AGX_RSTMGR_MPUMODRST_OFST
,
1
<<
cpu_id
);
}
/*******************************************************************************
* plat handler called when a power domain has just been powered on after
* being turned off earlier. The target_state encodes the low power state that
* each level has woken up from.
******************************************************************************/
void
socfpga_pwr_domain_on_finish
(
const
psci_power_state_t
*
target_state
)
{
for
(
size_t
i
=
0
;
i
<=
PLAT_MAX_PWR_LVL
;
i
++
)
VERBOSE
(
"%s: target_state->pwr_domain_state[%lu]=%x
\n
"
,
__func__
,
i
,
target_state
->
pwr_domain_state
[
i
]);
/* Program the gic per-cpu distributor or re-distributor interface */
gicv2_pcpu_distif_init
();
gicv2_set_pe_target_mask
(
plat_my_core_pos
());
/* Enable the gic cpu interface */
gicv2_cpuif_enable
();
}
/*******************************************************************************
* plat handler called when a power domain has just been powered on after
* having been suspended earlier. The target_state encodes the low power state
* that each level has woken up from.
* TODO: At the moment we reuse the on finisher and reinitialize the secure
* context. Need to implement a separate suspend finisher.
******************************************************************************/
void
socfpga_pwr_domain_suspend_finish
(
const
psci_power_state_t
*
target_state
)
{
unsigned
int
cpu_id
=
plat_my_core_pos
();
for
(
size_t
i
=
0
;
i
<=
PLAT_MAX_PWR_LVL
;
i
++
)
VERBOSE
(
"%s: target_state->pwr_domain_state[%lu]=%x
\n
"
,
__func__
,
i
,
target_state
->
pwr_domain_state
[
i
]);
/* release core reset */
mmio_clrbits_32
(
AGX_RSTMGR_OFST
+
AGX_RSTMGR_MPUMODRST_OFST
,
1
<<
cpu_id
);
}
/*******************************************************************************
* plat handlers to shutdown/reboot the system
******************************************************************************/
static
void
__dead2
socfpga_system_off
(
void
)
{
wfi
();
ERROR
(
"System Off: operation not handled.
\n
"
);
panic
();
}
static
void
__dead2
socfpga_system_reset
(
void
)
{
INFO
(
"assert Peripheral from Reset
\r\n
"
);
deassert_peripheral_reset
();
mailbox_reset_cold
();
while
(
1
)
wfi
();
}
int
socfpga_validate_power_state
(
unsigned
int
power_state
,
psci_power_state_t
*
req_state
)
{
VERBOSE
(
"%s: power_state: 0x%x
\n
"
,
__func__
,
power_state
);
return
PSCI_E_SUCCESS
;
}
int
socfpga_validate_ns_entrypoint
(
unsigned
long
ns_entrypoint
)
{
VERBOSE
(
"%s: ns_entrypoint: 0x%lx
\n
"
,
__func__
,
ns_entrypoint
);
return
PSCI_E_SUCCESS
;
}
void
socfpga_get_sys_suspend_power_state
(
psci_power_state_t
*
req_state
)
{
req_state
->
pwr_domain_state
[
PSCI_CPU_PWR_LVL
]
=
PLAT_MAX_OFF_STATE
;
req_state
->
pwr_domain_state
[
1
]
=
PLAT_MAX_OFF_STATE
;
}
/*******************************************************************************
* Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard
* platform layer will take care of registering the handlers with PSCI.
******************************************************************************/
const
plat_psci_ops_t
socfpga_psci_pm_ops
=
{
.
cpu_standby
=
socfpga_cpu_standby
,
.
pwr_domain_on
=
socfpga_pwr_domain_on
,
.
pwr_domain_off
=
socfpga_pwr_domain_off
,
.
pwr_domain_suspend
=
socfpga_pwr_domain_suspend
,
.
pwr_domain_on_finish
=
socfpga_pwr_domain_on_finish
,
.
pwr_domain_suspend_finish
=
socfpga_pwr_domain_suspend_finish
,
.
system_off
=
socfpga_system_off
,
.
system_reset
=
socfpga_system_reset
,
.
validate_power_state
=
socfpga_validate_power_state
,
.
validate_ns_entrypoint
=
socfpga_validate_ns_entrypoint
,
.
get_sys_suspend_power_state
=
socfpga_get_sys_suspend_power_state
};
/*******************************************************************************
* Export the platform specific power ops.
******************************************************************************/
int
plat_setup_psci_ops
(
uintptr_t
sec_entrypoint
,
const
struct
plat_psci_ops
**
psci_ops
)
{
/* Save warm boot entrypoint.*/
*
agilex_sec_entry
=
sec_entrypoint
;
*
psci_ops
=
&
socfpga_psci_pm_ops
;
return
0
;
}
This diff is collapsed.
Click to expand it.
plat/intel/soc/agilex/socfpga_sip_svc.c
0 → 100644
View file @
b514ee86
/*
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <common/debug.h>
#include <common/runtime_svc.h>
#include <tools_share/uuid.h>
#include "agilex_mailbox.h"
/* Number of SiP Calls implemented */
#define SIP_NUM_CALLS 0x3
/* Total buffer the driver can hold */
#define FPGA_CONFIG_BUFFER_SIZE 4
int
current_block
;
int
current_buffer
;
int
current_id
=
1
;
int
max_blocks
;
uint32_t
bytes_per_block
;
uint32_t
blocks_submitted
;
uint32_t
blocks_completed
;
struct
fpga_config_info
{
uint32_t
addr
;
int
size
;
int
size_written
;
uint32_t
write_requested
;
int
subblocks_sent
;
int
block_number
;
};
/* SiP Service UUID */
DEFINE_SVC_UUID2
(
intl_svc_uid
,
0xa85273b0
,
0xe85a
,
0x4862
,
0xa6
,
0x2a
,
0xfa
,
0x88
,
0x88
,
0x17
,
0x68
,
0x81
);
uint64_t
socfpga_sip_handler
(
uint32_t
smc_fid
,
uint64_t
x1
,
uint64_t
x2
,
uint64_t
x3
,
uint64_t
x4
,
void
*
cookie
,
void
*
handle
,
uint64_t
flags
)
{
ERROR
(
"%s: unhandled SMC (0x%x)
\n
"
,
__func__
,
smc_fid
);
SMC_RET1
(
handle
,
SMC_UNK
);
}
struct
fpga_config_info
fpga_config_buffers
[
FPGA_CONFIG_BUFFER_SIZE
];
static
void
intel_fpga_sdm_write_buffer
(
struct
fpga_config_info
*
buffer
)
{
uint32_t
args
[
3
];
while
(
max_blocks
>
0
&&
buffer
->
size
>
buffer
->
size_written
)
{
if
(
buffer
->
size
-
buffer
->
size_written
<=
bytes_per_block
)
{
args
[
0
]
=
(
1
<<
8
);
args
[
1
]
=
buffer
->
addr
+
buffer
->
size_written
;
args
[
2
]
=
buffer
->
size
-
buffer
->
size_written
;
buffer
->
size_written
+=
buffer
->
size
-
buffer
->
size_written
;
buffer
->
subblocks_sent
++
;
mailbox_send_cmd_async
(
0x4
,
MBOX_RECONFIG_DATA
,
args
,
3
,
0
);
current_buffer
++
;
current_buffer
%=
FPGA_CONFIG_BUFFER_SIZE
;
}
else
{
args
[
0
]
=
(
1
<<
8
);
args
[
1
]
=
buffer
->
addr
+
buffer
->
size_written
;
args
[
2
]
=
bytes_per_block
;
buffer
->
size_written
+=
bytes_per_block
;
mailbox_send_cmd_async
(
0x4
,
MBOX_RECONFIG_DATA
,
args
,
3
,
0
);
buffer
->
subblocks_sent
++
;
}
max_blocks
--
;
}
}
static
int
intel_fpga_sdm_write_all
(
void
)
{
int
i
;
for
(
i
=
0
;
i
<
FPGA_CONFIG_BUFFER_SIZE
;
i
++
)
intel_fpga_sdm_write_buffer
(
&
fpga_config_buffers
[
current_buffer
]);
return
0
;
}
uint32_t
intel_mailbox_fpga_config_isdone
(
void
)
{
uint32_t
args
[
2
];
uint32_t
response
[
6
];
int
status
;
status
=
mailbox_send_cmd
(
1
,
MBOX_RECONFIG_STATUS
,
args
,
0
,
0
,
response
);
if
(
status
<
0
)
return
INTEL_SIP_SMC_STATUS_ERROR
;
if
(
response
[
RECONFIG_STATUS_STATE
]
&&
response
[
RECONFIG_STATUS_STATE
]
!=
MBOX_CFGSTAT_STATE_CONFIG
)
return
INTEL_SIP_SMC_STATUS_ERROR
;
if
(
!
(
response
[
RECONFIG_STATUS_PIN_STATUS
]
&
PIN_STATUS_NSTATUS
))
return
INTEL_SIP_SMC_STATUS_ERROR
;
if
(
response
[
RECONFIG_STATUS_SOFTFUNC_STATUS
]
&
SOFTFUNC_STATUS_SEU_ERROR
)
return
INTEL_SIP_SMC_STATUS_ERROR
;
if
((
response
[
RECONFIG_STATUS_SOFTFUNC_STATUS
]
&
SOFTFUNC_STATUS_CONF_DONE
)
&&
(
response
[
RECONFIG_STATUS_SOFTFUNC_STATUS
]
&
SOFTFUNC_STATUS_INIT_DONE
))
return
INTEL_SIP_SMC_STATUS_OK
;
return
INTEL_SIP_SMC_STATUS_ERROR
;
}
static
int
mark_last_buffer_xfer_completed
(
uint32_t
*
buffer_addr_completed
)
{
int
i
;
for
(
i
=
0
;
i
<
FPGA_CONFIG_BUFFER_SIZE
;
i
++
)
{
if
(
fpga_config_buffers
[
i
].
block_number
==
current_block
)
{
fpga_config_buffers
[
i
].
subblocks_sent
--
;
if
(
fpga_config_buffers
[
i
].
subblocks_sent
==
0
&&
fpga_config_buffers
[
i
].
size
<=
fpga_config_buffers
[
i
].
size_written
)
{
fpga_config_buffers
[
i
].
write_requested
=
0
;
current_block
++
;
*
buffer_addr_completed
=
fpga_config_buffers
[
i
].
addr
;
return
0
;
}
}
}
return
-
1
;
}
unsigned
int
address_in_ddr
(
uint32_t
*
addr
)
{
if
(((
unsigned
long
long
)
addr
>
DRAM_BASE
)
&&
((
unsigned
long
long
)
addr
<
DRAM_BASE
+
DRAM_SIZE
))
return
0
;
return
-
1
;
}
int
intel_fpga_config_completed_write
(
uint32_t
*
completed_addr
,
uint32_t
*
count
)
{
uint32_t
status
=
INTEL_SIP_SMC_STATUS_OK
;
*
count
=
0
;
int
resp_len
=
0
;
uint32_t
resp
[
5
];
int
all_completed
=
1
;
int
count_check
=
0
;
if
(
address_in_ddr
(
completed_addr
)
!=
0
||
address_in_ddr
(
count
)
!=
0
)
return
INTEL_SIP_SMC_STATUS_ERROR
;
for
(
count_check
=
0
;
count_check
<
3
;
count_check
++
)
if
(
address_in_ddr
(
&
completed_addr
[
*
count
+
count_check
])
!=
0
)
return
INTEL_SIP_SMC_STATUS_ERROR
;
resp_len
=
mailbox_read_response
(
0x4
,
resp
);
while
(
resp_len
>=
0
&&
*
count
<
3
)
{
max_blocks
++
;
if
(
mark_last_buffer_xfer_completed
(
&
completed_addr
[
*
count
])
==
0
)
*
count
=
*
count
+
1
;
else
break
;
resp_len
=
mailbox_read_response
(
0x4
,
resp
);
}
if
(
*
count
<=
0
)
{
if
(
resp_len
!=
MBOX_NO_RESPONSE
&&
resp_len
!=
MBOX_TIMEOUT
&&
resp_len
!=
0
)
{
return
INTEL_SIP_SMC_STATUS_ERROR
;
}
*
count
=
0
;
}
intel_fpga_sdm_write_all
();
if
(
*
count
>
0
)
status
=
INTEL_SIP_SMC_STATUS_OK
;
else
if
(
*
count
==
0
)
status
=
INTEL_SIP_SMC_STATUS_BUSY
;
for
(
int
i
=
0
;
i
<
FPGA_CONFIG_BUFFER_SIZE
;
i
++
)
{
if
(
fpga_config_buffers
[
i
].
write_requested
!=
0
)
{
all_completed
=
0
;
break
;
}
}
if
(
all_completed
==
1
)
return
INTEL_SIP_SMC_STATUS_OK
;
return
status
;
}
int
intel_fpga_config_start
(
uint32_t
config_type
)
{
uint32_t
response
[
3
];
int
status
=
0
;
status
=
mailbox_send_cmd
(
2
,
MBOX_RECONFIG
,
0
,
0
,
0
,
response
);
if
(
status
<
0
)
return
status
;
max_blocks
=
response
[
0
];
bytes_per_block
=
response
[
1
];
for
(
int
i
=
0
;
i
<
FPGA_CONFIG_BUFFER_SIZE
;
i
++
)
{
fpga_config_buffers
[
i
].
size
=
0
;
fpga_config_buffers
[
i
].
size_written
=
0
;
fpga_config_buffers
[
i
].
addr
=
0
;
fpga_config_buffers
[
i
].
write_requested
=
0
;
fpga_config_buffers
[
i
].
block_number
=
0
;
fpga_config_buffers
[
i
].
subblocks_sent
=
0
;
}
blocks_submitted
=
0
;
current_block
=
0
;
current_buffer
=
0
;
return
0
;
}
uint32_t
intel_fpga_config_write
(
uint64_t
mem
,
uint64_t
size
)
{
int
i
=
0
;
uint32_t
status
=
INTEL_SIP_SMC_STATUS_OK
;
if
(
mem
<
DRAM_BASE
||
mem
>
DRAM_BASE
+
DRAM_SIZE
)
status
=
INTEL_SIP_SMC_STATUS_REJECTED
;
if
(
mem
+
size
>
DRAM_BASE
+
DRAM_SIZE
)
status
=
INTEL_SIP_SMC_STATUS_REJECTED
;
for
(
i
=
0
;
i
<
FPGA_CONFIG_BUFFER_SIZE
;
i
++
)
{
if
(
!
fpga_config_buffers
[
i
].
write_requested
)
{
fpga_config_buffers
[
i
].
addr
=
mem
;
fpga_config_buffers
[
i
].
size
=
size
;
fpga_config_buffers
[
i
].
size_written
=
0
;
fpga_config_buffers
[
i
].
write_requested
=
1
;
fpga_config_buffers
[
i
].
block_number
=
blocks_submitted
++
;
fpga_config_buffers
[
i
].
subblocks_sent
=
0
;
break
;
}
}
if
(
i
==
FPGA_CONFIG_BUFFER_SIZE
)
{
status
=
INTEL_SIP_SMC_STATUS_REJECTED
;
return
status
;
}
else
if
(
i
==
FPGA_CONFIG_BUFFER_SIZE
-
1
)
{
status
=
INTEL_SIP_SMC_STATUS_BUSY
;
}
intel_fpga_sdm_write_all
();
return
status
;
}
/*
* This function is responsible for handling all SiP calls from the NS world
*/
uintptr_t
sip_smc_handler
(
uint32_t
smc_fid
,
u_register_t
x1
,
u_register_t
x2
,
u_register_t
x3
,
u_register_t
x4
,
void
*
cookie
,
void
*
handle
,
u_register_t
flags
)
{
uint32_t
status
=
INTEL_SIP_SMC_STATUS_OK
;
uint32_t
completed_addr
[
3
];
uint32_t
count
=
0
;
switch
(
smc_fid
)
{
case
SIP_SVC_UID
:
/* Return UID to the caller */
SMC_UUID_RET
(
handle
,
intl_svc_uid
);
break
;
case
INTEL_SIP_SMC_FPGA_CONFIG_ISDONE
:
status
=
intel_mailbox_fpga_config_isdone
();
SMC_RET4
(
handle
,
status
,
0
,
0
,
0
);
break
;
case
INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM
:
SMC_RET3
(
handle
,
INTEL_SIP_SMC_STATUS_OK
,
INTEL_SIP_SMC_FPGA_CONFIG_ADDR
,
INTEL_SIP_SMC_FPGA_CONFIG_SIZE
-
INTEL_SIP_SMC_FPGA_CONFIG_ADDR
);
break
;
case
INTEL_SIP_SMC_FPGA_CONFIG_START
:
status
=
intel_fpga_config_start
(
x1
);
SMC_RET4
(
handle
,
status
,
0
,
0
,
0
);
break
;
case
INTEL_SIP_SMC_FPGA_CONFIG_WRITE
:
status
=
intel_fpga_config_write
(
x1
,
x2
);
SMC_RET4
(
handle
,
status
,
0
,
0
,
0
);
break
;
case
INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE
:
status
=
intel_fpga_config_completed_write
(
completed_addr
,
&
count
);
switch
(
count
)
{
case
1
:
SMC_RET4
(
handle
,
INTEL_SIP_SMC_STATUS_OK
,
completed_addr
[
0
],
0
,
0
);
break
;
case
2
:
SMC_RET4
(
handle
,
INTEL_SIP_SMC_STATUS_OK
,
completed_addr
[
0
],
completed_addr
[
1
],
0
);
break
;
case
3
:
SMC_RET4
(
handle
,
INTEL_SIP_SMC_STATUS_OK
,
completed_addr
[
0
],
completed_addr
[
1
],
completed_addr
[
2
]);
break
;
case
0
:
SMC_RET4
(
handle
,
status
,
0
,
0
,
0
);
break
;
default:
SMC_RET1
(
handle
,
INTEL_SIP_SMC_STATUS_ERROR
);
}
break
;
default:
return
socfpga_sip_handler
(
smc_fid
,
x1
,
x2
,
x3
,
x4
,
cookie
,
handle
,
flags
);
}
}
DECLARE_RT_SVC
(
agilex_sip_svc
,
OEN_SIP_START
,
OEN_SIP_END
,
SMC_TYPE_FAST
,
NULL
,
sip_smc_handler
);
DECLARE_RT_SVC
(
agilex_sip_svc_std
,
OEN_SIP_START
,
OEN_SIP_END
,
SMC_TYPE_YIELD
,
NULL
,
sip_smc_handler
);
This diff is collapsed.
Click to expand it.
plat/intel/soc/agilex/socfpga_storage.c
0 → 100644
View file @
b514ee86
/*
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2019, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <assert.h>
#include <common/debug.h>
#include <common/tbbr/tbbr_img_def.h>
#include <drivers/io/io_block.h>
#include <drivers/io/io_driver.h>
#include <drivers/io/io_fip.h>
#include <drivers/io/io_memmap.h>
#include <drivers/io/io_storage.h>
#include <drivers/mmc.h>
#include <drivers/partition/partition.h>
#include <lib/mmio.h>
#include <tools_share/firmware_image_package.h>
#include "agilex_private.h"
#define PLAT_FIP_BASE (0)
#define PLAT_FIP_MAX_SIZE (0x1000000)
#define PLAT_MMC_DATA_BASE (0xffe3c000)
#define PLAT_MMC_DATA_SIZE (0x2000)
#define PLAT_QSPI_DATA_BASE (0x3C00000)
#define PLAT_QSPI_DATA_SIZE (0x1000000)
static
const
io_dev_connector_t
*
fip_dev_con
;
static
const
io_dev_connector_t
*
boot_dev_con
;
static
uintptr_t
fip_dev_handle
;
static
uintptr_t
boot_dev_handle
;
static
const
io_uuid_spec_t
bl2_uuid_spec
=
{
.
uuid
=
UUID_TRUSTED_BOOT_FIRMWARE_BL2
,
};
static
const
io_uuid_spec_t
bl31_uuid_spec
=
{
.
uuid
=
UUID_EL3_RUNTIME_FIRMWARE_BL31
,
};
static
const
io_uuid_spec_t
bl33_uuid_spec
=
{
.
uuid
=
UUID_NON_TRUSTED_FIRMWARE_BL33
,
};
uintptr_t
a2_lba_offset
;
const
char
a2
[]
=
{
0xa2
,
0x0
};
static
const
io_block_spec_t
gpt_block_spec
=
{
.
offset
=
0
,
.
length
=
MMC_BLOCK_SIZE
};
static
int
check_fip
(
const
uintptr_t
spec
);
static
int
check_dev
(
const
uintptr_t
spec
);
static
io_block_dev_spec_t
boot_dev_spec
;
static
int
(
*
register_io_dev
)(
const
io_dev_connector_t
**
);
static
io_block_spec_t
fip_spec
=
{
.
offset
=
PLAT_FIP_BASE
,
.
length
=
PLAT_FIP_MAX_SIZE
,
};
struct
plat_io_policy
{
uintptr_t
*
dev_handle
;
uintptr_t
image_spec
;
int
(
*
check
)(
const
uintptr_t
spec
);
};
static
const
struct
plat_io_policy
policies
[]
=
{
[
FIP_IMAGE_ID
]
=
{
&
boot_dev_handle
,
(
uintptr_t
)
&
fip_spec
,
check_dev
},
[
BL2_IMAGE_ID
]
=
{
&
fip_dev_handle
,
(
uintptr_t
)
&
bl2_uuid_spec
,
check_fip
},
[
BL31_IMAGE_ID
]
=
{
&
fip_dev_handle
,
(
uintptr_t
)
&
bl31_uuid_spec
,
check_fip
},
[
BL33_IMAGE_ID
]
=
{
&
fip_dev_handle
,
(
uintptr_t
)
&
bl33_uuid_spec
,
check_fip
},
[
GPT_IMAGE_ID
]
=
{
&
boot_dev_handle
,
(
uintptr_t
)
&
gpt_block_spec
,
check_dev
},
};
static
int
check_dev
(
const
uintptr_t
spec
)
{
int
result
;
uintptr_t
local_handle
;
result
=
io_dev_init
(
boot_dev_handle
,
(
uintptr_t
)
NULL
);
if
(
result
==
0
)
{
result
=
io_open
(
boot_dev_handle
,
spec
,
&
local_handle
);
if
(
result
==
0
)
io_close
(
local_handle
);
}
return
result
;
}
static
int
check_fip
(
const
uintptr_t
spec
)
{
int
result
;
uintptr_t
local_image_handle
;
result
=
io_dev_init
(
fip_dev_handle
,
(
uintptr_t
)
FIP_IMAGE_ID
);
if
(
result
==
0
)
{
result
=
io_open
(
fip_dev_handle
,
spec
,
&
local_image_handle
);
if
(
result
==
0
)
io_close
(
local_image_handle
);
}
return
result
;
}
void
socfpga_io_setup
(
int
boot_source
)
{
int
result
;
switch
(
boot_source
)
{
case
BOOT_SOURCE_SDMMC
:
register_io_dev
=
&
register_io_dev_block
;
boot_dev_spec
.
buffer
.
offset
=
PLAT_MMC_DATA_BASE
;
boot_dev_spec
.
buffer
.
length
=
MMC_BLOCK_SIZE
;
boot_dev_spec
.
ops
.
read
=
mmc_read_blocks
;
boot_dev_spec
.
ops
.
write
=
mmc_write_blocks
;
boot_dev_spec
.
block_size
=
MMC_BLOCK_SIZE
;
break
;
case
BOOT_SOURCE_QSPI
:
register_io_dev
=
&
register_io_dev_memmap
;
fip_spec
.
offset
=
fip_spec
.
offset
+
PLAT_QSPI_DATA_BASE
;
break
;
default:
ERROR
(
"Unsupported boot source
\n
"
);
panic
();
break
;
}
result
=
(
*
register_io_dev
)(
&
boot_dev_con
);
assert
(
result
==
0
);
result
=
register_io_dev_fip
(
&
fip_dev_con
);
assert
(
result
==
0
);
result
=
io_dev_open
(
boot_dev_con
,
(
uintptr_t
)
&
boot_dev_spec
,
&
boot_dev_handle
);
assert
(
result
==
0
);
result
=
io_dev_open
(
fip_dev_con
,
(
uintptr_t
)
NULL
,
&
fip_dev_handle
);
assert
(
result
==
0
);
if
(
boot_source
==
BOOT_SOURCE_SDMMC
)
{
partition_init
(
GPT_IMAGE_ID
);
fip_spec
.
offset
=
get_partition_entry
(
a2
)
->
start
;
}
(
void
)
result
;
}
int
plat_get_image_source
(
unsigned
int
image_id
,
uintptr_t
*
dev_handle
,
uintptr_t
*
image_spec
)
{
int
result
;
const
struct
plat_io_policy
*
policy
;
assert
(
image_id
<
ARRAY_SIZE
(
policies
));
policy
=
&
policies
[
image_id
];
result
=
policy
->
check
(
policy
->
image_spec
);
assert
(
result
==
0
);
*
image_spec
=
policy
->
image_spec
;
*
dev_handle
=
*
(
policy
->
dev_handle
);
return
result
;
}
This diff is collapsed.
Click to expand it.
plat/intel/soc/agilex/socfpga_topology.c
0 → 100644
View file @
b514ee86
/*
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <platform_def.h>
#include <lib/psci/psci.h>
static
const
unsigned
char
plat_power_domain_tree_desc
[]
=
{
1
,
4
};
/*******************************************************************************
* This function returns the default topology tree information.
******************************************************************************/
const
unsigned
char
*
plat_get_power_domain_tree_desc
(
void
)
{
return
plat_power_domain_tree_desc
;
}
/*******************************************************************************
* This function implements a part of the critical interface between the psci
* generic layer and the platform that allows the former to query the platform
* to convert an MPIDR to a unique linear index. An error code (-1) is returned
* in case the MPIDR is invalid.
******************************************************************************/
int
plat_core_pos_by_mpidr
(
u_register_t
mpidr
)
{
unsigned
int
cluster_id
,
cpu_id
;
mpidr
&=
MPIDR_AFFINITY_MASK
;
if
(
mpidr
&
~
(
MPIDR_CLUSTER_MASK
|
MPIDR_CPU_MASK
))
return
-
1
;
cluster_id
=
(
mpidr
>>
MPIDR_AFF1_SHIFT
)
&
MPIDR_AFFLVL_MASK
;
cpu_id
=
(
mpidr
>>
MPIDR_AFF0_SHIFT
)
&
MPIDR_AFFLVL_MASK
;
if
(
cluster_id
>=
PLATFORM_CLUSTER_COUNT
)
return
-
1
;
/*
* Validate cpu_id by checking whether it represents a CPU in
* one of the two clusters present on the platform.
*/
if
(
cpu_id
>=
PLATFORM_MAX_CPUS_PER_CLUSTER
)
return
-
1
;
return
(
cpu_id
+
(
cluster_id
*
4
));
}
This diff is collapsed.
Click to expand it.
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
Menu
Projects
Groups
Snippets
Help