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
0cc1e68a
Commit
0cc1e68a
authored
Jul 24, 2019
by
Soby Mathew
Committed by
TrustedFirmware Code Review
Jul 24, 2019
Browse files
Merge "rockchip: px30: support px30" into integration
parents
bc61a9b8
010d6ae3
Changes
14
Hide whitespace changes
Inline
Side-by-side
docs/plat/rockchip.rst
View file @
0cc1e68a
...
...
@@ -5,6 +5,7 @@ Trusted Firmware-A supports a number of Rockchip ARM SoCs from both
AARCH32 and AARCH64 fields.
This includes right now:
- px30: Quad-Core Cortex-A53
- rk3288: Quad-Core Cortex-A17 (past A12)
- rk3328: Quad-Core Cortex-A53
- rk3368: Octa-Core Cortex-A53
...
...
plat/rockchip/common/pmusram/cpus_on_fixed_addr.S
0 → 100644
View file @
0cc1e68a
/*
*
Copyright
(
c
)
2019
,
ARM
Limited
and
Contributors
.
All
rights
reserved
.
*
*
SPDX
-
License
-
Identifier
:
BSD
-
3
-
Clause
*/
#include <arch.h>
#include <asm_macros.S>
#include <platform_def.h>
#include <cpus_on_fixed_addr.h>
.
globl
sys_sleep_flag_sram
.
globl
pmu_cpuson_entrypoint
.
macro
pmusram_entry_func
_name
.
section
.
pmusram
.
entry
,
"ax"
.
type
\
_name
,
%
function
.
cfi_startproc
\
_name
:
.
endm
pmusram_entry_func
pmu_cpuson_entrypoint
adr
x5
,
sys_sleep_flag_sram
ldr
w2
,
[
x5
,
#
PSRAM_DT_PM_FLAG
]
tbz
w2
,
#
PM_WARM_BOOT_SHT
,
sys_resume_sp
ldr
x1
,
=
platform_cpu_warmboot
br
x1
sys_resume_sp
:
adr
x5
,
sys_sleep_flag_sram
ldr
x1
,
[
x5
,
#
PSRAM_DT_SP
]
mov
sp
,
x1
ddr_resume
:
ldr
x1
,
[
x5
,
#
PSRAM_DT_DDR_FUNC
]
cmp
x1
,
#
0
b.eq
sys_resume
blr
x1
sys_resume
:
ldr
x1
,
=
bl31_warm_entrypoint
br
x1
endfunc
pmu_cpuson_entrypoint
.
section
.
pmusram
.
data
,
"a"
.
align
3
sys_sleep_flag_sram
:
.
rept
PSRAM_DT_SIZE_WORDS
.
word
0
.
endr
plat/rockchip/common/pmusram/cpus_on_fixed_addr.h
0 → 100644
View file @
0cc1e68a
/*
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __CPU_ON_FIXED_ADDR_H__
#define __CPU_ON_FIXED_ADDR_H__
/*****************************************************************************
* define data offset in struct psram_data
*****************************************************************************/
#define PSRAM_DT_SP 0x0
#define PSRAM_DT_DDR_FUNC 0x8
#define PSRAM_DT_DDR_DATA 0x10
#define PSRAM_DT_DDRFLAG 0x18
#define PSRAM_DT_MPIDR 0x1c
#define PSRAM_DT_PM_FLAG 0x20
#define PSRAM_DT_END 0x24
/* reserve 4 byte */
#define PSRAM_DT_END_RES4 (PSRAM_DT_END + 4)
#define PSRAM_DT_SIZE_WORDS (PSRAM_DT_END_RES4 / 4)
#define PM_WARM_BOOT_SHT 0
#define PM_WARM_BOOT_BIT (1 << PM_WARM_BOOT_SHT)
#ifndef __ASSEMBLY__
struct
psram_data_t
{
uint64_t
sp
;
uint64_t
ddr_func
;
uint64_t
ddr_data
;
uint32_t
ddr_flag
;
uint32_t
boot_mpidr
;
uint32_t
pm_flag
;
};
CASSERT
(
__builtin_offsetof
(
struct
psram_data_t
,
sp
)
==
PSRAM_DT_SP
,
assert_psram_dt_sp_offset_mistmatch
);
CASSERT
(
__builtin_offsetof
(
struct
psram_data_t
,
ddr_func
)
==
PSRAM_DT_DDR_FUNC
,
assert_psram_dt_ddr_func_offset_mistmatch
);
CASSERT
(
__builtin_offsetof
(
struct
psram_data_t
,
ddr_data
)
==
PSRAM_DT_DDR_DATA
,
assert_psram_dt_ddr_data_offset_mistmatch
);
CASSERT
(
__builtin_offsetof
(
struct
psram_data_t
,
ddr_flag
)
==
PSRAM_DT_DDRFLAG
,
assert_psram_dt_ddr_flag_offset_mistmatch
);
CASSERT
(
__builtin_offsetof
(
struct
psram_data_t
,
boot_mpidr
)
==
PSRAM_DT_MPIDR
,
assert_psram_dt_mpidr_offset_mistmatch
);
extern
void
*
sys_sleep_flag_sram
;
#endif
/* __ASSEMBLY__ */
#endif
plat/rockchip/px30/drivers/pmu/plat_pmu_macros.S
0 → 100644
View file @
0cc1e68a
/*
*
Copyright
(
c
)
2019
,
ARM
Limited
and
Contributors
.
All
rights
reserved
.
*
*
SPDX
-
License
-
Identifier
:
BSD
-
3
-
Clause
*/
#include <arch.h>
#include <asm_macros.S>
#include <platform_def.h>
.
globl
clst_warmboot_data
.
macro
func_rockchip_clst_warmboot
.
endm
.
macro
rockchip_clst_warmboot_data
clst_warmboot_data
:
.
rept
PLATFORM_CLUSTER_COUNT
.
word
0
.
endr
.
endm
plat/rockchip/px30/drivers/pmu/pmu.c
0 → 100644
View file @
0cc1e68a
/*
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <errno.h>
#include <platform_def.h>
#include <arch_helpers.h>
#include <bl31/bl31.h>
#include <common/debug.h>
#include <drivers/console.h>
#include <drivers/delay_timer.h>
#include <lib/bakery_lock.h>
#include <lib/mmio.h>
#include <plat/common/platform.h>
#include <cpus_on_fixed_addr.h>
#include <plat_private.h>
#include <pmu.h>
#include <px30_def.h>
#include <soc.h>
DEFINE_BAKERY_LOCK
(
rockchip_pd_lock
);
#define rockchip_pd_lock_init() bakery_lock_init(&rockchip_pd_lock)
#define rockchip_pd_lock_get() bakery_lock_get(&rockchip_pd_lock)
#define rockchip_pd_lock_rls() bakery_lock_release(&rockchip_pd_lock)
static
struct
psram_data_t
*
psram_boot_cfg
=
(
struct
psram_data_t
*
)
&
sys_sleep_flag_sram
;
/*
* There are two ways to powering on or off on core.
* 1) Control it power domain into on or off in PMU_PWRDN_CON reg,
* it is core_pwr_pd mode
* 2) Enable the core power manage in PMU_CORE_PM_CON reg,
* then, if the core enter into wfi, it power domain will be
* powered off automatically. it is core_pwr_wfi or core_pwr_wfi_int mode
* so we need core_pm_cfg_info to distinguish which method be used now.
*/
static
uint32_t
cores_pd_cfg_info
[
PLATFORM_CORE_COUNT
]
#if USE_COHERENT_MEM
__attribute__
((
section
(
"tzfw_coherent_mem"
)))
#endif
;
struct
px30_sleep_ddr_data
{
uint32_t
clk_sel0
;
uint32_t
cru_mode_save
;
uint32_t
cru_pmu_mode_save
;
uint32_t
ddrc_hwlpctl
;
uint32_t
ddrc_pwrctrl
;
uint32_t
ddrgrf_con0
;
uint32_t
ddrgrf_con1
;
uint32_t
ddrstdby_con0
;
uint32_t
gpio0b_iomux
;
uint32_t
gpio0c_iomux
;
uint32_t
pmu_pwrmd_core_l
;
uint32_t
pmu_pwrmd_core_h
;
uint32_t
pmu_pwrmd_cmm_l
;
uint32_t
pmu_pwrmd_cmm_h
;
uint32_t
pmu_wkup_cfg2_l
;
uint32_t
pmu_cru_clksel_con0
;
uint32_t
pmugrf_soc_con0
;
uint32_t
pmusgrf_soc_con0
;
uint32_t
pmic_slp_iomux
;
uint32_t
pgrf_pvtm_con
[
2
];
uint32_t
cru_clk_gate
[
CRU_CLKGATES_CON_CNT
];
uint32_t
cru_pmu_clk_gate
[
CRU_PMU_CLKGATE_CON_CNT
];
uint32_t
cru_plls_con_save
[
END_PLL_ID
][
PLL_CON_CNT
];
uint32_t
cpu_qos
[
CPU_AXI_QOS_NUM_REGS
];
uint32_t
gpu_qos
[
CPU_AXI_QOS_NUM_REGS
];
uint32_t
isp_128m_qos
[
CPU_AXI_QOS_NUM_REGS
];
uint32_t
isp_rd_qos
[
CPU_AXI_QOS_NUM_REGS
];
uint32_t
isp_wr_qos
[
CPU_AXI_QOS_NUM_REGS
];
uint32_t
isp_m1_qos
[
CPU_AXI_QOS_NUM_REGS
];
uint32_t
vip_qos
[
CPU_AXI_QOS_NUM_REGS
];
uint32_t
rga_rd_qos
[
CPU_AXI_QOS_NUM_REGS
];
uint32_t
rga_wr_qos
[
CPU_AXI_QOS_NUM_REGS
];
uint32_t
vop_m0_qos
[
CPU_AXI_QOS_NUM_REGS
];
uint32_t
vop_m1_qos
[
CPU_AXI_QOS_NUM_REGS
];
uint32_t
vpu_qos
[
CPU_AXI_QOS_NUM_REGS
];
uint32_t
vpu_r128_qos
[
CPU_AXI_QOS_NUM_REGS
];
uint32_t
dcf_qos
[
CPU_AXI_QOS_NUM_REGS
];
uint32_t
dmac_qos
[
CPU_AXI_QOS_NUM_REGS
];
uint32_t
crypto_qos
[
CPU_AXI_QOS_NUM_REGS
];
uint32_t
gmac_qos
[
CPU_AXI_QOS_NUM_REGS
];
uint32_t
emmc_qos
[
CPU_AXI_QOS_NUM_REGS
];
uint32_t
nand_qos
[
CPU_AXI_QOS_NUM_REGS
];
uint32_t
sdio_qos
[
CPU_AXI_QOS_NUM_REGS
];
uint32_t
sfc_qos
[
CPU_AXI_QOS_NUM_REGS
];
uint32_t
sdmmc_qos
[
CPU_AXI_QOS_NUM_REGS
];
uint32_t
usb_host_qos
[
CPU_AXI_QOS_NUM_REGS
];
uint32_t
usb_otg_qos
[
CPU_AXI_QOS_NUM_REGS
];
};
static
struct
px30_sleep_ddr_data
ddr_data
#if USE_COHERENT_MEM
__attribute__
((
section
(
"tzfw_coherent_mem"
)))
#endif
;
static
inline
uint32_t
get_cpus_pwr_domain_cfg_info
(
uint32_t
cpu_id
)
{
assert
(
cpu_id
<
PLATFORM_CORE_COUNT
);
return
cores_pd_cfg_info
[
cpu_id
];
}
static
inline
void
set_cpus_pwr_domain_cfg_info
(
uint32_t
cpu_id
,
uint32_t
value
)
{
assert
(
cpu_id
<
PLATFORM_CORE_COUNT
);
cores_pd_cfg_info
[
cpu_id
]
=
value
;
#if !USE_COHERENT_MEM
flush_dcache_range
((
uintptr_t
)
&
cores_pd_cfg_info
[
cpu_id
],
sizeof
(
uint32_t
));
#endif
}
static
inline
uint32_t
pmu_power_domain_st
(
uint32_t
pd
)
{
return
mmio_read_32
(
PMU_BASE
+
PMU_PWRDN_ST
)
&
BIT
(
pd
)
?
pmu_pd_off
:
pmu_pd_on
;
}
static
int
pmu_power_domain_ctr
(
uint32_t
pd
,
uint32_t
pd_state
)
{
uint32_t
loop
=
0
;
int
ret
=
0
;
rockchip_pd_lock_get
();
mmio_write_32
(
PMU_BASE
+
PMU_PWRDN_CON
,
BITS_WITH_WMASK
(
pd_state
,
0x1
,
pd
));
dsb
();
while
((
pmu_power_domain_st
(
pd
)
!=
pd_state
)
&&
(
loop
<
PD_CTR_LOOP
))
{
udelay
(
1
);
loop
++
;
}
if
(
pmu_power_domain_st
(
pd
)
!=
pd_state
)
{
WARN
(
"%s: %d, %d, error!
\n
"
,
__func__
,
pd
,
pd_state
);
ret
=
-
EINVAL
;
}
rockchip_pd_lock_rls
();
return
ret
;
}
static
inline
uint32_t
pmu_bus_idle_st
(
uint32_t
bus
)
{
return
!!
((
mmio_read_32
(
PMU_BASE
+
PMU_BUS_IDLE_ST
)
&
BIT
(
bus
))
&&
(
mmio_read_32
(
PMU_BASE
+
PMU_BUS_IDLE_ST
)
&
BIT
(
bus
+
16
)));
}
static
void
pmu_bus_idle_req
(
uint32_t
bus
,
uint32_t
state
)
{
uint32_t
wait_cnt
=
0
;
mmio_write_32
(
PMU_BASE
+
PMU_BUS_IDLE_REQ
,
BITS_WITH_WMASK
(
state
,
0x1
,
bus
));
while
(
pmu_bus_idle_st
(
bus
)
!=
state
&&
wait_cnt
<
BUS_IDLE_LOOP
)
{
udelay
(
1
);
wait_cnt
++
;
}
if
(
pmu_bus_idle_st
(
bus
)
!=
state
)
WARN
(
"%s:idle_st=0x%x, bus_id=%d
\n
"
,
__func__
,
mmio_read_32
(
PMU_BASE
+
PMU_BUS_IDLE_ST
),
bus
);
}
static
void
qos_save
(
void
)
{
/* scu powerdomain will power off, so cpu qos should be saved */
SAVE_QOS
(
ddr_data
.
cpu_qos
,
CPU
);
if
(
pmu_power_domain_st
(
PD_GPU
)
==
pmu_pd_on
)
SAVE_QOS
(
ddr_data
.
gpu_qos
,
GPU
);
if
(
pmu_power_domain_st
(
PD_VI
)
==
pmu_pd_on
)
{
SAVE_QOS
(
ddr_data
.
isp_128m_qos
,
ISP_128M
);
SAVE_QOS
(
ddr_data
.
isp_rd_qos
,
ISP_RD
);
SAVE_QOS
(
ddr_data
.
isp_wr_qos
,
ISP_WR
);
SAVE_QOS
(
ddr_data
.
isp_m1_qos
,
ISP_M1
);
SAVE_QOS
(
ddr_data
.
vip_qos
,
VIP
);
}
if
(
pmu_power_domain_st
(
PD_VO
)
==
pmu_pd_on
)
{
SAVE_QOS
(
ddr_data
.
rga_rd_qos
,
RGA_RD
);
SAVE_QOS
(
ddr_data
.
rga_wr_qos
,
RGA_WR
);
SAVE_QOS
(
ddr_data
.
vop_m0_qos
,
VOP_M0
);
SAVE_QOS
(
ddr_data
.
vop_m1_qos
,
VOP_M1
);
}
if
(
pmu_power_domain_st
(
PD_VPU
)
==
pmu_pd_on
)
{
SAVE_QOS
(
ddr_data
.
vpu_qos
,
VPU
);
SAVE_QOS
(
ddr_data
.
vpu_r128_qos
,
VPU_R128
);
}
if
(
pmu_power_domain_st
(
PD_MMC_NAND
)
==
pmu_pd_on
)
{
SAVE_QOS
(
ddr_data
.
emmc_qos
,
EMMC
);
SAVE_QOS
(
ddr_data
.
nand_qos
,
NAND
);
SAVE_QOS
(
ddr_data
.
sdio_qos
,
SDIO
);
SAVE_QOS
(
ddr_data
.
sfc_qos
,
SFC
);
}
if
(
pmu_power_domain_st
(
PD_GMAC
)
==
pmu_pd_on
)
SAVE_QOS
(
ddr_data
.
gmac_qos
,
GMAC
);
if
(
pmu_power_domain_st
(
PD_CRYPTO
)
==
pmu_pd_on
)
SAVE_QOS
(
ddr_data
.
crypto_qos
,
CRYPTO
);
if
(
pmu_power_domain_st
(
PD_SDCARD
)
==
pmu_pd_on
)
SAVE_QOS
(
ddr_data
.
sdmmc_qos
,
SDMMC
);
if
(
pmu_power_domain_st
(
PD_USB
)
==
pmu_pd_on
)
{
SAVE_QOS
(
ddr_data
.
usb_host_qos
,
USB_HOST
);
SAVE_QOS
(
ddr_data
.
usb_otg_qos
,
USB_OTG
);
}
}
static
void
qos_restore
(
void
)
{
RESTORE_QOS
(
ddr_data
.
cpu_qos
,
CPU
);
if
(
pmu_power_domain_st
(
PD_GPU
)
==
pmu_pd_on
)
RESTORE_QOS
(
ddr_data
.
gpu_qos
,
GPU
);
if
(
pmu_power_domain_st
(
PD_VI
)
==
pmu_pd_on
)
{
RESTORE_QOS
(
ddr_data
.
isp_128m_qos
,
ISP_128M
);
RESTORE_QOS
(
ddr_data
.
isp_rd_qos
,
ISP_RD
);
RESTORE_QOS
(
ddr_data
.
isp_wr_qos
,
ISP_WR
);
RESTORE_QOS
(
ddr_data
.
isp_m1_qos
,
ISP_M1
);
RESTORE_QOS
(
ddr_data
.
vip_qos
,
VIP
);
}
if
(
pmu_power_domain_st
(
PD_VO
)
==
pmu_pd_on
)
{
RESTORE_QOS
(
ddr_data
.
rga_rd_qos
,
RGA_RD
);
RESTORE_QOS
(
ddr_data
.
rga_wr_qos
,
RGA_WR
);
RESTORE_QOS
(
ddr_data
.
vop_m0_qos
,
VOP_M0
);
RESTORE_QOS
(
ddr_data
.
vop_m1_qos
,
VOP_M1
);
}
if
(
pmu_power_domain_st
(
PD_VPU
)
==
pmu_pd_on
)
{
RESTORE_QOS
(
ddr_data
.
vpu_qos
,
VPU
);
RESTORE_QOS
(
ddr_data
.
vpu_r128_qos
,
VPU_R128
);
}
if
(
pmu_power_domain_st
(
PD_MMC_NAND
)
==
pmu_pd_on
)
{
RESTORE_QOS
(
ddr_data
.
emmc_qos
,
EMMC
);
RESTORE_QOS
(
ddr_data
.
nand_qos
,
NAND
);
RESTORE_QOS
(
ddr_data
.
sdio_qos
,
SDIO
);
RESTORE_QOS
(
ddr_data
.
sfc_qos
,
SFC
);
}
if
(
pmu_power_domain_st
(
PD_GMAC
)
==
pmu_pd_on
)
RESTORE_QOS
(
ddr_data
.
gmac_qos
,
GMAC
);
if
(
pmu_power_domain_st
(
PD_CRYPTO
)
==
pmu_pd_on
)
RESTORE_QOS
(
ddr_data
.
crypto_qos
,
CRYPTO
);
if
(
pmu_power_domain_st
(
PD_SDCARD
)
==
pmu_pd_on
)
RESTORE_QOS
(
ddr_data
.
sdmmc_qos
,
SDMMC
);
if
(
pmu_power_domain_st
(
PD_USB
)
==
pmu_pd_on
)
{
RESTORE_QOS
(
ddr_data
.
usb_host_qos
,
USB_HOST
);
RESTORE_QOS
(
ddr_data
.
usb_otg_qos
,
USB_OTG
);
}
}
static
int
pmu_set_power_domain
(
uint32_t
pd_id
,
uint32_t
pd_state
)
{
uint32_t
state
;
if
(
pmu_power_domain_st
(
pd_id
)
==
pd_state
)
goto
out
;
if
(
pd_state
==
pmu_pd_on
)
pmu_power_domain_ctr
(
pd_id
,
pd_state
);
state
=
(
pd_state
==
pmu_pd_off
)
?
bus_idle
:
bus_active
;
switch
(
pd_id
)
{
case
PD_GPU
:
pmu_bus_idle_req
(
BUS_ID_GPU
,
state
);
break
;
case
PD_VI
:
pmu_bus_idle_req
(
BUS_ID_VI
,
state
);
break
;
case
PD_VO
:
pmu_bus_idle_req
(
BUS_ID_VO
,
state
);
break
;
case
PD_VPU
:
pmu_bus_idle_req
(
BUS_ID_VPU
,
state
);
break
;
case
PD_MMC_NAND
:
pmu_bus_idle_req
(
BUS_ID_MMC
,
state
);
break
;
case
PD_GMAC
:
pmu_bus_idle_req
(
BUS_ID_GMAC
,
state
);
break
;
case
PD_CRYPTO
:
pmu_bus_idle_req
(
BUS_ID_CRYPTO
,
state
);
break
;
case
PD_SDCARD
:
pmu_bus_idle_req
(
BUS_ID_SDCARD
,
state
);
break
;
case
PD_USB
:
pmu_bus_idle_req
(
BUS_ID_USB
,
state
);
break
;
default:
break
;
}
if
(
pd_state
==
pmu_pd_off
)
pmu_power_domain_ctr
(
pd_id
,
pd_state
);
out:
return
0
;
}
static
uint32_t
pmu_powerdomain_state
;
static
void
pmu_power_domains_suspend
(
void
)
{
uint32_t
clkgt_save
[
CRU_CLKGATES_CON_CNT
+
CRU_PMU_CLKGATE_CON_CNT
];
clk_gate_con_save
(
clkgt_save
);
clk_gate_con_disable
();
qos_save
();
pmu_powerdomain_state
=
mmio_read_32
(
PMU_BASE
+
PMU_PWRDN_ST
);
pmu_set_power_domain
(
PD_GPU
,
pmu_pd_off
);
pmu_set_power_domain
(
PD_VI
,
pmu_pd_off
);
pmu_set_power_domain
(
PD_VO
,
pmu_pd_off
);
pmu_set_power_domain
(
PD_VPU
,
pmu_pd_off
);
pmu_set_power_domain
(
PD_MMC_NAND
,
pmu_pd_off
);
pmu_set_power_domain
(
PD_GMAC
,
pmu_pd_off
);
pmu_set_power_domain
(
PD_CRYPTO
,
pmu_pd_off
);
pmu_set_power_domain
(
PD_SDCARD
,
pmu_pd_off
);
pmu_set_power_domain
(
PD_USB
,
pmu_pd_off
);
clk_gate_con_restore
(
clkgt_save
);
}
static
void
pmu_power_domains_resume
(
void
)
{
uint32_t
clkgt_save
[
CRU_CLKGATES_CON_CNT
+
CRU_PMU_CLKGATE_CON_CNT
];
clk_gate_con_save
(
clkgt_save
);
clk_gate_con_disable
();
if
(
!
(
pmu_powerdomain_state
&
BIT
(
PD_USB
)))
pmu_set_power_domain
(
PD_USB
,
pmu_pd_on
);
if
(
!
(
pmu_powerdomain_state
&
BIT
(
PD_SDCARD
)))
pmu_set_power_domain
(
PD_SDCARD
,
pmu_pd_on
);
if
(
!
(
pmu_powerdomain_state
&
BIT
(
PD_CRYPTO
)))
pmu_set_power_domain
(
PD_CRYPTO
,
pmu_pd_on
);
if
(
!
(
pmu_powerdomain_state
&
BIT
(
PD_GMAC
)))
pmu_set_power_domain
(
PD_GMAC
,
pmu_pd_on
);
if
(
!
(
pmu_powerdomain_state
&
BIT
(
PD_MMC_NAND
)))
pmu_set_power_domain
(
PD_MMC_NAND
,
pmu_pd_on
);
if
(
!
(
pmu_powerdomain_state
&
BIT
(
PD_VPU
)))
pmu_set_power_domain
(
PD_VPU
,
pmu_pd_on
);
if
(
!
(
pmu_powerdomain_state
&
BIT
(
PD_VO
)))
pmu_set_power_domain
(
PD_VO
,
pmu_pd_on
);
if
(
!
(
pmu_powerdomain_state
&
BIT
(
PD_VI
)))
pmu_set_power_domain
(
PD_VI
,
pmu_pd_on
);
if
(
!
(
pmu_powerdomain_state
&
BIT
(
PD_GPU
)))
pmu_set_power_domain
(
PD_GPU
,
pmu_pd_on
);
qos_restore
();
clk_gate_con_restore
(
clkgt_save
);
}
static
int
check_cpu_wfie
(
uint32_t
cpu
)
{
uint32_t
loop
=
0
,
wfie_msk
=
CKECK_WFEI_MSK
<<
cpu
;
while
(
!
(
mmio_read_32
(
GRF_BASE
+
GRF_CPU_STATUS1
)
&
wfie_msk
)
&&
(
loop
<
WFEI_CHECK_LOOP
))
{
udelay
(
1
);
loop
++
;
}
if
((
mmio_read_32
(
GRF_BASE
+
GRF_CPU_STATUS1
)
&
wfie_msk
)
==
0
)
{
WARN
(
"%s: %d, %d, error!
\n
"
,
__func__
,
cpu
,
wfie_msk
);
return
-
EINVAL
;
}
return
0
;
}
static
int
cpus_power_domain_on
(
uint32_t
cpu_id
)
{
uint32_t
cpu_pd
,
apm_value
,
cfg_info
,
loop
=
0
;
cpu_pd
=
PD_CPU0
+
cpu_id
;
cfg_info
=
get_cpus_pwr_domain_cfg_info
(
cpu_id
);
if
(
cfg_info
==
core_pwr_pd
)
{
/* disable apm cfg */
mmio_write_32
(
PMU_BASE
+
PMU_CPUAPM_CON
(
cpu_id
),
WITH_16BITS_WMSK
(
CORES_PM_DISABLE
));
if
(
pmu_power_domain_st
(
cpu_pd
)
==
pmu_pd_on
)
{
mmio_write_32
(
PMU_BASE
+
PMU_CPUAPM_CON
(
cpu_id
),
WITH_16BITS_WMSK
(
CORES_PM_DISABLE
));
pmu_power_domain_ctr
(
cpu_pd
,
pmu_pd_off
);
}
pmu_power_domain_ctr
(
cpu_pd
,
pmu_pd_on
);
}
else
{
/* wait cpu down */
while
(
pmu_power_domain_st
(
cpu_pd
)
==
pmu_pd_on
&&
loop
<
100
)
{
udelay
(
2
);
loop
++
;
}
/* return error if can't wait cpu down */
if
(
pmu_power_domain_st
(
cpu_pd
)
==
pmu_pd_on
)
{
WARN
(
"%s:can't wait cpu down
\n
"
,
__func__
);
return
-
EINVAL
;
}
/* power up cpu in power down state */
apm_value
=
BIT
(
core_pm_sft_wakeup_en
);
mmio_write_32
(
PMU_BASE
+
PMU_CPUAPM_CON
(
cpu_id
),
WITH_16BITS_WMSK
(
apm_value
));
}
return
0
;
}
static
int
cpus_power_domain_off
(
uint32_t
cpu_id
,
uint32_t
pd_cfg
)
{
uint32_t
cpu_pd
,
apm_value
;
cpu_pd
=
PD_CPU0
+
cpu_id
;
if
(
pmu_power_domain_st
(
cpu_pd
)
==
pmu_pd_off
)
return
0
;
if
(
pd_cfg
==
core_pwr_pd
)
{
if
(
check_cpu_wfie
(
cpu_id
))
return
-
EINVAL
;
/* disable apm cfg */
mmio_write_32
(
PMU_BASE
+
PMU_CPUAPM_CON
(
cpu_id
),
WITH_16BITS_WMSK
(
CORES_PM_DISABLE
));
set_cpus_pwr_domain_cfg_info
(
cpu_id
,
pd_cfg
);
pmu_power_domain_ctr
(
cpu_pd
,
pmu_pd_off
);
}
else
{
set_cpus_pwr_domain_cfg_info
(
cpu_id
,
pd_cfg
);
apm_value
=
BIT
(
core_pm_en
)
|
BIT
(
core_pm_dis_int
);
if
(
pd_cfg
==
core_pwr_wfi_int
)
apm_value
|=
BIT
(
core_pm_int_wakeup_en
);
mmio_write_32
(
PMU_BASE
+
PMU_CPUAPM_CON
(
cpu_id
),
WITH_16BITS_WMSK
(
apm_value
));
}
return
0
;
}
static
void
nonboot_cpus_off
(
void
)
{
uint32_t
boot_cpu
,
cpu
;
boot_cpu
=
plat_my_core_pos
();
for
(
cpu
=
0
;
cpu
<
PLATFORM_CORE_COUNT
;
cpu
++
)
{
if
(
cpu
==
boot_cpu
)
continue
;
cpus_power_domain_off
(
cpu
,
core_pwr_pd
);
}
}
int
rockchip_soc_cores_pwr_dm_on
(
unsigned
long
mpidr
,
uint64_t
entrypoint
)
{
uint32_t
cpu_id
=
plat_core_pos_by_mpidr
(
mpidr
);
assert
(
cpu_id
<
PLATFORM_CORE_COUNT
);
assert
(
cpuson_flags
[
cpu_id
]
==
0
);
cpuson_flags
[
cpu_id
]
=
PMU_CPU_HOTPLUG
;
cpuson_entry_point
[
cpu_id
]
=
entrypoint
;
dsb
();
cpus_power_domain_on
(
cpu_id
);
return
PSCI_E_SUCCESS
;
}
int
rockchip_soc_cores_pwr_dm_on_finish
(
void
)
{
uint32_t
cpu_id
=
plat_my_core_pos
();
mmio_write_32
(
PMU_BASE
+
PMU_CPUAPM_CON
(
cpu_id
),
WITH_16BITS_WMSK
(
CORES_PM_DISABLE
));
return
PSCI_E_SUCCESS
;
}
int
rockchip_soc_cores_pwr_dm_off
(
void
)
{
uint32_t
cpu_id
=
plat_my_core_pos
();
cpus_power_domain_off
(
cpu_id
,
core_pwr_wfi
);
return
PSCI_E_SUCCESS
;
}
int
rockchip_soc_cores_pwr_dm_suspend
(
void
)
{
uint32_t
cpu_id
=
plat_my_core_pos
();
assert
(
cpu_id
<
PLATFORM_CORE_COUNT
);
assert
(
cpuson_flags
[
cpu_id
]
==
0
);
cpuson_flags
[
cpu_id
]
=
PMU_CPU_AUTO_PWRDN
;
cpuson_entry_point
[
cpu_id
]
=
plat_get_sec_entrypoint
();
dsb
();
cpus_power_domain_off
(
cpu_id
,
core_pwr_wfi_int
);
return
PSCI_E_SUCCESS
;
}
int
rockchip_soc_cores_pwr_dm_resume
(
void
)
{
uint32_t
cpu_id
=
plat_my_core_pos
();
/* Disable core_pm */
mmio_write_32
(
PMU_BASE
+
PMU_CPUAPM_CON
(
cpu_id
),
WITH_16BITS_WMSK
(
CORES_PM_DISABLE
));
return
PSCI_E_SUCCESS
;
}
#define CLK_MSK_GATING(msk, con) \
mmio_write_32(CRU_BASE + (con), ((msk) << 16) | 0xffff)
#define CLK_MSK_UNGATING(msk, con) \
mmio_write_32(CRU_BASE + (con), ((~(msk)) << 16) | 0xffff)
static
uint32_t
clk_ungt_msk
[
CRU_CLKGATES_CON_CNT
]
=
{
0xe0ff
,
0xffff
,
0x0000
,
0x0000
,
0x0000
,
0x0380
,
0x0000
,
0x0000
,
0x07c0
,
0x0000
,
0x0000
,
0x000f
,
0x0061
,
0x1f02
,
0x0440
,
0x1801
,
0x004b
,
0x0000
};
static
uint32_t
clk_pmu_ungt_msk
[
CRU_PMU_CLKGATE_CON_CNT
]
=
{
0xf1ff
,
0x0310
};
void
clk_gate_suspend
(
void
)
{
int
i
;
for
(
i
=
0
;
i
<
CRU_CLKGATES_CON_CNT
;
i
++
)
{
ddr_data
.
cru_clk_gate
[
i
]
=
mmio_read_32
(
CRU_BASE
+
CRU_CLKGATES_CON
(
i
));
mmio_write_32
(
CRU_BASE
+
CRU_CLKGATES_CON
(
i
),
WITH_16BITS_WMSK
(
~
clk_ungt_msk
[
i
]));
}
for
(
i
=
0
;
i
<
CRU_PMU_CLKGATE_CON_CNT
;
i
++
)
{
ddr_data
.
cru_pmu_clk_gate
[
i
]
=
mmio_read_32
(
PMUCRU_BASE
+
CRU_PMU_CLKGATES_CON
(
i
));
mmio_write_32
(
PMUCRU_BASE
+
CRU_PMU_CLKGATES_CON
(
i
),
WITH_16BITS_WMSK
(
~
clk_pmu_ungt_msk
[
i
]));
}
}
void
clk_gate_resume
(
void
)
{
int
i
;
for
(
i
=
0
;
i
<
CRU_PMU_CLKGATE_CON_CNT
;
i
++
)
mmio_write_32
(
PMUCRU_BASE
+
CRU_PMU_CLKGATES_CON
(
i
),
WITH_16BITS_WMSK
(
ddr_data
.
cru_pmu_clk_gate
[
i
]));
for
(
i
=
0
;
i
<
CRU_CLKGATES_CON_CNT
;
i
++
)
mmio_write_32
(
CRU_BASE
+
CRU_CLKGATES_CON
(
i
),
WITH_16BITS_WMSK
(
ddr_data
.
cru_clk_gate
[
i
]));
}
static
void
pvtm_32k_config
(
void
)
{
uint32_t
pvtm_freq_khz
,
pvtm_div
;
ddr_data
.
pmu_cru_clksel_con0
=
mmio_read_32
(
PMUCRU_BASE
+
CRU_PMU_CLKSELS_CON
(
0
));
ddr_data
.
pgrf_pvtm_con
[
0
]
=
mmio_read_32
(
PMUGRF_BASE
+
PMUGRF_PVTM_CON0
);
ddr_data
.
pgrf_pvtm_con
[
1
]
=
mmio_read_32
(
PMUGRF_BASE
+
PMUGRF_PVTM_CON1
);
mmio_write_32
(
PMUGRF_BASE
+
PMUGRF_PVTM_CON0
,
BITS_WITH_WMASK
(
0
,
0x3
,
pgrf_pvtm_st
));
dsb
();
mmio_write_32
(
PMUGRF_BASE
+
PMUGRF_PVTM_CON0
,
BITS_WITH_WMASK
(
1
,
0x1
,
pgrf_pvtm_en
));
dsb
();
mmio_write_32
(
PMUGRF_BASE
+
PMUGRF_PVTM_CON1
,
PVTM_CALC_CNT
);
dsb
();
mmio_write_32
(
PMUGRF_BASE
+
PMUGRF_PVTM_CON0
,
BITS_WITH_WMASK
(
1
,
0x1
,
pgrf_pvtm_st
));
/* pmugrf_pvtm_st0 will be clear after PVTM start,
* which will cost about 6 cycles of pvtm at least.
* So we wait 30 cycles of pvtm for security.
*/
while
(
mmio_read_32
(
PMUGRF_BASE
+
PMUGRF_PVTM_ST1
)
<
30
)
;
dsb
();
while
(
!
(
mmio_read_32
(
PMUGRF_BASE
+
PMUGRF_PVTM_ST0
)
&
0x1
))
;
pvtm_freq_khz
=
(
mmio_read_32
(
PMUGRF_BASE
+
PMUGRF_PVTM_ST1
)
*
24000
+
PVTM_CALC_CNT
/
2
)
/
PVTM_CALC_CNT
;
pvtm_div
=
(
pvtm_freq_khz
+
16
)
/
32
;
/* pvtm_div = div_factor << 2 + 1,
* so div_factor = (pvtm_div - 1) >> 2.
* But the operation ">> 2" will clear the low bit of pvtm_div,
* so we don't have to do "- 1" for compasation
*/
pvtm_div
=
pvtm_div
>>
2
;
if
(
pvtm_div
>
0x3f
)
pvtm_div
=
0x3f
;
mmio_write_32
(
PMUGRF_BASE
+
PMUGRF_PVTM_CON0
,
BITS_WITH_WMASK
(
pvtm_div
,
0x3f
,
pgrf_pvtm_div
));
/* select pvtm as 32k source */
mmio_write_32
(
PMUCRU_BASE
+
CRU_PMU_CLKSELS_CON
(
0
),
BITS_WITH_WMASK
(
1
,
0x3
,
14
));
}
static
void
pvtm_32k_config_restore
(
void
)
{
mmio_write_32
(
PMUCRU_BASE
+
CRU_PMU_CLKSELS_CON
(
0
),
ddr_data
.
pmu_cru_clksel_con0
|
BITS_WMSK
(
0x3
,
14
));
mmio_write_32
(
PMUGRF_BASE
+
PMUGRF_PVTM_CON0
,
WITH_16BITS_WMSK
(
ddr_data
.
pgrf_pvtm_con
[
0
]));
mmio_write_32
(
PMUGRF_BASE
+
PMUGRF_PVTM_CON1
,
ddr_data
.
pgrf_pvtm_con
[
1
]);
}
static
void
ddr_sleep_config
(
void
)
{
/* disable ddr pd, sr */
ddr_data
.
ddrc_pwrctrl
=
mmio_read_32
(
DDR_UPCTL_BASE
+
0x30
);
mmio_write_32
(
DDR_UPCTL_BASE
+
0x30
,
BITS_WITH_WMASK
(
0x0
,
0x3
,
0
));
/* disable ddr auto gt */
ddr_data
.
ddrgrf_con1
=
mmio_read_32
(
DDRGRF_BASE
+
0x4
);
mmio_write_32
(
DDRGRF_BASE
+
0x4
,
BITS_WITH_WMASK
(
0x0
,
0x1f
,
0
));
/* disable ddr standby */
ddr_data
.
ddrstdby_con0
=
mmio_read_32
(
DDR_STDBY_BASE
+
0x0
);
mmio_write_32
(
DDR_STDBY_BASE
+
0x0
,
BITS_WITH_WMASK
(
0x0
,
0x1
,
0
));
while
((
mmio_read_32
(
DDR_UPCTL_BASE
+
0x4
)
&
0x7
)
!=
1
)
;
/* ddr pmu ctrl */
ddr_data
.
ddrgrf_con0
=
mmio_read_32
(
DDRGRF_BASE
+
0x0
);
mmio_write_32
(
DDRGRF_BASE
+
0x0
,
BITS_WITH_WMASK
(
0x0
,
0x1
,
5
));
dsb
();
mmio_write_32
(
DDRGRF_BASE
+
0x0
,
BITS_WITH_WMASK
(
0x1
,
0x1
,
4
));
/* ddr ret sel */
ddr_data
.
pmugrf_soc_con0
=
mmio_read_32
(
PMUGRF_BASE
+
PMUGRF_SOC_CON
(
0
));
mmio_write_32
(
PMUGRF_BASE
+
PMUGRF_SOC_CON
(
0
),
BITS_WITH_WMASK
(
0x0
,
0x1
,
12
));
}
static
void
ddr_sleep_config_restore
(
void
)
{
/* restore ddr ret sel */
mmio_write_32
(
PMUGRF_BASE
+
PMUGRF_SOC_CON
(
0
),
ddr_data
.
pmugrf_soc_con0
|
BITS_WMSK
(
0x1
,
12
));
/* restore ddr pmu ctrl */
mmio_write_32
(
DDRGRF_BASE
+
0x0
,
ddr_data
.
ddrgrf_con0
|
BITS_WMSK
(
0x1
,
4
));
dsb
();
mmio_write_32
(
DDRGRF_BASE
+
0x0
,
ddr_data
.
ddrgrf_con0
|
BITS_WMSK
(
0x1
,
5
));
/* restore ddr standby */
mmio_write_32
(
DDR_STDBY_BASE
+
0x0
,
ddr_data
.
ddrstdby_con0
|
BITS_WMSK
(
0x1
,
0
));
/* restore ddr auto gt */
mmio_write_32
(
DDRGRF_BASE
+
0x4
,
ddr_data
.
ddrgrf_con1
|
BITS_WMSK
(
0x1f
,
0
));
/* restore ddr pd, sr */
mmio_write_32
(
DDR_UPCTL_BASE
+
0x30
,
ddr_data
.
ddrc_pwrctrl
|
BITS_WMSK
(
0x3
,
0
));
}
static
void
pmu_sleep_config
(
void
)
{
uint32_t
pwrmd_core_lo
,
pwrmd_core_hi
,
pwrmd_com_lo
,
pwrmd_com_hi
;
uint32_t
pmu_wkup_cfg2_lo
;
uint32_t
clk_freq_khz
;
/* save pmic_sleep iomux gpio0_a4 */
ddr_data
.
pmic_slp_iomux
=
mmio_read_32
(
PMUGRF_BASE
+
GPIO0A_IOMUX
);
ddr_data
.
pmu_pwrmd_core_l
=
mmio_read_32
(
PMU_BASE
+
PMU_PWRMODE_CORE_LO
);
ddr_data
.
pmu_pwrmd_core_h
=
mmio_read_32
(
PMU_BASE
+
PMU_PWRMODE_CORE_HI
);
ddr_data
.
pmu_pwrmd_cmm_l
=
mmio_read_32
(
PMU_BASE
+
PMU_PWRMODE_COMMON_CON_LO
);
ddr_data
.
pmu_pwrmd_cmm_h
=
mmio_read_32
(
PMU_BASE
+
PMU_PWRMODE_COMMON_CON_HI
);
ddr_data
.
pmu_wkup_cfg2_l
=
mmio_read_32
(
PMU_BASE
+
PMU_WKUP_CFG2_LO
);
pwrmd_core_lo
=
BIT
(
pmu_global_int_dis
)
|
BIT
(
pmu_core_src_gt
)
|
BIT
(
pmu_cpu0_pd
)
|
BIT
(
pmu_clr_core
)
|
BIT
(
pmu_scu_pd
)
|
BIT
(
pmu_l2_idle
)
|
BIT
(
pmu_l2_flush
)
|
BIT
(
pmu_clr_bus2main
)
|
BIT
(
pmu_clr_peri2msch
);
pwrmd_core_hi
=
BIT
(
pmu_dpll_pd_en
)
|
BIT
(
pmu_apll_pd_en
)
|
BIT
(
pmu_cpll_pd_en
)
|
BIT
(
pmu_gpll_pd_en
)
|
BIT
(
pmu_npll_pd_en
);
pwrmd_com_lo
=
BIT
(
pmu_mode_en
)
|
BIT
(
pmu_pll_pd
)
|
BIT
(
pmu_pmu_use_if
)
|
BIT
(
pmu_alive_use_if
)
|
BIT
(
pmu_osc_dis
)
|
BIT
(
pmu_sref_enter
)
|
BIT
(
pmu_ddrc_gt
)
|
BIT
(
pmu_clr_pmu
)
|
BIT
(
pmu_clr_peri_pmu
);
pwrmd_com_hi
=
BIT
(
pmu_clr_bus
)
|
BIT
(
pmu_clr_msch
)
|
BIT
(
pmu_wakeup_begin_cfg
);
pmu_wkup_cfg2_lo
=
BIT
(
pmu_cluster_wkup_en
)
|
BIT
(
pmu_gpio_wkup_en
)
|
BIT
(
pmu_timer_wkup_en
);
/* set pmic_sleep iomux gpio0_a4 */
mmio_write_32
(
PMUGRF_BASE
+
GPIO0A_IOMUX
,
BITS_WITH_WMASK
(
1
,
0x3
,
8
));
clk_freq_khz
=
32
;
mmio_write_32
(
PMU_BASE
+
PMU_OSC_CNT_LO
,
WITH_16BITS_WMSK
(
clk_freq_khz
*
32
&
0xffff
));
mmio_write_32
(
PMU_BASE
+
PMU_OSC_CNT_HI
,
WITH_16BITS_WMSK
(
clk_freq_khz
*
32
>>
16
));
mmio_write_32
(
PMU_BASE
+
PMU_STABLE_CNT_LO
,
WITH_16BITS_WMSK
(
clk_freq_khz
*
32
&
0xffff
));
mmio_write_32
(
PMU_BASE
+
PMU_STABLE_CNT_HI
,
WITH_16BITS_WMSK
(
clk_freq_khz
*
32
>>
16
));
mmio_write_32
(
PMU_BASE
+
PMU_WAKEUP_RST_CLR_LO
,
WITH_16BITS_WMSK
(
clk_freq_khz
*
2
&
0xffff
));
mmio_write_32
(
PMU_BASE
+
PMU_WAKEUP_RST_CLR_HI
,
WITH_16BITS_WMSK
(
clk_freq_khz
*
2
>>
16
));
/* Pmu's clk has switched to 24M back When pmu FSM counts
* the follow counters, so we should use 24M to calculate
* these counters.
*/
mmio_write_32
(
PMU_BASE
+
PMU_SCU_PWRDN_CNT_LO
,
WITH_16BITS_WMSK
(
24000
*
2
&
0xffff
));
mmio_write_32
(
PMU_BASE
+
PMU_SCU_PWRDN_CNT_HI
,
WITH_16BITS_WMSK
(
24000
*
2
>>
16
));
mmio_write_32
(
PMU_BASE
+
PMU_SCU_PWRUP_CNT_LO
,
WITH_16BITS_WMSK
(
24000
*
2
&
0xffff
));
mmio_write_32
(
PMU_BASE
+
PMU_SCU_PWRUP_CNT_HI
,
WITH_16BITS_WMSK
(
24000
*
2
>>
16
));
mmio_write_32
(
PMU_BASE
+
PMU_PLLLOCK_CNT_LO
,
WITH_16BITS_WMSK
(
24000
*
5
&
0xffff
));
mmio_write_32
(
PMU_BASE
+
PMU_PLLLOCK_CNT_HI
,
WITH_16BITS_WMSK
(
24000
*
5
>>
16
));
mmio_write_32
(
PMU_BASE
+
PMU_PLLRST_CNT_LO
,
WITH_16BITS_WMSK
(
24000
*
2
&
0xffff
));
mmio_write_32
(
PMU_BASE
+
PMU_PLLRST_CNT_HI
,
WITH_16BITS_WMSK
(
24000
*
2
>>
16
));
/* Config pmu power mode and pmu wakeup source */
mmio_write_32
(
PMU_BASE
+
PMU_PWRMODE_CORE_LO
,
WITH_16BITS_WMSK
(
pwrmd_core_lo
));
mmio_write_32
(
PMU_BASE
+
PMU_PWRMODE_CORE_HI
,
WITH_16BITS_WMSK
(
pwrmd_core_hi
));
mmio_write_32
(
PMU_BASE
+
PMU_PWRMODE_COMMON_CON_LO
,
WITH_16BITS_WMSK
(
pwrmd_com_lo
));
mmio_write_32
(
PMU_BASE
+
PMU_PWRMODE_COMMON_CON_HI
,
WITH_16BITS_WMSK
(
pwrmd_com_hi
));
mmio_write_32
(
PMU_BASE
+
PMU_WKUP_CFG2_LO
,
WITH_16BITS_WMSK
(
pmu_wkup_cfg2_lo
));
}
static
void
pmu_sleep_restore
(
void
)
{
mmio_write_32
(
PMU_BASE
+
PMU_PWRMODE_CORE_LO
,
WITH_16BITS_WMSK
(
ddr_data
.
pmu_pwrmd_core_l
));
mmio_write_32
(
PMU_BASE
+
PMU_PWRMODE_CORE_HI
,
WITH_16BITS_WMSK
(
ddr_data
.
pmu_pwrmd_core_h
));
mmio_write_32
(
PMU_BASE
+
PMU_PWRMODE_COMMON_CON_LO
,
WITH_16BITS_WMSK
(
ddr_data
.
pmu_pwrmd_cmm_l
));
mmio_write_32
(
PMU_BASE
+
PMU_PWRMODE_COMMON_CON_HI
,
WITH_16BITS_WMSK
(
ddr_data
.
pmu_pwrmd_cmm_h
));
mmio_write_32
(
PMU_BASE
+
PMU_WKUP_CFG2_LO
,
WITH_16BITS_WMSK
(
ddr_data
.
pmu_wkup_cfg2_l
));
/* restore pmic_sleep iomux */
mmio_write_32
(
PMUGRF_BASE
+
GPIO0A_IOMUX
,
WITH_16BITS_WMSK
(
ddr_data
.
pmic_slp_iomux
));
}
static
void
soc_sleep_config
(
void
)
{
ddr_data
.
gpio0c_iomux
=
mmio_read_32
(
PMUGRF_BASE
+
GPIO0C_IOMUX
);
pmu_sleep_config
();
ddr_sleep_config
();
pvtm_32k_config
();
}
static
void
soc_sleep_restore
(
void
)
{
secure_timer_init
();
pvtm_32k_config_restore
();
ddr_sleep_config_restore
();
pmu_sleep_restore
();
mmio_write_32
(
PMUGRF_BASE
+
GPIO0C_IOMUX
,
WITH_16BITS_WMSK
(
ddr_data
.
gpio0c_iomux
));
}
static
inline
void
pm_pll_wait_lock
(
uint32_t
pll_base
,
uint32_t
pll_id
)
{
uint32_t
delay
=
PLL_LOCKED_TIMEOUT
;
while
(
delay
>
0
)
{
if
(
mmio_read_32
(
pll_base
+
PLL_CON
(
1
))
&
PLL_LOCK_MSK
)
break
;
delay
--
;
}
if
(
delay
==
0
)
ERROR
(
"Can't wait pll:%d lock
\n
"
,
pll_id
);
}
static
inline
void
pll_pwr_ctr
(
uint32_t
pll_base
,
uint32_t
pll_id
,
uint32_t
pd
)
{
mmio_write_32
(
pll_base
+
PLL_CON
(
1
),
BITS_WITH_WMASK
(
1
,
1
,
15
));
if
(
pd
)
mmio_write_32
(
pll_base
+
PLL_CON
(
1
),
BITS_WITH_WMASK
(
1
,
1
,
14
));
else
mmio_write_32
(
pll_base
+
PLL_CON
(
1
),
BITS_WITH_WMASK
(
0
,
1
,
14
));
}
static
inline
void
pll_set_mode
(
uint32_t
pll_id
,
uint32_t
mode
)
{
uint32_t
val
=
BITS_WITH_WMASK
(
mode
,
0x3
,
PLL_MODE_SHIFT
(
pll_id
));
if
(
pll_id
!=
GPLL_ID
)
mmio_write_32
(
CRU_BASE
+
CRU_MODE
,
val
);
else
mmio_write_32
(
PMUCRU_BASE
+
CRU_PMU_MODE
,
BITS_WITH_WMASK
(
mode
,
0x3
,
0
));
}
static
inline
void
pll_suspend
(
uint32_t
pll_id
)
{
int
i
;
uint32_t
pll_base
;
if
(
pll_id
!=
GPLL_ID
)
pll_base
=
CRU_BASE
+
CRU_PLL_CONS
(
pll_id
,
0
);
else
pll_base
=
PMUCRU_BASE
+
CRU_PLL_CONS
(
0
,
0
);
/* save pll con */
for
(
i
=
0
;
i
<
PLL_CON_CNT
;
i
++
)
ddr_data
.
cru_plls_con_save
[
pll_id
][
i
]
=
mmio_read_32
(
pll_base
+
PLL_CON
(
i
));
/* slow mode */
pll_set_mode
(
pll_id
,
SLOW_MODE
);
}
static
inline
void
pll_resume
(
uint32_t
pll_id
)
{
uint32_t
mode
,
pll_base
;
if
(
pll_id
!=
GPLL_ID
)
{
pll_base
=
CRU_BASE
+
CRU_PLL_CONS
(
pll_id
,
0
);
mode
=
(
ddr_data
.
cru_mode_save
>>
PLL_MODE_SHIFT
(
pll_id
))
&
0x3
;
}
else
{
pll_base
=
PMUCRU_BASE
+
CRU_PLL_CONS
(
0
,
0
);
mode
=
ddr_data
.
cru_pmu_mode_save
&
0x3
;
}
/* if pll locked before suspend, we should wait atfer resume */
if
(
ddr_data
.
cru_plls_con_save
[
pll_id
][
1
]
&
PLL_LOCK_MSK
)
pm_pll_wait_lock
(
pll_base
,
pll_id
);
pll_set_mode
(
pll_id
,
mode
);
}
static
void
pm_plls_suspend
(
void
)
{
ddr_data
.
cru_mode_save
=
mmio_read_32
(
CRU_BASE
+
CRU_MODE
);
ddr_data
.
cru_pmu_mode_save
=
mmio_read_32
(
PMUCRU_BASE
+
CRU_PMU_MODE
);
ddr_data
.
clk_sel0
=
mmio_read_32
(
CRU_BASE
+
CRU_CLKSELS_CON
(
0
));
pll_suspend
(
GPLL_ID
);
pll_suspend
(
NPLL_ID
);
pll_suspend
(
CPLL_ID
);
pll_suspend
(
APLL_ID
);
/* core */
mmio_write_32
(
CRU_BASE
+
CRU_CLKSELS_CON
(
0
),
BITS_WITH_WMASK
(
0
,
0xf
,
0
));
/* pclk_dbg */
mmio_write_32
(
CRU_BASE
+
CRU_CLKSELS_CON
(
0
),
BITS_WITH_WMASK
(
0
,
0xf
,
8
));
}
static
void
pm_plls_resume
(
void
)
{
/* pclk_dbg */
mmio_write_32
(
CRU_BASE
+
CRU_CLKSELS_CON
(
0
),
ddr_data
.
clk_sel0
|
BITS_WMSK
(
0xf
,
8
));
/* core */
mmio_write_32
(
CRU_BASE
+
CRU_CLKSELS_CON
(
0
),
ddr_data
.
clk_sel0
|
BITS_WMSK
(
0xf
,
0
));
pll_resume
(
APLL_ID
);
pll_resume
(
CPLL_ID
);
pll_resume
(
NPLL_ID
);
pll_resume
(
GPLL_ID
);
}
int
rockchip_soc_sys_pwr_dm_suspend
(
void
)
{
pmu_power_domains_suspend
();
clk_gate_suspend
();
soc_sleep_config
();
pm_plls_suspend
();
psram_boot_cfg
->
pm_flag
&=
~
PM_WARM_BOOT_BIT
;
return
0
;
}
int
rockchip_soc_sys_pwr_dm_resume
(
void
)
{
psram_boot_cfg
->
pm_flag
|=
PM_WARM_BOOT_BIT
;
pm_plls_resume
();
soc_sleep_restore
();
clk_gate_resume
();
pmu_power_domains_resume
();
plat_rockchip_gic_cpuif_enable
();
return
0
;
}
void
__dead2
rockchip_soc_soft_reset
(
void
)
{
pll_set_mode
(
GPLL_ID
,
SLOW_MODE
);
pll_set_mode
(
CPLL_ID
,
SLOW_MODE
);
pll_set_mode
(
NPLL_ID
,
SLOW_MODE
);
pll_set_mode
(
APLL_ID
,
SLOW_MODE
);
dsb
();
mmio_write_32
(
CRU_BASE
+
CRU_GLB_SRST_FST
,
CRU_GLB_SRST_FST_VALUE
);
dsb
();
/*
* Maybe the HW needs some times to reset the system,
* so we do not hope the core to execute valid codes.
*/
psci_power_down_wfi
();
}
void
__dead2
rockchip_soc_system_off
(
void
)
{
uint32_t
val
;
/* set pmic_sleep pin(gpio0_a4) to gpio mode */
mmio_write_32
(
PMUGRF_BASE
+
GPIO0A_IOMUX
,
BITS_WITH_WMASK
(
0
,
0x3
,
8
));
/* config output */
val
=
mmio_read_32
(
GPIO0_BASE
+
SWPORTA_DDR
);
val
|=
BIT
(
4
);
mmio_write_32
(
GPIO0_BASE
+
SWPORTA_DDR
,
val
);
/* config output high level */
val
=
mmio_read_32
(
GPIO0_BASE
);
val
|=
BIT
(
4
);
mmio_write_32
(
GPIO0_BASE
,
val
);
dsb
();
/*
* Maybe the HW needs some times to reset the system,
* so we do not hope the core to execute valid codes.
*/
psci_power_down_wfi
();
}
void
rockchip_plat_mmu_el3
(
void
)
{
/* TODO: support the el3 for px30 SoCs */
}
void
plat_rockchip_pmu_init
(
void
)
{
uint32_t
cpu
;
rockchip_pd_lock_init
();
for
(
cpu
=
0
;
cpu
<
PLATFORM_CORE_COUNT
;
cpu
++
)
cpuson_flags
[
cpu
]
=
0
;
psram_boot_cfg
->
ddr_func
=
(
uint64_t
)
0
;
psram_boot_cfg
->
ddr_data
=
(
uint64_t
)
0
;
psram_boot_cfg
->
sp
=
PSRAM_SP_TOP
;
psram_boot_cfg
->
ddr_flag
=
0x0
;
psram_boot_cfg
->
boot_mpidr
=
read_mpidr_el1
()
&
0xffff
;
psram_boot_cfg
->
pm_flag
=
PM_WARM_BOOT_BIT
;
nonboot_cpus_off
();
/* Remap pmu_sram's base address to boot address */
mmio_write_32
(
PMUSGRF_BASE
+
PMUSGRF_SOC_CON
(
0
),
BITS_WITH_WMASK
(
1
,
0x1
,
13
));
INFO
(
"%s: pd status %x
\n
"
,
__func__
,
mmio_read_32
(
PMU_BASE
+
PMU_PWRDN_ST
));
}
plat/rockchip/px30/drivers/pmu/pmu.h
0 → 100644
View file @
0cc1e68a
/*
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __PMU_H__
#define __PMU_H__
/* Needed aligned 16 bytes for sp stack top */
#define PSRAM_SP_TOP ((PMUSRAM_BASE + PMUSRAM_RSIZE) & ~0xf)
/*****************************************************************************
* pmu con,reg
*****************************************************************************/
#define PMU_WKUP_CFG0_LO 0x00
#define PMU_WKUP_CFG0_HI 0x04
#define PMU_WKUP_CFG1_LO 0x08
#define PMU_WKUP_CFG1_HI 0x0c
#define PMU_WKUP_CFG2_LO 0x10
#define PMU_PWRDN_CON 0x18
#define PMU_PWRDN_ST 0x20
#define PMU_PWRMODE_CORE_LO 0x24
#define PMU_PWRMODE_CORE_HI 0x28
#define PMU_PWRMODE_COMMON_CON_LO 0x2c
#define PMU_PWRMODE_COMMON_CON_HI 0x30
#define PMU_SFT_CON 0x34
#define PMU_INT_ST 0x44
#define PMU_BUS_IDLE_REQ 0x64
#define PMU_BUS_IDLE_ST 0x6c
#define PMU_OSC_CNT_LO 0x74
#define PMU_OSC_CNT_HI 0x78
#define PMU_PLLLOCK_CNT_LO 0x7c
#define PMU_PLLLOCK_CNT_HI 0x80
#define PMU_PLLRST_CNT_LO 0x84
#define PMU_PLLRST_CNT_HI 0x88
#define PMU_STABLE_CNT_LO 0x8c
#define PMU_STABLE_CNT_HI 0x90
#define PMU_WAKEUP_RST_CLR_LO 0x9c
#define PMU_WAKEUP_RST_CLR_HI 0xa0
#define PMU_DDR_SREF_ST 0xa4
#define PMU_SYS_REG0_LO 0xa8
#define PMU_SYS_REG0_HI 0xac
#define PMU_SYS_REG1_LO 0xb0
#define PMU_SYS_REG1_HI 0xb4
#define PMU_SYS_REG2_LO 0xb8
#define PMU_SYS_REG2_HI 0xbc
#define PMU_SYS_REG3_LO 0xc0
#define PMU_SYS_REG3_HI 0xc4
#define PMU_SCU_PWRDN_CNT_LO 0xc8
#define PMU_SCU_PWRDN_CNT_HI 0xcc
#define PMU_SCU_PWRUP_CNT_LO 0xd0
#define PMU_SCU_PWRUP_CNT_HI 0xd4
#define PMU_TIMEOUT_CNT_LO 0xd8
#define PMU_TIMEOUT_CNT_HI 0xdc
#define PMU_CPUAPM_CON(cpu) (0xe0 + (cpu) * 0x4)
#define CORES_PM_DISABLE 0x0
#define CLST_CPUS_MSK 0xf
#define PD_CTR_LOOP 500
#define PD_CHECK_LOOP 500
#define WFEI_CHECK_LOOP 500
#define BUS_IDLE_LOOP 1000
enum
pmu_wkup_cfg2
{
pmu_cluster_wkup_en
=
0
,
pmu_gpio_wkup_en
=
2
,
pmu_sdio_wkup_en
=
3
,
pmu_sdmmc_wkup_en
=
4
,
pmu_uart0_wkup_en
=
5
,
pmu_timer_wkup_en
=
6
,
pmu_usbdev_wkup_en
=
7
,
pmu_sft_wkup_en
=
8
,
pmu_timeout_wkup_en
=
10
,
};
enum
pmu_powermode_core_lo
{
pmu_global_int_dis
=
0
,
pmu_core_src_gt
=
1
,
pmu_cpu0_pd
=
3
,
pmu_clr_core
=
5
,
pmu_scu_pd
=
6
,
pmu_l2_idle
=
8
,
pmu_l2_flush
=
9
,
pmu_clr_bus2main
=
10
,
pmu_clr_peri2msch
=
11
,
};
enum
pmu_powermode_core_hi
{
pmu_apll_pd_en
=
3
,
pmu_dpll_pd_en
=
4
,
pmu_cpll_pd_en
=
5
,
pmu_gpll_pd_en
=
6
,
pmu_npll_pd_en
=
7
,
};
enum
pmu_powermode_common_lo
{
pmu_mode_en
=
0
,
pmu_ddr_pd_en
=
1
,
pmu_wkup_rst
=
3
,
pmu_pll_pd
=
4
,
pmu_pmu_use_if
=
6
,
pmu_alive_use_if
=
7
,
pmu_osc_dis
=
8
,
pmu_input_clamp
=
9
,
pmu_sref_enter
=
10
,
pmu_ddrc_gt
=
11
,
pmu_ddrio_ret
=
12
,
pmu_ddrio_ret_deq
=
13
,
pmu_clr_pmu
=
14
,
pmu_clr_peri_pmu
=
15
,
};
enum
pmu_powermode_common_hi
{
pmu_clr_bus
=
0
,
pmu_clr_mmc
=
1
,
pmu_clr_msch
=
2
,
pmu_clr_nandc
=
3
,
pmu_clr_gmac
=
4
,
pmu_clr_vo
=
5
,
pmu_clr_vi
=
6
,
pmu_clr_gpu
=
7
,
pmu_clr_usb
=
8
,
pmu_clr_vpu
=
9
,
pmu_clr_crypto
=
10
,
pmu_wakeup_begin_cfg
=
11
,
pmu_peri_clk_src_gt
=
12
,
pmu_bus_clk_src_gt
=
13
,
};
enum
pmu_pd_id
{
PD_CPU0
=
0
,
PD_CPU1
=
1
,
PD_CPU2
=
2
,
PD_CPU3
=
3
,
PD_SCU
=
4
,
PD_USB
=
5
,
PD_DDR
=
6
,
PD_SDCARD
=
8
,
PD_CRYPTO
=
9
,
PD_GMAC
=
10
,
PD_MMC_NAND
=
11
,
PD_VPU
=
12
,
PD_VO
=
13
,
PD_VI
=
14
,
PD_GPU
=
15
,
PD_END
=
16
,
};
enum
pmu_bus_id
{
BUS_ID_BUS
=
0
,
BUS_ID_BUS2MAIN
=
1
,
BUS_ID_GPU
=
2
,
BUS_ID_CORE
=
3
,
BUS_ID_CRYPTO
=
4
,
BUS_ID_MMC
=
5
,
BUS_ID_GMAC
=
6
,
BUS_ID_VO
=
7
,
BUS_ID_VI
=
8
,
BUS_ID_SDCARD
=
9
,
BUS_ID_USB
=
10
,
BUS_ID_MSCH
=
11
,
BUS_ID_PERI
=
12
,
BUS_ID_PMU
=
13
,
BUS_ID_VPU
=
14
,
BUS_ID_PERI2MSCH
=
15
,
};
enum
pmu_pd_state
{
pmu_pd_on
=
0
,
pmu_pd_off
=
1
};
enum
pmu_bus_state
{
bus_active
=
0
,
bus_idle
=
1
,
};
enum
cores_pm_ctr_mode
{
core_pwr_pd
=
0
,
core_pwr_wfi
=
1
,
core_pwr_wfi_int
=
2
};
enum
pmu_cores_pm_by_wfi
{
core_pm_en
=
0
,
core_pm_int_wakeup_en
,
core_pm_dis_int
,
core_pm_sft_wakeup_en
};
/*****************************************************************************
* pmu_sgrf
*****************************************************************************/
#define PMUSGRF_SOC_CON(i) ((i) * 0x4)
/*****************************************************************************
* pmu_grf
*****************************************************************************/
#define GPIO0A_IOMUX 0x0
#define GPIO0B_IOMUX 0x4
#define GPIO0C_IOMUX 0x8
#define GPIO0A_PULL 0x10
#define GPIO0L_SMT 0x38
#define GPIO0H_SMT 0x3c
#define PMUGRF_SOC_CON(i) (0x100 + (i) * 4)
#define PMUGRF_PVTM_CON0 0x180
#define PMUGRF_PVTM_CON1 0x184
#define PMUGRF_PVTM_ST0 0x190
#define PMUGRF_PVTM_ST1 0x194
#define PVTM_CALC_CNT 0x200
#define PMUGRF_OS_REG(n) (0x200 + (n) * 4)
#define GPIO0A6_IOMUX_MSK (0x3 << 12)
#define GPIO0A6_IOMUX_GPIO (0x0 << 12)
#define GPIO0A6_IOMUX_RSTOUT (0x1 << 12)
#define GPIO0A6_IOMUX_SHTDN (0x2 << 12)
enum
px30_pmugrf_pvtm_con0
{
pgrf_pvtm_st
=
0
,
pgrf_pvtm_en
=
1
,
pgrf_pvtm_div
=
2
,
};
/*****************************************************************************
* pmu_cru
*****************************************************************************/
#define CRU_PMU_MODE 0x20
#define CRU_PMU_CLKSEL_CON 0x40
#define CRU_PMU_CLKSELS_CON(i) (CRU_PMU_CLKSEL_CON + (i) * 4)
#define CRU_PMU_CLKSEL_CON_CNT 5
#define CRU_PMU_CLKGATE_CON 0x80
#define CRU_PMU_CLKGATES_CON(i) (CRU_PMU_CLKGATE_CON + (i) * 4)
#define CRU_PMU_CLKGATE_CON_CNT 2
#define CRU_PMU_ATCS_CON 0xc0
#define CRU_PMU_ATCSS_CON(i) (CRU_PMU_ATCS_CON + (i) * 4)
#define CRU_PMU_ATCS_CON_CNT 2
/*****************************************************************************
* pmusgrf
*****************************************************************************/
#define PMUSGRF_RSTOUT_EN (0x7 << 10)
#define PMUSGRF_RSTOUT_FST 10
#define PMUSGRF_RSTOUT_TSADC 11
#define PMUSGRF_RSTOUT_WDT 12
#define PMUGRF_SOC_CON2_US_WMSK (0x1fff << 16)
#define PMUGRF_SOC_CON2_MAX_341US 0x1fff
#define PMUGRF_SOC_CON2_200US 0x12c0
#define PMUGRF_FAILSAFE_SHTDN_TSADC BIT(0)
#define PMUGRF_FAILSAFE_SHTDN_WDT BIT(1)
/*****************************************************************************
* QOS
*****************************************************************************/
#define CPU_AXI_QOS_ID_COREID 0x00
#define CPU_AXI_QOS_REVISIONID 0x04
#define CPU_AXI_QOS_PRIORITY 0x08
#define CPU_AXI_QOS_MODE 0x0c
#define CPU_AXI_QOS_BANDWIDTH 0x10
#define CPU_AXI_QOS_SATURATION 0x14
#define CPU_AXI_QOS_EXTCONTROL 0x18
#define CPU_AXI_QOS_NUM_REGS 0x07
#define CPU_AXI_CPU_QOS_BASE 0xff508000
#define CPU_AXI_GPU_QOS_BASE 0xff520000
#define CPU_AXI_ISP_128M_QOS_BASE 0xff548000
#define CPU_AXI_ISP_RD_QOS_BASE 0xff548080
#define CPU_AXI_ISP_WR_QOS_BASE 0xff548100
#define CPU_AXI_ISP_M1_QOS_BASE 0xff548180
#define CPU_AXI_VIP_QOS_BASE 0xff548200
#define CPU_AXI_RGA_RD_QOS_BASE 0xff550000
#define CPU_AXI_RGA_WR_QOS_BASE 0xff550080
#define CPU_AXI_VOP_M0_QOS_BASE 0xff550100
#define CPU_AXI_VOP_M1_QOS_BASE 0xff550180
#define CPU_AXI_VPU_QOS_BASE 0xff558000
#define CPU_AXI_VPU_R128_QOS_BASE 0xff558080
#define CPU_AXI_DCF_QOS_BASE 0xff500000
#define CPU_AXI_DMAC_QOS_BASE 0xff500080
#define CPU_AXI_CRYPTO_QOS_BASE 0xff510000
#define CPU_AXI_GMAC_QOS_BASE 0xff518000
#define CPU_AXI_EMMC_QOS_BASE 0xff538000
#define CPU_AXI_NAND_QOS_BASE 0xff538080
#define CPU_AXI_SDIO_QOS_BASE 0xff538100
#define CPU_AXI_SFC_QOS_BASE 0xff538180
#define CPU_AXI_SDMMC_QOS_BASE 0xff52c000
#define CPU_AXI_USB_HOST_QOS_BASE 0xff540000
#define CPU_AXI_USB_OTG_QOS_BASE 0xff540080
#define PX30_CPU_AXI_SAVE_QOS(array, base) do { \
array[0] = mmio_read_32(base + CPU_AXI_QOS_ID_COREID); \
array[1] = mmio_read_32(base + CPU_AXI_QOS_REVISIONID); \
array[2] = mmio_read_32(base + CPU_AXI_QOS_PRIORITY); \
array[3] = mmio_read_32(base + CPU_AXI_QOS_MODE); \
array[4] = mmio_read_32(base + CPU_AXI_QOS_BANDWIDTH); \
array[5] = mmio_read_32(base + CPU_AXI_QOS_SATURATION); \
array[6] = mmio_read_32(base + CPU_AXI_QOS_EXTCONTROL); \
} while (0)
#define PX30_CPU_AXI_RESTORE_QOS(array, base) do { \
mmio_write_32(base + CPU_AXI_QOS_ID_COREID, array[0]); \
mmio_write_32(base + CPU_AXI_QOS_REVISIONID, array[1]); \
mmio_write_32(base + CPU_AXI_QOS_PRIORITY, array[2]); \
mmio_write_32(base + CPU_AXI_QOS_MODE, array[3]); \
mmio_write_32(base + CPU_AXI_QOS_BANDWIDTH, array[4]); \
mmio_write_32(base + CPU_AXI_QOS_SATURATION, array[5]); \
mmio_write_32(base + CPU_AXI_QOS_EXTCONTROL, array[6]); \
} while (0)
#define SAVE_QOS(array, NAME) \
PX30_CPU_AXI_SAVE_QOS(array, CPU_AXI_##NAME##_QOS_BASE)
#define RESTORE_QOS(array, NAME) \
PX30_CPU_AXI_RESTORE_QOS(array, CPU_AXI_##NAME##_QOS_BASE)
#endif
/* __PMU_H__ */
plat/rockchip/px30/drivers/soc/soc.c
0 → 100644
View file @
0cc1e68a
/*
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <platform_def.h>
#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/console.h>
#include <drivers/delay_timer.h>
#include <lib/mmio.h>
#include <ddr_parameter.h>
#include <platform_def.h>
#include <pmu.h>
#include <px30_def.h>
#include <soc.h>
#include <rockchip_sip_svc.h>
/* Aggregate of all devices in the first GB */
#define PX30_DEV_RNG0_BASE 0xff000000
#define PX30_DEV_RNG0_SIZE 0x00ff0000
const
mmap_region_t
plat_rk_mmap
[]
=
{
MAP_REGION_FLAT
(
PX30_DEV_RNG0_BASE
,
PX30_DEV_RNG0_SIZE
,
MT_DEVICE
|
MT_RW
|
MT_SECURE
),
MAP_REGION_FLAT
(
SHARE_MEM_BASE
,
SHARE_MEM_SIZE
,
MT_DEVICE
|
MT_RW
|
MT_SECURE
),
MAP_REGION_FLAT
(
DDR_PARAM_BASE
,
DDR_PARAM_SIZE
,
MT_DEVICE
|
MT_RW
|
MT_SECURE
),
{
0
}
};
/* The RockChip power domain tree descriptor */
const
unsigned
char
rockchip_power_domain_tree_desc
[]
=
{
/* No of root nodes */
PLATFORM_SYSTEM_COUNT
,
/* No of children for the root node */
PLATFORM_CLUSTER_COUNT
,
/* No of children for the first cluster node */
PLATFORM_CLUSTER0_CORE_COUNT
,
};
void
clk_gate_con_save
(
uint32_t
*
clkgt_save
)
{
uint32_t
i
,
j
;
for
(
i
=
0
;
i
<
CRU_CLKGATES_CON_CNT
;
i
++
)
clkgt_save
[
i
]
=
mmio_read_32
(
CRU_BASE
+
CRU_CLKGATES_CON
(
i
));
j
=
i
;
for
(
i
=
0
;
i
<
CRU_PMU_CLKGATE_CON_CNT
;
i
++
,
j
++
)
clkgt_save
[
j
]
=
mmio_read_32
(
PMUCRU_BASE
+
CRU_PMU_CLKGATES_CON
(
i
));
}
void
clk_gate_con_restore
(
uint32_t
*
clkgt_save
)
{
uint32_t
i
,
j
;
for
(
i
=
0
;
i
<
CRU_CLKGATES_CON_CNT
;
i
++
)
mmio_write_32
(
CRU_BASE
+
CRU_CLKGATES_CON
(
i
),
WITH_16BITS_WMSK
(
clkgt_save
[
i
]));
j
=
i
;
for
(
i
=
0
;
i
<
CRU_PMU_CLKGATE_CON_CNT
;
i
++
,
j
++
)
mmio_write_32
(
PMUCRU_BASE
+
CRU_PMU_CLKGATES_CON
(
i
),
WITH_16BITS_WMSK
(
clkgt_save
[
j
]));
}
void
clk_gate_con_disable
(
void
)
{
uint32_t
i
;
for
(
i
=
0
;
i
<
CRU_CLKGATES_CON_CNT
;
i
++
)
mmio_write_32
(
CRU_BASE
+
CRU_CLKGATES_CON
(
i
),
0xffff0000
);
for
(
i
=
0
;
i
<
CRU_PMU_CLKGATE_CON_CNT
;
i
++
)
mmio_write_32
(
PMUCRU_BASE
+
CRU_PMU_CLKGATES_CON
(
i
),
0xffff0000
);
}
void
secure_timer_init
(
void
)
{
mmio_write_32
(
STIMER_CHN_BASE
(
1
)
+
TIMER_CONTROL_REG
,
TIMER_DIS
);
mmio_write_32
(
STIMER_CHN_BASE
(
1
)
+
TIMER_LOAD_COUNT0
,
0xffffffff
);
mmio_write_32
(
STIMER_CHN_BASE
(
1
)
+
TIMER_LOAD_COUNT1
,
0xffffffff
);
/* auto reload & enable the timer */
mmio_write_32
(
STIMER_CHN_BASE
(
1
)
+
TIMER_CONTROL_REG
,
TIMER_EN
|
TIMER_FMODE
);
}
static
void
sgrf_init
(
void
)
{
uint32_t
i
,
val
;
struct
param_ddr_usage
usg
;
/* general secure regions */
usg
=
ddr_region_usage_parse
(
DDR_PARAM_BASE
,
PLAT_MAX_DDR_CAPACITY_MB
);
for
(
i
=
0
;
i
<
usg
.
s_nr
;
i
++
)
{
/* enable secure */
val
=
mmio_read_32
(
FIREWALL_DDR_BASE
+
FIREWALL_DDR_FW_DDR_CON_REG
);
val
|=
BIT
(
7
-
i
);
mmio_write_32
(
FIREWALL_DDR_BASE
+
FIREWALL_DDR_FW_DDR_CON_REG
,
val
);
/* map top and base */
mmio_write_32
(
FIREWALL_DDR_BASE
+
FIREWALL_DDR_FW_DDR_RGN
(
7
-
i
),
RG_MAP_SECURE
(
usg
.
s_top
[
i
],
usg
.
s_base
[
i
]));
}
/* set ddr rgn0_top and rga0_top as 0 */
mmio_write_32
(
FIREWALL_DDR_BASE
+
FIREWALL_DDR_FW_DDR_RGN
(
0
),
0x0
);
/* set all slave ip into no-secure, except stimer */
mmio_write_32
(
SGRF_BASE
+
SGRF_SOC_CON
(
4
),
SGRF_SLV_S_ALL_NS
);
mmio_write_32
(
SGRF_BASE
+
SGRF_SOC_CON
(
5
),
SGRF_SLV_S_ALL_NS
);
mmio_write_32
(
SGRF_BASE
+
SGRF_SOC_CON
(
6
),
SGRF_SLV_S_ALL_NS
);
mmio_write_32
(
SGRF_BASE
+
SGRF_SOC_CON
(
7
),
SGRF_SLV_S_ALL_NS
);
mmio_write_32
(
SGRF_BASE
+
SGRF_SOC_CON
(
8
),
0x00030000
);
/* set master crypto to no-secure, dcf to secure */
mmio_write_32
(
SGRF_BASE
+
SGRF_SOC_CON
(
3
),
0x000f0003
);
/* set DMAC into no-secure */
mmio_write_32
(
SGRF_BASE
+
SGRF_DMAC_CON
(
0
),
DMA_IRQ_BOOT_NS
);
mmio_write_32
(
SGRF_BASE
+
SGRF_DMAC_CON
(
1
),
DMA_PERI_CH_NS_15_0
);
mmio_write_32
(
SGRF_BASE
+
SGRF_DMAC_CON
(
2
),
DMA_PERI_CH_NS_19_16
);
mmio_write_32
(
SGRF_BASE
+
SGRF_DMAC_CON
(
3
),
DMA_MANAGER_BOOT_NS
);
/* soft reset dma before use */
mmio_write_32
(
SGRF_BASE
+
SGRF_SOC_CON
(
1
),
DMA_SOFTRST_REQ
);
udelay
(
5
);
mmio_write_32
(
SGRF_BASE
+
SGRF_SOC_CON
(
1
),
DMA_SOFTRST_RLS
);
}
static
void
soc_reset_config_all
(
void
)
{
uint32_t
tmp
;
/* tsadc and wdt can trigger a first rst */
tmp
=
mmio_read_32
(
CRU_BASE
+
CRU_GLB_RST_CON
);
tmp
|=
CRU_GLB_RST_TSADC_FST
|
CRU_GLB_RST_WDT_FST
;
mmio_write_32
(
CRU_BASE
+
CRU_GLB_RST_CON
,
tmp
);
return
;
tmp
=
mmio_read_32
(
PMUGRF_BASE
+
PMUGRF_SOC_CON
(
3
));
tmp
&=
~
(
PMUGRF_FAILSAFE_SHTDN_TSADC
|
PMUGRF_FAILSAFE_SHTDN_WDT
);
mmio_write_32
(
PMUGRF_BASE
+
PMUGRF_SOC_CON
(
3
),
tmp
);
/* wdt pin rst eable */
mmio_write_32
(
GRF_BASE
+
GRF_SOC_CON
(
2
),
BIT_WITH_WMSK
(
GRF_SOC_CON2_NSWDT_RST_EN
));
}
void
px30_soc_reset_config
(
void
)
{
uint32_t
tmp
;
/* enable soc ip rst hold time cfg */
tmp
=
mmio_read_32
(
CRU_BASE
+
CRU_GLB_RST_CON
);
tmp
|=
BIT
(
CRU_GLB_RST_TSADC_EXT
)
|
BIT
(
CRU_GLB_RST_WDT_EXT
);
mmio_write_32
(
CRU_BASE
+
CRU_GLB_RST_CON
,
tmp
);
/* soc ip rst hold time, 24m */
tmp
=
mmio_read_32
(
CRU_BASE
+
CRU_GLB_CNT_TH
);
tmp
&=
~
CRU_GLB_CNT_RST_MSK
;
tmp
|=
(
CRU_GLB_CNT_RST_1MS
/
2
);
mmio_write_32
(
CRU_BASE
+
CRU_GLB_CNT_TH
,
tmp
);
mmio_write_32
(
PMUSGRF_BASE
+
PMUSGRF_SOC_CON
(
0
),
BIT_WITH_WMSK
(
PMUSGRF_RSTOUT_FST
)
|
BIT_WITH_WMSK
(
PMUSGRF_RSTOUT_TSADC
)
|
BIT_WITH_WMSK
(
PMUSGRF_RSTOUT_WDT
));
/* rst_out pulse time */
mmio_write_32
(
PMUGRF_BASE
+
PMUGRF_SOC_CON
(
2
),
PMUGRF_SOC_CON2_MAX_341US
|
PMUGRF_SOC_CON2_US_WMSK
);
soc_reset_config_all
();
}
void
plat_rockchip_soc_init
(
void
)
{
secure_timer_init
();
sgrf_init
();
}
plat/rockchip/px30/drivers/soc/soc.h
0 → 100644
View file @
0cc1e68a
/*
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __SOC_H__
#define __SOC_H__
#include <plat_private.h>
#ifndef BITS_WMSK
#define BITS_WMSK(msk, shift) ((msk) << (shift + REG_MSK_SHIFT))
#endif
enum
plls_id
{
APLL_ID
=
0
,
DPLL_ID
,
CPLL_ID
,
NPLL_ID
,
GPLL_ID
,
END_PLL_ID
,
};
enum
pll_mode
{
SLOW_MODE
,
NORM_MODE
,
DEEP_SLOW_MODE
,
};
/***************************************************************************
* SGRF
***************************************************************************/
#define SGRF_SOC_CON(i) ((i) * 0x4)
#define SGRF_DMAC_CON(i) (0x30 + (i) * 0x4)
#define SGRF_MST_S_ALL_NS 0xffffffff
#define SGRF_SLV_S_ALL_NS 0xffff0000
#define DMA_IRQ_BOOT_NS 0xffffffff
#define DMA_PERI_CH_NS_15_0 0xffffffff
#define DMA_PERI_CH_NS_19_16 0x000f000f
#define DMA_MANAGER_BOOT_NS 0x00010001
#define DMA_SOFTRST_REQ BITS_WITH_WMASK(1, 0x1, 12)
#define DMA_SOFTRST_RLS BITS_WITH_WMASK(0, 0x1, 12)
/***************************************************************************
* GRF
***************************************************************************/
#define GRF_SOC_CON(i) (0x0400 + (i) * 4)
#define GRF_PD_VO_CON0 0x0434
#define GRF_SOC_STATUS0 0x0480
#define GRF_CPU_STATUS0 0x0520
#define GRF_CPU_STATUS1 0x0524
#define GRF_SOC_NOC_CON0 0x0530
#define GRF_SOC_NOC_CON1 0x0534
#define CKECK_WFE_MSK 0x1
#define CKECK_WFI_MSK 0x10
#define CKECK_WFEI_MSK 0x11
#define GRF_SOC_CON2_NSWDT_RST_EN 12
/***************************************************************************
* DDR FIREWALL
***************************************************************************/
#define FIREWALL_DDR_FW_DDR_RGN(i) ((i) * 0x4)
#define FIREWALL_DDR_FW_DDR_MST(i) (0x20 + (i) * 0x4)
#define FIREWALL_DDR_FW_DDR_CON_REG 0x40
#define FIREWALL_DDR_FW_DDR_RGN_NUM 8
#define FIREWALL_DDR_FW_DDR_MST_NUM 6
#define PLAT_MAX_DDR_CAPACITY_MB 4096
#define RG_MAP_SECURE(top, base) ((((top) - 1) << 16) | (base))
/***************************************************************************
* cru
***************************************************************************/
#define CRU_MODE 0xa0
#define CRU_MISC 0xa4
#define CRU_GLB_CNT_TH 0xb0
#define CRU_GLB_RST_ST 0xb4
#define CRU_GLB_SRST_FST 0xb8
#define CRU_GLB_SRST_SND 0xbc
#define CRU_GLB_RST_CON 0xc0
#define CRU_CLKSEL_CON 0x100
#define CRU_CLKSELS_CON(i) (CRU_CLKSEL_CON + (i) * 4)
#define CRU_CLKSEL_CON_CNT 60
#define CRU_CLKGATE_CON 0x200
#define CRU_CLKGATES_CON(i) (CRU_CLKGATE_CON + (i) * 4)
#define CRU_CLKGATES_CON_CNT 18
#define CRU_SOFTRST_CON 0x300
#define CRU_SOFTRSTS_CON(n) (CRU_SOFTRST_CON + ((n) * 4))
#define CRU_SOFTRSTS_CON_CNT 12
#define CRU_AUTOCS_CON0(id) (0x400 + (id) * 8)
#define CRU_AUTOCS_CON1(id) (0x404 + (id) * 8)
#define CRU_CONS_GATEID(i) (16 * (i))
#define GATE_ID(reg, bit) ((reg) * 16 + (bit))
#define CRU_GLB_SRST_FST_VALUE 0xfdb9
#define CRU_GLB_SRST_SND_VALUE 0xeca8
#define CRU_GLB_RST_TSADC_EXT 6
#define CRU_GLB_RST_WDT_EXT 7
#define CRU_GLB_CNT_RST_MSK 0xffff
#define CRU_GLB_CNT_RST_1MS 0x5DC0
#define CRU_GLB_RST_TSADC_FST BIT(0)
#define CRU_GLB_RST_WDT_FST BIT(1)
/***************************************************************************
* pll
***************************************************************************/
#define CRU_PLL_CONS(id, i) ((id) * 0x20 + (i) * 4)
#define PLL_CON(i) ((i) * 4)
#define PLL_CON_CNT 5
#define PLL_LOCK_MSK BIT(10)
#define PLL_MODE_SHIFT(id) ((id) == CPLL_ID ? \
2 : \
((id) == DPLL_ID ? 4 : 2 * (id)))
#define PLL_MODE_MSK(id) (0x3 << PLL_MODE_SHIFT(id))
#define PLL_LOCKED_TIMEOUT 600000U
/***************************************************************************
* GPIO
***************************************************************************/
#define SWPORTA_DR 0x00
#define SWPORTA_DDR 0x04
#define GPIO_INTEN 0x30
#define GPIO_INT_STATUS 0x40
#define GPIO_NUMS 4
/**************************************************
* secure timer
**************************************************/
/* chanal0~5 */
#define STIMER_CHN_BASE(n) (STIME_BASE + 0x20 * (n))
#define TIMER_LOAD_COUNT0 0x0
#define TIMER_LOAD_COUNT1 0x4
#define TIMER_CUR_VALUE0 0x8
#define TIMER_CUR_VALUE1 0xc
#define TIMER_CONTROL_REG 0x10
#define TIMER_INTSTATUS 0x18
#define TIMER_DIS 0x0
#define TIMER_EN 0x1
#define TIMER_FMODE (0x0 << 1)
#define TIMER_RMODE (0x1 << 1)
#define TIMER_LOAD_COUNT0_MSK (0xffffffff)
#define TIMER_LOAD_COUNT1_MSK (0xffffffff00000000)
void
clk_gate_con_save
(
uint32_t
*
clkgt_save
);
void
clk_gate_con_restore
(
uint32_t
*
clkgt_save
);
void
clk_gate_con_disable
(
void
);
void
secure_timer_init
(
void
);
void
secure_timer_disable
(
void
);
void
px30_soc_reset_config
(
void
);
#endif
/* __SOC_H__ */
plat/rockchip/px30/include/plat.ld.S
0 → 100644
View file @
0cc1e68a
/*
*
Copyright
(
c
)
2019
,
ARM
Limited
and
Contributors
.
All
rights
reserved
.
*
*
SPDX
-
License
-
Identifier
:
BSD
-
3
-
Clause
*/
#ifndef __ROCKCHIP_PLAT_LD_S__
#define __ROCKCHIP_PLAT_LD_S__
MEMORY
{
PMUSRAM
(
rwx
)
:
ORIGIN
=
PMUSRAM_BASE
,
LENGTH
=
PMUSRAM_RSIZE
}
SECTIONS
{
.
=
PMUSRAM_BASE
;
/
*
*
pmu_cpuson_entrypoint
request
address
*
align
64
K
when
resume
,
so
put
it
in
the
*
start
of
pmusram
*/
.
pmusram
:
{
ASSERT
(.
==
ALIGN
(
64
*
1024
),
".
pmusram.entry
request
64
K
aligned
.
");
KEEP
(*(.
pmusram.entry
))
__bl31_pmusram_text_start
=
.
;
*(.
pmusram.text
)
*(.
pmusram.rodata
)
__bl31_pmusram_text_end
=
.
;
__bl31_pmusram_data_start
=
.
;
*(.
pmusram.data
)
__bl31_pmusram_data_end
=
.
;
}
>
PMUSRAM
}
#endif /* __ROCKCHIP_PLAT_LD_S__ */
plat/rockchip/px30/include/plat_sip_calls.h
0 → 100644
View file @
0cc1e68a
/*
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __PLAT_SIP_CALLS_H__
#define __PLAT_SIP_CALLS_H__
#define RK_PLAT_SIP_NUM_CALLS 0
#endif
/* __PLAT_SIP_CALLS_H__ */
plat/rockchip/px30/include/platform_def.h
0 → 100644
View file @
0cc1e68a
/*
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __PLATFORM_DEF_H__
#define __PLATFORM_DEF_H__
#include <arch.h>
#include <common_def.h>
#include <px30_def.h>
#define DEBUG_XLAT_TABLE 0
/*******************************************************************************
* Platform binary types for linking
******************************************************************************/
#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
#define PLATFORM_LINKER_ARCH aarch64
/*******************************************************************************
* Generic platform constants
******************************************************************************/
/* Size of cacheable stacks */
#if DEBUG_XLAT_TABLE
#define PLATFORM_STACK_SIZE 0x800
#elif IMAGE_BL1
#define PLATFORM_STACK_SIZE 0x440
#elif IMAGE_BL2
#define PLATFORM_STACK_SIZE 0x400
#elif IMAGE_BL31
#define PLATFORM_STACK_SIZE 0x800
#elif IMAGE_BL32
#define PLATFORM_STACK_SIZE 0x440
#endif
#define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n"
#define PLATFORM_MAX_AFFLVL MPIDR_AFFLVL2
#define PLATFORM_SYSTEM_COUNT 1
#define PLATFORM_CLUSTER_COUNT 1
#define PLATFORM_CLUSTER0_CORE_COUNT 4
#define PLATFORM_CLUSTER1_CORE_COUNT 0
#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER1_CORE_COUNT + \
PLATFORM_CLUSTER0_CORE_COUNT)
#define PLATFORM_NUM_AFFS (PLATFORM_SYSTEM_COUNT + \
PLATFORM_CLUSTER_COUNT + \
PLATFORM_CORE_COUNT)
#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2
#define PLAT_RK_CLST_TO_CPUID_SHIFT 8
/*
* This macro defines the deepest retention state possible. A higher state
* id will represent an invalid or a power down state.
*/
#define PLAT_MAX_RET_STATE 1
/*
* This macro defines the deepest power down states possible. Any state ID
* higher than this is invalid.
*/
#define PLAT_MAX_OFF_STATE 2
/*******************************************************************************
* Platform memory map related constants
******************************************************************************/
/* TF txet, ro, rw, Size: 512KB */
#define TZRAM_BASE (0x0)
#define TZRAM_SIZE (0x80000)
/*******************************************************************************
* BL31 specific defines.
******************************************************************************/
/*
* Put BL3-1 at the top of the Trusted RAM
*/
#define BL31_BASE (TZRAM_BASE + 0x10000)
#define BL31_LIMIT (TZRAM_BASE + TZRAM_SIZE)
/*******************************************************************************
* Platform specific page table and MMU setup constants
******************************************************************************/
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 32)
#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 32)
#define ADDR_SPACE_SIZE (1ull << 32)
#define MAX_XLAT_TABLES 8
#define MAX_MMAP_REGIONS 27
/*******************************************************************************
* Declarations and constants to access the mailboxes safely. Each mailbox is
* aligned on the biggest cache line size in the platform. This is known only
* to the platform as it might have a combination of integrated and external
* caches. Such alignment ensures that two maiboxes do not sit on the same cache
* line at any cache level. They could belong to different cpus/clusters &
* get written while being protected by different locks causing corruption of
* a valid mailbox address.
******************************************************************************/
#define CACHE_WRITEBACK_SHIFT 6
#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
/*
* Define GICD and GICC and GICR base
*/
#define PLAT_RK_GICD_BASE PX30_GICD_BASE
#define PLAT_RK_GICC_BASE PX30_GICC_BASE
#define PLAT_RK_UART_BASE PX30_UART_BASE
#define PLAT_RK_UART_CLOCK PX30_UART_CLOCK
#define PLAT_RK_UART_BAUDRATE PX30_BAUDRATE
#define PLAT_RK_PRIMARY_CPU 0x0
#endif
/* __PLATFORM_DEF_H__ */
plat/rockchip/px30/plat_sip_calls.c
0 → 100644
View file @
0cc1e68a
/*
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/debug.h>
#include <common/runtime_svc.h>
#include <lib/mmio.h>
#include <plat_sip_calls.h>
#include <rockchip_sip_svc.h>
uintptr_t
rockchip_plat_sip_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
)
{
ERROR
(
"%s: unhandled SMC (0x%x)
\n
"
,
__func__
,
smc_fid
);
SMC_RET1
(
handle
,
SMC_UNK
);
}
plat/rockchip/px30/platform.mk
0 → 100644
View file @
0cc1e68a
#
#Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
#
#SPDX-License-Identifier: BSD-3-Clause
#
RK_PLAT
:=
plat/rockchip
RK_PLAT_SOC
:=
${RK_PLAT}
/
${PLAT}
RK_PLAT_COMMON
:=
${RK_PLAT}
/common
DISABLE_BIN_GENERATION
:=
1
PLAT_INCLUDES
:=
-Idrivers
/arm/gic/common/
\
-Idrivers
/arm/gic/v2/
\
-Iinclude
/plat/common/
\
-I
${RK_PLAT_COMMON}
/
\
-I
${RK_PLAT_COMMON}
/include/
\
-I
${RK_PLAT_COMMON}
/drivers/parameter/
\
-I
${RK_PLAT_COMMON}
/pmusram
\
-I
${RK_PLAT_SOC}
/
\
-I
${RK_PLAT_SOC}
/drivers/pmu/
\
-I
${RK_PLAT_SOC}
/drivers/soc/
\
-I
${RK_PLAT_SOC}
/include/
RK_GIC_SOURCES
:=
drivers/arm/gic/common/gic_common.c
\
drivers/arm/gic/v2/gicv2_main.c
\
drivers/arm/gic/v2/gicv2_helpers.c
\
plat/common/plat_gicv2.c
\
plat/common/aarch64/crash_console_helpers.S
\
${RK_PLAT}
/common/rockchip_gicv2.c
PLAT_BL_COMMON_SOURCES
:=
lib/xlat_tables/xlat_tables_common.c
\
lib/xlat_tables/aarch64/xlat_tables.c
\
plat/common/plat_psci_common.c
BL31_SOURCES
+=
${RK_GIC_SOURCES}
\
drivers/arm/cci/cci.c
\
drivers/delay_timer/delay_timer.c
\
drivers/delay_timer/generic_delay_timer.c
\
drivers/ti/uart/aarch64/16550_console.S
\
lib/cpus/aarch64/cortex_a35.S
\
${RK_PLAT_COMMON}
/aarch64/plat_helpers.S
\
${RK_PLAT_COMMON}
/aarch64/platform_common.c
\
${RK_PLAT_COMMON}
/bl31_plat_setup.c
\
${RK_PLAT_COMMON}
/drivers/parameter/ddr_parameter.c
\
${RK_PLAT_COMMON}
/params_setup.c
\
${RK_PLAT_COMMON}
/pmusram/cpus_on_fixed_addr.S
\
${RK_PLAT_COMMON}
/plat_pm.c
\
${RK_PLAT_COMMON}
/plat_topology.c
\
${RK_PLAT_COMMON}
/rockchip_sip_svc.c
\
${RK_PLAT_SOC}
/drivers/pmu/pmu.c
\
${RK_PLAT_SOC}
/drivers/soc/soc.c
\
${RK_PLAT_SOC}
/plat_sip_calls.c
ENABLE_PLAT_COMPAT
:=
0
MULTI_CONSOLE_API
:=
1
include
lib/libfdt/libfdt.mk
$(eval
$(call
add_define,PLAT_EXTRA_LD_SCRIPT))
$(eval
$(call
add_define,PLAT_SKIP_OPTEE_S_EL1_INT_REGISTER))
$(eval
$(call
add_define,PLAT_WARMBOOT_ADDR_NOT_ALIGN))
plat/rockchip/px30/px30_def.h
0 → 100644
View file @
0cc1e68a
/*
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __PX30_DEF_H__
#define __PX30_DEF_H__
#define MAJOR_VERSION (1)
#define MINOR_VERSION (0)
#define SIZE_K(n) ((n) * 1024)
#define WITH_16BITS_WMSK(bits) (0xffff0000 | (bits))
/* Special value used to verify platform parameters from BL2 to BL3-1 */
#define RK_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL
#define PMU_BASE 0xff000000
#define PMU_SIZE SIZE_K(64)
#define PMUGRF_BASE 0xff010000
#define PMUGRF_SIZE SIZE_K(64)
#define PMUSRAM_BASE 0xff020000
#define PMUSRAM_SIZE SIZE_K(64)
#define PMUSRAM_RSIZE SIZE_K(8)
#define UART0_BASE 0xff030000
#define UART0_SIZE SIZE_K(64)
#define GPIO0_BASE 0xff040000
#define GPIO0_SIZE SIZE_K(64)
#define PMUSGRF_BASE 0xff050000
#define PMUSGRF_SIZE SIZE_K(64)
#define INTSRAM_BASE 0xff0e0000
#define INTSRAM_SIZE SIZE_K(64)
#define SGRF_BASE 0xff11c000
#define SGRF_SIZE SIZE_K(16)
#define GIC400_BASE 0xff130000
#define GIC400_SIZE SIZE_K(64)
#define GRF_BASE 0xff140000
#define GRF_SIZE SIZE_K(64)
#define UART1_BASE 0xff158000
#define UART1_SIZE SIZE_K(64)
#define UART2_BASE 0xff160000
#define UART2_SIZE SIZE_K(64)
#define I2C0_BASE 0xff180000
#define I2C0_SIZE SIZE_K(64)
#define PWM0_BASE 0xff200000
#define PWM0_SIZE SIZE_K(32)
#define PWM1_BASE 0xff208000
#define PWM1_SIZE SIZE_K(32)
#define NTIME_BASE 0xff210000
#define NTIME_SIZE SIZE_K(64)
#define STIME_BASE 0xff220000
#define STIME_SIZE SIZE_K(64)
#define DCF_BASE 0xff230000
#define DCF_SIZE SIZE_K(64)
#define GPIO1_BASE 0xff250000
#define GPIO1_SIZE SIZE_K(64)
#define GPIO2_BASE 0xff260000
#define GPIO2_SIZE SIZE_K(64)
#define GPIO3_BASE 0xff270000
#define GPIO3_SIZE SIZE_K(64)
#define DDR_PHY_BASE 0xff2a0000
#define DDR_PHY_SIZE SIZE_K(64)
#define CRU_BASE 0xff2b0000
#define CRU_SIZE SIZE_K(32)
#define CRU_BOOST_BASE 0xff2b8000
#define CRU_BOOST_SIZE SIZE_K(16)
#define PMUCRU_BASE 0xff2bc000
#define PMUCRU_SIZE SIZE_K(16)
#define VOP_BASE 0xff460000
#define VOP_SIZE SIZE_K(16)
#define SERVER_MSCH_BASE 0xff530000
#define SERVER_MSCH_SIZE SIZE_K(64)
#define FIREWALL_DDR_BASE 0xff534000
#define FIREWALL_DDR_SIZE SIZE_K(16)
#define DDR_UPCTL_BASE 0xff600000
#define DDR_UPCTL_SIZE SIZE_K(64)
#define DDR_MNTR_BASE 0xff610000
#define DDR_MNTR_SIZE SIZE_K(64)
#define DDR_STDBY_BASE 0xff620000
#define DDR_STDBY_SIZE SIZE_K(64)
#define DDRGRF_BASE 0xff630000
#define DDRGRF_SIZE SIZE_K(32)
/**************************************************************************
* UART related constants
**************************************************************************/
#define PX30_UART_BASE UART2_BASE
#define PX30_BAUDRATE 1500000
#define PX30_UART_CLOCK 24000000
/******************************************************************************
* System counter frequency related constants
******************************************************************************/
#define SYS_COUNTER_FREQ_IN_TICKS 24000000
#define SYS_COUNTER_FREQ_IN_MHZ 24
/******************************************************************************
* GIC-400 & interrupt handling related constants
******************************************************************************/
/* Base rk_platform compatible GIC memory map */
#define PX30_GICD_BASE (GIC400_BASE + 0x1000)
#define PX30_GICC_BASE (GIC400_BASE + 0x2000)
#define PX30_GICR_BASE 0
/* no GICR in GIC-400 */
/******************************************************************************
* sgi, ppi
******************************************************************************/
#define RK_IRQ_SEC_PHY_TIMER 29
#define RK_IRQ_SEC_SGI_0 8
#define RK_IRQ_SEC_SGI_1 9
#define RK_IRQ_SEC_SGI_2 10
#define RK_IRQ_SEC_SGI_3 11
#define RK_IRQ_SEC_SGI_4 12
#define RK_IRQ_SEC_SGI_5 13
#define RK_IRQ_SEC_SGI_6 14
#define RK_IRQ_SEC_SGI_7 15
/*
* Define a list of Group 0 interrupts.
*/
#define PLAT_RK_GICV2_G0_IRQS \
INTR_PROP_DESC(RK_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \
GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), \
INTR_PROP_DESC(RK_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, \
GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL)
#define SHARE_MEM_BASE 0x100000
/* [1MB, 1MB+60K]*/
#define SHARE_MEM_PAGE_NUM 15
#define SHARE_MEM_SIZE SIZE_K(SHARE_MEM_PAGE_NUM * 4)
#define DDR_PARAM_BASE 0x02000000
#define DDR_PARAM_SIZE SIZE_K(4)
#endif
/* __PLAT_DEF_H__ */
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