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
d6845d3d
Commit
d6845d3d
authored
Feb 27, 2017
by
davidcunado-arm
Committed by
GitHub
Feb 27, 2017
Browse files
Merge pull request #835 from rockchip-linux/rk3399-atf-cleanup-20170210
RK3399 ARM TF clean up 20170210
parents
86a3b266
ccdc044a
Changes
37
Show whitespace changes
Inline
Side-by-side
plat/rockchip/common/include/plat_private.h
View file @
d6845d3d
...
...
@@ -44,6 +44,7 @@
extern
uint32_t
__bl31_sram_text_start
,
__bl31_sram_text_end
;
extern
uint32_t
__bl31_sram_data_start
,
__bl31_sram_data_end
;
extern
uint32_t
__sram_incbin_start
,
__sram_incbin_end
;
/******************************************************************************
* For rockchip socs pm ops
...
...
plat/rockchip/common/pmusram/pmu_sram.c
View file @
d6845d3d
...
...
@@ -62,6 +62,12 @@ void rockchip_plat_sram_mmu_el3(void)
mmap_add_region
((
unsigned
long
)
&
__bl31_sram_data_start
,
(
unsigned
long
)
&
__bl31_sram_data_start
,
sram_size
,
MT_MEMORY
|
MT_RW
|
MT_SECURE
);
/* sram.incbin size */
sram_size
=
(
char
*
)
&
__sram_incbin_end
-
(
char
*
)
&
__sram_incbin_start
;
mmap_add_region
((
unsigned
long
)
&
__sram_incbin_start
,
(
unsigned
long
)
&
__sram_incbin_start
,
sram_size
,
MT_NON_CACHEABLE
|
MT_RW
|
MT_SECURE
);
#else
/* TODO: Support other SoCs, Just support RK3399 now */
return
;
...
...
plat/rockchip/rk3399/drivers/dram/dcf_code.inc
deleted
100644 → 0
View file @
86a3b266
0x0
,
0x4f8c120c
,
0x0
,
0x4f8c1210
,
0x100000
,
0x1f310019
,
0x0
,
0xb0000001
,
0x58
,
0xd0000000
,
0x1300
,
0x1f760329
,
0x0
,
0xb0000001
,
0x40
,
0xd0000000
,
0xc
,
0x1f760371
,
0x0
,
0xb0000001
,
0x28
,
0xd0000000
,
0x400000
,
0x1f900009
,
0x0
,
0xb0000001
,
0x10
,
0xd0000000
,
0x1
,
0x4f8c120c
,
0x100000
,
0x1f310019
,
0x0
,
0xb0000001
,
0x58
,
0xd0000000
,
0x2c00
,
0x1f760329
,
0x0
,
0xb0000001
,
0x40
,
0xd0000000
,
0xc0
,
0x1f760371
,
0x0
,
0xb0000001
,
0x28
,
0xd0000000
,
0x400000
,
0x1f8f0009
,
0x0
,
0xb0000001
,
0x10
,
0xd0000000
,
0x1
,
0x4f8c1210
,
0x0
,
0x4f8c1220
,
0x0
,
0x4f8c121c
,
0x0
,
0xaf8c120d
,
0x108
,
0xd0000000
,
0x2000
,
0x1f900009
,
0x0
,
0xa0000001
,
0x30
,
0xd0000000
,
0x0
,
0x4f8c1220
,
0x0
,
0x4f8c121c
,
0x0
,
0x10000001
,
0x0
,
0xa0000001
,
0xb0
,
0xd0000000
,
0x8000
,
0x1f900009
,
0x0
,
0xa0000001
,
0x30
,
0xd0000000
,
0x1
,
0x4f8c1220
,
0x1
,
0x4f8c121c
,
0x0
,
0x10000001
,
0x0
,
0xa0000001
,
0x70
,
0xd0000000
,
0x4000
,
0x1f900009
,
0x0
,
0xa0000001
,
0x30
,
0xd0000000
,
0x0
,
0x4f8c1220
,
0x1
,
0x4f8c121c
,
0x0
,
0x10000001
,
0x0
,
0xa0000001
,
0x30
,
0xd0000000
,
0x1000
,
0x1f900009
,
0x0
,
0xa0000001
,
0x18
,
0xd0000000
,
0x0
,
0x4f8c1220
,
0x1
,
0x4f8c121c
,
0x0
,
0x10000001
,
0x0
,
0xa0000001
,
0x100
,
0xd0000000
,
0x0
,
0xaf8c1211
,
0xf0
,
0xd0000000
,
0x2000
,
0x1f8f0009
,
0x0
,
0xa0000001
,
0x30
,
0xd0000000
,
0x0
,
0x4f8c1220
,
0x0
,
0x4f8c121c
,
0x0
,
0x10000001
,
0x0
,
0xa0000001
,
0xb0
,
0xd0000000
,
0x8000
,
0x1f8f0009
,
0x0
,
0xa0000001
,
0x30
,
0xd0000000
,
0x1
,
0x4f8c1220
,
0x1
,
0x4f8c121c
,
0x0
,
0x10000001
,
0x0
,
0xa0000001
,
0x70
,
0xd0000000
,
0x4000
,
0x1f8f0009
,
0x0
,
0xa0000001
,
0x30
,
0xd0000000
,
0x0
,
0x4f8c1220
,
0x1
,
0x4f8c121c
,
0x0
,
0x10000001
,
0x0
,
0xa0000001
,
0x30
,
0xd0000000
,
0x1000
,
0x1f8f0009
,
0x0
,
0xa0000001
,
0x18
,
0xd0000000
,
0x0
,
0x4f8c1220
,
0x1
,
0x4f8c121c
,
0x0
,
0xaf8c120d
,
0x40
,
0xd0000000
,
0x80008000
,
0x7f900284
,
0x1
,
0x0
,
0x8000
,
0x1f90028d
,
0x0
,
0x60000001
,
0x0
,
0x10000001
,
0x0
,
0xa0000001
,
0x38
,
0xd0000000
,
0x0
,
0xaf8c1211
,
0x28
,
0xd0000000
,
0x80008000
,
0x7f8f0284
,
0x1
,
0x0
,
0x8000
,
0x1f8f028d
,
0x0
,
0x60000001
,
0xffffffff
,
0x4f77e200
,
0xffffffff
,
0x4f77e204
,
0xffffffff
,
0x4f77e208
,
0xffffffff
,
0x4f77e20c
,
0x70007000
,
0x4f77e210
,
0x3fffffff
,
0x7f750130
,
0x0
,
0x2f310061
,
0xc0000
,
0x20000001
,
0x0
,
0x4f310061
,
0xc0000
,
0x1f310065
,
0xc0000
,
0xb0000001
,
0x10
,
0xc0000000
,
0x0
,
0xaf8c121d
,
0x48
,
0xd0000000
,
0x0
,
0xaf8c120d
,
0x18
,
0xd0000000
,
0x80000000
,
0x2f90000d
,
0x0
,
0x4f90000d
,
0x0
,
0xaf8c1211
,
0x18
,
0xd0000000
,
0x80000000
,
0x2f90000d
,
0x0
,
0x4f8f000d
,
0x0
,
0x2f8c101d
,
0x350005
,
0x20000001
,
0x0
,
0x4f620001
,
0x1
,
0x0
,
0x4
,
0x1f620011
,
0x0
,
0x60000001
,
0x3000000
,
0x7f76004c
,
0x18
,
0x0
,
0x10001
,
0x7f76004c
,
0x0
,
0x2f8c1005
,
0x0
,
0x4f760041
,
0x0
,
0x2f8c1009
,
0x0
,
0x4f760045
,
0x10000
,
0x7f76004c
,
0x18
,
0x0
,
0x1
,
0x0
,
0x80000000
,
0x1f760049
,
0x0
,
0x60000001
,
0x3000100
,
0x7f76004c
,
0x3e8
,
0x0
,
0x20002
,
0x4f620000
,
0x1
,
0x0
,
0x1
,
0x1f620011
,
0x0
,
0x60000001
,
0x0
,
0xaf8c121d
,
0x48
,
0xd0000000
,
0x0
,
0xaf8c120d
,
0x18
,
0xd0000000
,
0x7fffffff
,
0x1f90000d
,
0x0
,
0x4f90000d
,
0x0
,
0xaf8c1211
,
0x18
,
0xd0000000
,
0x7fffffff
,
0x1f90000d
,
0x0
,
0x4f8f000d
,
0xfff3ffff
,
0x1f310061
,
0x0
,
0x7f310061
,
0xc0000
,
0x1f310065
,
0x0
,
0xb0000001
,
0x10
,
0xc0000000
,
0x0
,
0x7f750130
,
0x1
,
0x0
,
0x1
,
0x0
,
0x1
,
0x0
,
0x1
,
0x0
,
0x1
,
0x0
,
0x1
,
0x0
,
0x1
,
0x0
,
0x1
,
0x0
,
0x1
,
0x0
,
0x0
,
0xe0000000
,
plat/rockchip/rk3399/drivers/dram/dfs.c
View file @
d6845d3d
...
...
@@ -28,8 +28,10 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <arch_helpers.h>
#include <debug.h>
#include <mmio.h>
#include <m0_ctl.h>
#include <plat_private.h>
#include "dfs.h"
#include "dram.h"
...
...
@@ -40,31 +42,14 @@
#include <delay_timer.h>
#define CTL_TRAINING (1)
#define PI_TRAINING (!CTL_TRAINING)
#define EN_READ_GATE_TRAINING (1)
#define EN_CA_TRAINING (0)
#define EN_WRITE_LEVELING (0)
#define EN_READ_LEVELING (0)
#define EN_WDQ_LEVELING (0)
#define ENPER_CS_TRAINING_FREQ (933)
struct
pll_div
{
unsigned
int
mhz
;
unsigned
int
refdiv
;
unsigned
int
fbdiv
;
unsigned
int
postdiv1
;
unsigned
int
postdiv2
;
unsigned
int
frac
;
unsigned
int
freq
;
};
#define ENPER_CS_TRAINING_FREQ (666)
#define TDFI_LAT_THRESHOLD_FREQ (928)
#define PHY_DLL_BYPASS_FREQ (260)
static
const
struct
pll_div
dpll_rates_table
[]
=
{
/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2 */
{.
mhz
=
9
33
,
.
refdiv
=
3
,
.
fbdiv
=
350
,
.
postdiv1
=
3
,
.
postdiv2
=
1
},
{.
mhz
=
9
28
,
.
refdiv
=
1
,
.
fbdiv
=
116
,
.
postdiv1
=
3
,
.
postdiv2
=
1
},
{.
mhz
=
800
,
.
refdiv
=
1
,
.
fbdiv
=
100
,
.
postdiv1
=
3
,
.
postdiv2
=
1
},
{.
mhz
=
732
,
.
refdiv
=
1
,
.
fbdiv
=
61
,
.
postdiv1
=
2
,
.
postdiv2
=
1
},
{.
mhz
=
666
,
.
refdiv
=
1
,
.
fbdiv
=
111
,
.
postdiv1
=
4
,
.
postdiv2
=
1
},
...
...
@@ -78,128 +63,44 @@ static const struct pll_div dpll_rates_table[] = {
struct
rk3399_dram_status
{
uint32_t
current_index
;
uint32_t
index_freq
[
2
];
uint32_t
boot_freq
;
uint32_t
low_power_stat
;
struct
timing_related_config
timing_config
;
struct
drv_odt_lp_config
drv_odt_lp_cfg
;
};
static
struct
rk3399_dram_status
rk3399_dram_status
;
static
struct
ddr_dts_config_timing
dts_parameter
=
{
.
available
=
0
struct
rk3399_saved_status
{
uint32_t
freq
;
uint32_t
low_power_stat
;
uint32_t
odt
;
};
static
struct
rk3399_dram_status
rk3399_dram_status
;
static
struct
rk3399_saved_status
rk3399_suspend_status
;
static
uint32_t
wrdqs_delay_val
[
2
][
2
][
4
];
static
struct
rk3399_sdram_default_config
ddr3_default_config
=
{
.
bl
=
8
,
.
ap
=
0
,
.
dramds
=
40
,
.
dramodt
=
120
,
.
burst_ref_cnt
=
1
,
.
zqcsi
=
0
};
static
struct
drv_odt_lp_config
ddr3_drv_odt_default_config
=
{
.
ddr3_speed_bin
=
DDR3_DEFAULT
,
.
pd_idle
=
0
,
.
sr_idle
=
0
,
.
sr_mc_gate_idle
=
0
,
.
srpd_lite_idle
=
0
,
.
standby_idle
=
0
,
.
ddr3_dll_dis_freq
=
300
,
.
phy_dll_dis_freq
=
125
,
.
odt_dis_freq
=
933
,
.
dram_side_drv
=
40
,
.
dram_side_dq_odt
=
120
,
.
dram_side_ca_odt
=
120
,
.
phy_side_ca_drv
=
40
,
.
phy_side_ck_cs_drv
=
40
,
.
phy_side_dq_drv
=
40
,
.
phy_side_odt
=
240
,
};
static
struct
rk3399_sdram_default_config
lpddr3_default_config
=
{
.
bl
=
8
,
.
ap
=
0
,
.
dramds
=
34
,
.
dramodt
=
240
,
.
burst_ref_cnt
=
1
,
.
zqcsi
=
0
};
static
struct
drv_odt_lp_config
lpddr3_drv_odt_default_config
=
{
.
ddr3_speed_bin
=
DDR3_DEFAULT
,
.
pd_idle
=
0
,
.
sr_idle
=
0
,
.
sr_mc_gate_idle
=
0
,
.
srpd_lite_idle
=
0
,
.
standby_idle
=
0
,
.
ddr3_dll_dis_freq
=
300
,
.
phy_dll_dis_freq
=
125
,
.
odt_dis_freq
=
666
,
.
dram_side_drv
=
40
,
.
dram_side_dq_odt
=
120
,
.
dram_side_ca_odt
=
120
,
.
phy_side_ca_drv
=
40
,
.
phy_side_ck_cs_drv
=
40
,
.
phy_side_dq_drv
=
40
,
.
phy_side_odt
=
240
,
};
static
struct
rk3399_sdram_default_config
lpddr4_default_config
=
{
.
bl
=
16
,
.
ap
=
0
,
.
dramds
=
40
,
.
dramodt
=
240
,
.
caodt
=
240
,
.
burst_ref_cnt
=
1
,
.
zqcsi
=
0
};
static
struct
drv_odt_lp_config
lpddr4_drv_odt_default_config
=
{
.
ddr3_speed_bin
=
DDR3_DEFAULT
,
.
pd_idle
=
0
,
.
sr_idle
=
0
,
.
sr_mc_gate_idle
=
0
,
.
srpd_lite_idle
=
0
,
.
standby_idle
=
0
,
.
ddr3_dll_dis_freq
=
300
,
.
phy_dll_dis_freq
=
125
,
.
odt_dis_freq
=
933
,
.
dram_side_drv
=
60
,
.
dram_side_dq_odt
=
40
,
.
dram_side_ca_odt
=
40
,
.
phy_side_ca_drv
=
40
,
.
phy_side_ck_cs_drv
=
80
,
.
phy_side_dq_drv
=
80
,
.
phy_side_odt
=
60
,
};
uint32_t
dcf_code
[]
=
{
#include "dcf_code.inc"
};
#define DCF_START_ADDR (SRAM_BASE + 0x1400)
#define DCF_PARAM_ADDR (SRAM_BASE + 0x1000)
/* DCF_PAMET */
#define PARAM_DRAM_FREQ (0)
#define PARAM_DPLL_CON0 (4)
#define PARAM_DPLL_CON1 (8)
#define PARAM_DPLL_CON2 (0xc)
#define PARAM_DPLL_CON3 (0x10)
#define PARAM_DPLL_CON4 (0x14)
#define PARAM_DPLL_CON5 (0x18)
/* equal to fn<<4 */
#define PARAM_FREQ_SELECT (0x1c)
static
uint32_t
get_cs_die_capability
(
struct
rk3399_sdram_params
*
sdram_config
,
uint8_t
channel
,
uint8_t
cs
)
{
...
...
@@ -222,176 +123,79 @@ static uint32_t get_cs_die_capability(struct rk3399_sdram_params *sdram_config,
return
(
cs_cap
/
die
);
}
static
void
drv_odt_lp_cfg_init
(
uint32_t
dram_type
,
struct
ddr_dts_config_timing
*
dts_timing
,
static
void
get_dram_drv_odt_val
(
uint32_t
dram_type
,
struct
drv_odt_lp_config
*
drv_config
)
{
if
((
dts_timing
)
&&
(
dts_timing
->
available
))
{
drv_config
->
ddr3_speed_bin
=
dts_timing
->
ddr3_speed_bin
;
drv_config
->
pd_idle
=
dts_timing
->
pd_idle
;
drv_config
->
sr_idle
=
dts_timing
->
sr_idle
;
drv_config
->
sr_mc_gate_idle
=
dts_timing
->
sr_mc_gate_idle
;
drv_config
->
srpd_lite_idle
=
dts_timing
->
srpd_lite_idle
;
drv_config
->
standby_idle
=
dts_timing
->
standby_idle
;
drv_config
->
ddr3_dll_dis_freq
=
dts_timing
->
ddr3_dll_dis_freq
;
drv_config
->
phy_dll_dis_freq
=
dts_timing
->
phy_dll_dis_freq
;
}
uint32_t
tmp
;
uint32_t
mr1_val
,
mr3_val
,
mr11_val
;
switch
(
dram_type
)
{
case
DDR3
:
if
((
dts_timing
)
&&
(
dts_timing
->
available
))
{
drv_config
->
odt_dis_freq
=
dts_timing
->
ddr3_odt_dis_freq
;
drv_config
->
dram_side_drv
=
dts_timing
->
ddr3_drv
;
drv_config
->
dram_side_dq_odt
=
dts_timing
->
ddr3_odt
;
drv_config
->
phy
_side_
ca_
drv
=
dts_timing
->
phy_ddr3_ca_drv
;
drv_config
->
phy_side_ck_cs_drv
=
dts_timing
->
phy_ddr3_ca_drv
;
drv_config
->
phy
_side_dq_
drv
=
dts_timing
->
phy_ddr3_dq_drv
;
drv_config
->
phy
_side_odt
=
dts_timing
->
phy_ddr3_odt
;
}
else
{
memcpy
(
drv_config
,
&
ddr3_drv_odt_default_config
,
sizeof
(
struct
drv_odt_lp_config
));
}
mr1_val
=
(
mmio_read_32
(
CTL_REG
(
0
,
133
))
>>
16
)
&
0xffff
;
tmp
=
((
mr1_val
>>
1
)
&
1
)
|
((
mr1_val
>>
4
)
&
1
);
if
(
tmp
)
drv_config
->
dram_side_drv
=
34
;
else
drv_config
->
dram
_side_drv
=
40
;
tmp
=
((
mr1_val
>>
2
)
&
1
)
|
((
mr1_val
>>
5
)
&
1
)
|
((
mr1_val
>>
7
)
&
1
);
if
(
tmp
==
0
)
drv_config
->
dram
_side_dq_
odt
=
0
;
else
if
(
tmp
==
1
)
drv_config
->
dram
_side_
dq_
odt
=
60
;
else
if
(
tmp
==
3
)
drv_config
->
dram_side_dq_odt
=
40
;
else
drv_config
->
dram_side_dq_odt
=
120
;
break
;
case
LPDDR3
:
if
((
dts_timing
)
&&
(
dts_timing
->
available
))
{
drv_config
->
odt_dis_freq
=
dts_timing
->
lpddr3_odt_dis_freq
;
drv_config
->
dram_side_drv
=
dts_timing
->
lpddr3_drv
;
drv_config
->
dram_side_dq_odt
=
dts_timing
->
lpddr3_odt
;
drv_config
->
phy_side_ca_drv
=
dts_timing
->
phy_lpddr3_ca_drv
;
drv_config
->
phy_side_ck_cs_drv
=
dts_timing
->
phy_lpddr3_ca_drv
;
drv_config
->
phy_side_dq_drv
=
dts_timing
->
phy_lpddr3_dq_drv
;
drv_config
->
phy_side_odt
=
dts_timing
->
phy_lpddr3_odt
;
}
else
{
memcpy
(
drv_config
,
&
lpddr3_drv_odt_default_config
,
sizeof
(
struct
drv_odt_lp_config
));
}
mr3_val
=
mmio_read_32
(
CTL_REG
(
0
,
138
))
&
0xf
;
mr11_val
=
(
mmio_read_32
(
CTL_REG
(
0
,
139
))
>>
24
)
&
0x3
;
if
(
mr3_val
==
0xb
)
drv_config
->
dram_side_drv
=
3448
;
else
if
(
mr3_val
==
0xa
)
drv_config
->
dram_side_drv
=
4048
;
else
if
(
mr3_val
==
0x9
)
drv_config
->
dram_side_drv
=
3440
;
else
if
(
mr3_val
==
0x4
)
drv_config
->
dram_side_drv
=
60
;
else
if
(
mr3_val
==
0x3
)
drv_config
->
dram_side_drv
=
48
;
else
if
(
mr3_val
==
0x2
)
drv_config
->
dram_side_drv
=
40
;
else
drv_config
->
dram_side_drv
=
34
;
if
(
mr11_val
==
1
)
drv_config
->
dram_side_dq_odt
=
60
;
else
if
(
mr11_val
==
2
)
drv_config
->
dram_side_dq_odt
=
120
;
else
if
(
mr11_val
==
0
)
drv_config
->
dram_side_dq_odt
=
0
;
else
drv_config
->
dram_side_dq_odt
=
240
;
break
;
case
LPDDR4
:
default:
if
((
dts_timing
)
&&
(
dts_timing
->
available
))
{
drv_config
->
odt_dis_freq
=
dts_timing
->
lpddr4_odt_dis_freq
;
drv_config
->
dram_side_drv
=
dts_timing
->
lpddr4_drv
;
drv_config
->
dram_side_dq_odt
=
dts_timing
->
lpddr4_dq_odt
;
drv_config
->
dram_side_ca_odt
=
dts_timing
->
lpddr4_ca_odt
;
drv_config
->
phy_side_ca_drv
=
dts_timing
->
phy_lpddr4_ca_drv
;
drv_config
->
phy_side_ck_cs_drv
=
dts_timing
->
phy_lpddr4_ck_cs_drv
;
drv_config
->
phy_side_dq_drv
=
dts_timing
->
phy_lpddr4_dq_drv
;
drv_config
->
phy_side_odt
=
dts_timing
->
phy_lpddr4_odt
;
}
else
{
memcpy
(
drv_config
,
&
lpddr4_drv_odt_default_config
,
sizeof
(
struct
drv_odt_lp_config
));
}
break
;
}
switch
(
drv_config
->
phy_side_ca_drv
)
{
case
240
:
drv_config
->
phy_side_ca_drv
=
PHY_DRV_ODT_240
;
break
;
case
120
:
drv_config
->
phy_side_ca_drv
=
PHY_DRV_ODT_120
;
break
;
case
80
:
drv_config
->
phy_side_ca_drv
=
PHY_DRV_ODT_80
;
break
;
case
60
:
drv_config
->
phy_side_ca_drv
=
PHY_DRV_ODT_60
;
break
;
case
48
:
drv_config
->
phy_side_ca_drv
=
PHY_DRV_ODT_48
;
break
;
case
40
:
drv_config
->
phy_side_ca_drv
=
PHY_DRV_ODT_40
;
break
;
default:
drv_config
->
phy_side_ca_drv
=
PHY_DRV_ODT_34_3
;
break
;
};
mr3_val
=
(
mmio_read_32
(
CTL_REG
(
0
,
138
))
>>
3
)
&
0x7
;
mr11_val
=
(
mmio_read_32
(
CTL_REG
(
0
,
139
))
>>
24
)
&
0xff
;
switch
(
drv_config
->
phy_side_ck_cs_drv
)
{
case
240
:
drv_config
->
phy_side_ck_cs_drv
=
PHY_DRV_ODT_240
;
break
;
case
120
:
drv_config
->
phy_side_ck_cs_drv
=
PHY_DRV_ODT_120
;
break
;
case
80
:
drv_config
->
phy_side_ck_cs_drv
=
PHY_DRV_ODT_80
;
break
;
case
60
:
drv_config
->
phy_side_ck_cs_drv
=
PHY_DRV_ODT_60
;
break
;
case
48
:
drv_config
->
phy_side_ck_cs_drv
=
PHY_DRV_ODT_48
;
break
;
case
40
:
drv_config
->
phy_side_ck_cs_drv
=
PHY_DRV_ODT_40
;
break
;
default:
drv_config
->
phy_side_ck_cs_drv
=
PHY_DRV_ODT_34_3
;
break
;
}
if
((
mr3_val
==
0
)
||
(
mr3_val
==
7
))
drv_config
->
dram_side_drv
=
40
;
else
drv_config
->
dram_side_drv
=
240
/
mr3_val
;
switch
(
drv_config
->
phy_side_dq_drv
)
{
case
240
:
drv_config
->
phy_side_dq_drv
=
PHY_DRV_ODT_240
;
break
;
case
120
:
drv_config
->
phy_side_dq_drv
=
PHY_DRV_ODT_120
;
break
;
case
80
:
drv_config
->
phy_side_dq_drv
=
PHY_DRV_ODT_80
;
break
;
case
60
:
drv_config
->
phy_side_dq_drv
=
PHY_DRV_ODT_60
;
break
;
case
48
:
drv_config
->
phy_side_dq_drv
=
PHY_DRV_ODT_48
;
break
;
case
40
:
drv_config
->
phy_side_dq_drv
=
PHY_DRV_ODT_40
;
break
;
default:
drv_config
->
phy_side_dq_drv
=
PHY_DRV_ODT_34_3
;
break
;
}
tmp
=
mr11_val
&
0x7
;
if
((
tmp
==
7
)
||
(
tmp
==
0
))
drv_config
->
dram_side_dq_odt
=
0
;
else
drv_config
->
dram_side_dq_odt
=
240
/
tmp
;
switch
(
drv_config
->
phy_side_odt
)
{
case
240
:
drv_config
->
phy_side_odt
=
PHY_DRV_ODT_240
;
break
;
case
120
:
drv_config
->
phy_side_odt
=
PHY_DRV_ODT_120
;
break
;
case
80
:
drv_config
->
phy_side_odt
=
PHY_DRV_ODT_80
;
break
;
case
60
:
drv_config
->
phy_side_odt
=
PHY_DRV_ODT_60
;
break
;
case
48
:
drv_config
->
phy_side_odt
=
PHY_DRV_ODT_48
;
break
;
case
40
:
drv_config
->
phy_side_odt
=
PHY_DRV_ODT_40
;
break
;
default:
drv_config
->
phy_side_odt
=
PHY_DRV_ODT_34_3
;
tmp
=
(
mr11_val
>>
4
)
&
0x7
;
if
((
tmp
==
7
)
||
(
tmp
==
0
))
drv_config
->
dram_side_ca_odt
=
0
;
else
drv_config
->
dram_side_ca_odt
=
240
/
tmp
;
break
;
}
}
...
...
@@ -403,8 +207,7 @@ static void sdram_timing_cfg_init(struct timing_related_config *ptiming_config,
uint32_t
i
,
j
;
for
(
i
=
0
;
i
<
sdram_params
->
num_channels
;
i
++
)
{
ptiming_config
->
dram_info
[
i
].
speed_rate
=
drv_config
->
ddr3_speed_bin
;
ptiming_config
->
dram_info
[
i
].
speed_rate
=
DDR3_DEFAULT
;
ptiming_config
->
dram_info
[
i
].
cs_cnt
=
sdram_params
->
ch
[
i
].
rank
;
for
(
j
=
0
;
j
<
sdram_params
->
ch
[
i
].
rank
;
j
++
)
{
ptiming_config
->
dram_info
[
i
].
per_die_capability
[
j
]
=
...
...
@@ -432,6 +235,7 @@ static void sdram_timing_cfg_init(struct timing_related_config *ptiming_config,
ptiming_config
->
dramds
=
drv_config
->
dram_side_drv
;
ptiming_config
->
dramodt
=
drv_config
->
dram_side_dq_odt
;
ptiming_config
->
caodt
=
drv_config
->
dram_side_ca_odt
;
ptiming_config
->
odt
=
(
mmio_read_32
(
PHY_REG
(
0
,
5
))
>>
16
)
&
0x1
;
}
struct
lat_adj_pair
{
...
...
@@ -928,7 +732,7 @@ static void gen_rk3399_ctl_params_f0(struct timing_related_config
/* CTL_314 TDFI_WRCSLAT_F0:RW:8:8 */
tmp1
=
get_pi_wrlat_adj
(
pdram_timing
,
timing_config
);
if
(
timing_config
->
freq
<=
ENPER_CS_TRAINING
_FREQ
)
{
if
(
timing_config
->
freq
<=
TDFI_LAT_THRESHOLD
_FREQ
)
{
if
(
tmp1
==
0
)
tmp
=
0
;
else
if
(
tmp1
<
5
)
...
...
@@ -941,7 +745,7 @@ static void gen_rk3399_ctl_params_f0(struct timing_related_config
mmio_clrsetbits_32
(
CTL_REG
(
i
,
314
),
0xff
<<
8
,
tmp
<<
8
);
/* CTL_314 TDFI_RDCSLAT_F0:RW:0:8 */
if
((
timing_config
->
freq
<=
ENPER_CS_TRAINING
_FREQ
)
&&
if
((
timing_config
->
freq
<=
TDFI_LAT_THRESHOLD
_FREQ
)
&&
(
pdram_timing
->
cl
>=
5
))
tmp
=
pdram_timing
->
cl
-
5
;
else
...
...
@@ -1178,7 +982,7 @@ static void gen_rk3399_ctl_params_f1(struct timing_related_config
/* CTL_314 TDFI_WRCSLAT_F1:RW:24:8 */
tmp1
=
get_pi_wrlat_adj
(
pdram_timing
,
timing_config
);
if
(
timing_config
->
freq
<=
ENPER_CS_TRAINING
_FREQ
)
{
if
(
timing_config
->
freq
<=
TDFI_LAT_THRESHOLD
_FREQ
)
{
if
(
tmp1
==
0
)
tmp
=
0
;
else
if
(
tmp1
<
5
)
...
...
@@ -1192,7 +996,7 @@ static void gen_rk3399_ctl_params_f1(struct timing_related_config
mmio_clrsetbits_32
(
CTL_REG
(
i
,
314
),
0xff
<<
24
,
tmp
<<
24
);
/* CTL_314 TDFI_RDCSLAT_F1:RW:16:8 */
if
((
timing_config
->
freq
<=
ENPER_CS_TRAINING
_FREQ
)
&&
if
((
timing_config
->
freq
<=
TDFI_LAT_THRESHOLD
_FREQ
)
&&
(
pdram_timing
->
cl
>=
5
))
tmp
=
pdram_timing
->
cl
-
5
;
else
...
...
@@ -1201,6 +1005,33 @@ static void gen_rk3399_ctl_params_f1(struct timing_related_config
}
}
static
void
gen_rk3399_enable_training
(
uint32_t
ch_cnt
,
uint32_t
nmhz
)
{
uint32_t
i
,
tmp
;
if
(
nmhz
<=
PHY_DLL_BYPASS_FREQ
)
tmp
=
0
;
else
tmp
=
1
;
for
(
i
=
0
;
i
<
ch_cnt
;
i
++
)
{
mmio_clrsetbits_32
(
CTL_REG
(
i
,
305
),
1
<<
16
,
tmp
<<
16
);
mmio_clrsetbits_32
(
CTL_REG
(
i
,
71
),
1
,
tmp
);
mmio_clrsetbits_32
(
CTL_REG
(
i
,
70
),
1
<<
8
,
1
<<
8
);
}
}
static
void
gen_rk3399_disable_training
(
uint32_t
ch_cnt
)
{
uint32_t
i
;
for
(
i
=
0
;
i
<
ch_cnt
;
i
++
)
{
mmio_clrbits_32
(
CTL_REG
(
i
,
305
),
1
<<
16
);
mmio_clrbits_32
(
CTL_REG
(
i
,
71
),
1
);
mmio_clrbits_32
(
CTL_REG
(
i
,
70
),
1
<<
8
);
}
}
static
void
gen_rk3399_ctl_params
(
struct
timing_related_config
*
timing_config
,
struct
dram_timing_t
*
pdram_timing
,
uint32_t
fn
)
...
...
@@ -1209,35 +1040,6 @@ static void gen_rk3399_ctl_params(struct timing_related_config *timing_config,
gen_rk3399_ctl_params_f0
(
timing_config
,
pdram_timing
);
else
gen_rk3399_ctl_params_f1
(
timing_config
,
pdram_timing
);
#if CTL_TRAINING
uint32_t
i
,
tmp0
,
tmp1
;
tmp0
=
tmp1
=
0
;
#if EN_READ_GATE_TRAINING
tmp1
=
1
;
#endif
#if EN_CA_TRAINING
tmp0
|=
(
1
<<
8
);
#endif
#if EN_WRITE_LEVELING
tmp0
|=
(
1
<<
16
);
#endif
#if EN_READ_LEVELING
tmp0
|=
(
1
<<
24
);
#endif
for
(
i
=
0
;
i
<
timing_config
->
ch_cnt
;
i
++
)
{
if
(
tmp0
|
tmp1
)
mmio_setbits_32
(
CTL_REG
(
i
,
305
),
1
<<
16
);
if
(
tmp0
)
mmio_setbits_32
(
CTL_REG
(
i
,
70
),
tmp0
);
if
(
tmp1
)
mmio_setbits_32
(
CTL_REG
(
i
,
71
),
tmp1
);
}
#endif
}
static
void
gen_rk3399_pi_params_f0
(
struct
timing_related_config
*
timing_config
,
...
...
@@ -1381,7 +1183,8 @@ static void gen_rk3399_pi_params_f0(struct timing_related_config *timing_config,
mmio_clrsetbits_32
(
PI_REG
(
i
,
148
),
0xffff
<<
16
,
pdram_timing
->
mr
[
2
]
<<
16
);
/* PI_156 PI_TFC_F0:RW:0:10 */
mmio_clrsetbits_32
(
PI_REG
(
i
,
156
),
0x3ff
,
pdram_timing
->
trfc
);
mmio_clrsetbits_32
(
PI_REG
(
i
,
156
),
0x3ff
,
pdram_timing
->
tfc_long
);
/* PI_158 PI_TWR_F0:RW:24:6 */
mmio_clrsetbits_32
(
PI_REG
(
i
,
158
),
0x3f
<<
24
,
pdram_timing
->
twr
<<
24
);
...
...
@@ -1452,7 +1255,7 @@ static void gen_rk3399_pi_params_f1(struct timing_related_config *timing_config,
mmio_clrsetbits_32
(
PI_REG
(
i
,
44
),
0x3f
,
PI_ADD_LATENCY
);
/* PI_44 PI_CASLAT_LIN_F1:RW:8:7:=0x18 */
mmio_clrsetbits_32
(
PI_REG
(
i
,
44
),
0x7f
<<
8
,
pdram_timing
->
cl
*
2
);
(
pdram_timing
->
cl
*
2
)
<<
8
)
;
/* PI_47 PI_TREF_F1:RW:16:16 */
mmio_clrsetbits_32
(
PI_REG
(
i
,
47
),
0xffff
<<
16
,
pdram_timing
->
trefi
<<
16
);
...
...
@@ -1561,7 +1364,7 @@ static void gen_rk3399_pi_params_f1(struct timing_related_config *timing_config,
mmio_clrsetbits_32
(
PI_REG
(
i
,
151
),
0xffff
,
pdram_timing
->
mr
[
2
]);
/* PI_156 PI_TFC_F1:RW:16:10 */
mmio_clrsetbits_32
(
PI_REG
(
i
,
156
),
0x3ff
<<
16
,
pdram_timing
->
t
r
fc
<<
16
);
pdram_timing
->
tfc
_long
<<
16
);
/* PI_162 PI_TWR_F1:RW:8:6 */
mmio_clrsetbits_32
(
PI_REG
(
i
,
162
),
0x3f
<<
8
,
pdram_timing
->
twr
<<
8
);
...
...
@@ -1605,32 +1408,6 @@ static void gen_rk3399_pi_params(struct timing_related_config *timing_config,
gen_rk3399_pi_params_f0
(
timing_config
,
pdram_timing
);
else
gen_rk3399_pi_params_f1
(
timing_config
,
pdram_timing
);
#if PI_TRAINING
uint32_t
i
;
for
(
i
=
0
;
i
<
timing_config
->
ch_cnt
;
i
++
)
{
#if EN_READ_GATE_TRAINING
mmio_clrsetbits_32
(
PI_REG
(
i
,
80
),
3
<<
24
,
2
<<
24
);
#endif
#if EN_CA_TRAINING
mmio_clrsetbits_32
(
PI_REG
(
i
,
100
),
3
<<
8
,
2
<<
8
);
#endif
#if EN_WRITE_LEVELING
mmio_clrsetbits_32
(
PI_REG
(
i
,
60
),
3
<<
8
,
2
<<
8
);
#endif
#if EN_READ_LEVELING
mmio_clrsetbits_32
(
PI_REG
(
i
,
80
),
3
<<
16
,
2
<<
16
);
#endif
#if EN_WDQ_LEVELING
mmio_clrsetbits_32
(
PI_REG
(
i
,
124
),
3
<<
16
,
2
<<
16
);
#endif
}
#endif
}
static
void
gen_rk3399_set_odt
(
uint32_t
odt_en
)
...
...
@@ -1652,57 +1429,92 @@ static void gen_rk3399_set_odt(uint32_t odt_en)
}
}
static
void
gen_rk3399_
set_ds_odt
(
struct
timing_related_config
*
timing_config
,
struct
drv_odt_lp_config
*
drv_config
)
static
void
gen_rk3399_
phy_dll_bypass
(
uint32_t
mhz
,
uint32_t
ch
,
uint32_t
index
,
uint32_t
dram_type
)
{
uint32_t
i
,
drv_odt_val
;
uint32_t
sw_master_mode
=
0
;
uint32_t
rddqs_gate_delay
,
rddqs_latency
,
total_delay
;
uint32_t
i
;
for
(
i
=
0
;
i
<
timing_config
->
ch_cnt
;
i
++
)
{
if
(
timing_config
->
dram_type
==
LPDDR4
)
drv_odt_val
=
drv_config
->
phy_side_odt
|
(
PHY_DRV_ODT_Hi_Z
<<
4
)
|
(
drv_config
->
phy_side_dq_drv
<<
8
)
|
(
drv_config
->
phy_side_dq_drv
<<
12
);
else
if
(
timing_config
->
dram_type
==
LPDDR3
)
drv_odt_val
=
PHY_DRV_ODT_Hi_Z
|
(
drv_config
->
phy_side_odt
<<
4
)
|
(
drv_config
->
phy_side_dq_drv
<<
8
)
|
(
drv_config
->
phy_side_dq_drv
<<
12
);
if
(
dram_type
==
DDR3
)
total_delay
=
PI_PAD_DELAY_PS_VALUE
;
else
if
(
dram_type
==
LPDDR3
)
total_delay
=
PI_PAD_DELAY_PS_VALUE
+
2500
;
else
drv_odt_val
=
drv_config
->
phy_side_odt
|
(
drv_config
->
phy_side_odt
<<
4
)
|
(
drv_config
->
phy_side_dq_drv
<<
8
)
|
(
drv_config
->
phy_side_dq_drv
<<
12
);
/* DQ drv odt set */
mmio_clrsetbits_32
(
PHY_REG
(
i
,
6
),
0xffffff
,
drv_odt_val
);
mmio_clrsetbits_32
(
PHY_REG
(
i
,
134
),
0xffffff
,
drv_odt_val
);
mmio_clrsetbits_32
(
PHY_REG
(
i
,
262
),
0xffffff
,
drv_odt_val
);
mmio_clrsetbits_32
(
PHY_REG
(
i
,
390
),
0xffffff
,
drv_odt_val
);
/* DQS drv odt set */
mmio_clrsetbits_32
(
PHY_REG
(
i
,
7
),
0xffffff
,
drv_odt_val
);
mmio_clrsetbits_32
(
PHY_REG
(
i
,
135
),
0xffffff
,
drv_odt_val
);
mmio_clrsetbits_32
(
PHY_REG
(
i
,
263
),
0xffffff
,
drv_odt_val
);
mmio_clrsetbits_32
(
PHY_REG
(
i
,
391
),
0xffffff
,
drv_odt_val
);
gen_rk3399_set_odt
(
timing_config
->
odt
);
/* CA drv set */
drv_odt_val
=
drv_config
->
phy_side_ca_drv
|
(
drv_config
->
phy_side_ca_drv
<<
4
);
mmio_clrsetbits_32
(
PHY_REG
(
i
,
544
),
0xff
,
drv_odt_val
);
mmio_clrsetbits_32
(
PHY_REG
(
i
,
672
),
0xff
,
drv_odt_val
);
mmio_clrsetbits_32
(
PHY_REG
(
i
,
800
),
0xff
,
drv_odt_val
);
mmio_clrsetbits_32
(
PHY_REG
(
i
,
928
),
0xff
,
drv_odt_val
);
mmio_clrsetbits_32
(
PHY_REG
(
i
,
937
),
0xff
,
drv_odt_val
);
mmio_clrsetbits_32
(
PHY_REG
(
i
,
935
),
0xff
,
drv_odt_val
);
drv_odt_val
=
drv_config
->
phy_side_ck_cs_drv
|
(
drv_config
->
phy_side_ck_cs_drv
<<
4
);
mmio_clrsetbits_32
(
PHY_REG
(
i
,
929
),
0xff
,
drv_odt_val
);
mmio_clrsetbits_32
(
PHY_REG
(
i
,
939
),
0xff
,
drv_odt_val
);
total_delay
=
PI_PAD_DELAY_PS_VALUE
+
1500
;
/* total_delay + 0.55tck */
total_delay
+=
(
55
*
10000
)
/
mhz
;
rddqs_latency
=
total_delay
*
mhz
/
1000000
;
total_delay
-=
rddqs_latency
*
1000000
/
mhz
;
rddqs_gate_delay
=
total_delay
*
0x200
*
mhz
/
1000000
;
if
(
mhz
<=
PHY_DLL_BYPASS_FREQ
)
{
sw_master_mode
=
0xc
;
mmio_setbits_32
(
PHY_REG
(
ch
,
514
),
1
);
mmio_setbits_32
(
PHY_REG
(
ch
,
642
),
1
);
mmio_setbits_32
(
PHY_REG
(
ch
,
770
),
1
);
/* setting bypass mode slave delay */
for
(
i
=
0
;
i
<
4
;
i
++
)
{
/* wr dq delay = -180deg + (0x60 / 4) * 20ps */
mmio_clrsetbits_32
(
PHY_REG
(
ch
,
1
+
128
*
i
),
0x7ff
<<
8
,
0x4a0
<<
8
);
/* rd dqs/dq delay = (0x60 / 4) * 20ps */
mmio_clrsetbits_32
(
PHY_REG
(
ch
,
11
+
128
*
i
),
0x3ff
,
0xa0
);
/* rd rddqs_gate delay */
mmio_clrsetbits_32
(
PHY_REG
(
ch
,
2
+
128
*
i
),
0x3ff
,
rddqs_gate_delay
);
mmio_clrsetbits_32
(
PHY_REG
(
ch
,
78
+
128
*
i
),
0xf
,
rddqs_latency
);
}
for
(
i
=
0
;
i
<
3
;
i
++
)
/* adr delay */
mmio_clrsetbits_32
(
PHY_REG
(
ch
,
513
+
128
*
i
),
0x7ff
<<
16
,
0x80
<<
16
);
if
((
mmio_read_32
(
PHY_REG
(
ch
,
86
))
&
0xc00
)
==
0
)
{
/*
* old status is normal mode,
* and saving the wrdqs slave delay
*/
for
(
i
=
0
;
i
<
4
;
i
++
)
{
/* save and clear wr dqs slave delay */
wrdqs_delay_val
[
ch
][
index
][
i
]
=
0x3ff
&
(
mmio_read_32
(
PHY_REG
(
ch
,
63
+
i
*
128
))
>>
16
);
mmio_clrsetbits_32
(
PHY_REG
(
ch
,
63
+
i
*
128
),
0x03ff
<<
16
,
0
<<
16
);
/*
* in normal mode the cmd may delay 1cycle by
* wrlvl and in bypass mode making dqs also
* delay 1cycle.
*/
mmio_clrsetbits_32
(
PHY_REG
(
ch
,
78
+
i
*
128
),
0x07
<<
8
,
0x1
<<
8
);
}
}
}
else
if
(
mmio_read_32
(
PHY_REG
(
ch
,
86
))
&
0xc00
)
{
/* old status is bypass mode and restore wrlvl resume */
for
(
i
=
0
;
i
<
4
;
i
++
)
{
mmio_clrsetbits_32
(
PHY_REG
(
ch
,
63
+
i
*
128
),
0x03ff
<<
16
,
(
wrdqs_delay_val
[
ch
][
index
][
i
]
&
0x3ff
)
<<
16
);
/* resume phy_write_path_lat_add */
mmio_clrbits_32
(
PHY_REG
(
ch
,
78
+
i
*
128
),
0x07
<<
8
);
}
}
/* phy_sw_master_mode_X PHY_86/214/342/470 4bits offset_8 */
mmio_clrsetbits_32
(
PHY_REG
(
ch
,
86
),
0xf
<<
8
,
sw_master_mode
<<
8
);
mmio_clrsetbits_32
(
PHY_REG
(
ch
,
214
),
0xf
<<
8
,
sw_master_mode
<<
8
);
mmio_clrsetbits_32
(
PHY_REG
(
ch
,
342
),
0xf
<<
8
,
sw_master_mode
<<
8
);
mmio_clrsetbits_32
(
PHY_REG
(
ch
,
470
),
0xf
<<
8
,
sw_master_mode
<<
8
);
/* phy_adrctl_sw_master_mode PHY_547/675/803 4bits offset_16 */
mmio_clrsetbits_32
(
PHY_REG
(
ch
,
547
),
0xf
<<
16
,
sw_master_mode
<<
16
);
mmio_clrsetbits_32
(
PHY_REG
(
ch
,
675
),
0xf
<<
16
,
sw_master_mode
<<
16
);
mmio_clrsetbits_32
(
PHY_REG
(
ch
,
803
),
0xf
<<
16
,
sw_master_mode
<<
16
);
}
static
void
gen_rk3399_phy_params
(
struct
timing_related_config
*
timing_config
,
...
...
@@ -1745,15 +1557,7 @@ static void gen_rk3399_phy_params(struct timing_related_config *timing_config,
/* DENALI_PHY_911 13bits offset_0 */
/* PHY_LP4_BOOT_PLL_CTRL */
/* DENALI_PHY_919 13bits offset_0 */
if
(
pdram_timing
->
mhz
<=
150
)
tmp
=
3
;
else
if
(
pdram_timing
->
mhz
<=
300
)
tmp
=
2
;
else
if
(
pdram_timing
->
mhz
<=
600
)
tmp
=
1
;
else
tmp
=
0
;
tmp
=
(
1
<<
12
)
|
(
tmp
<<
9
)
|
(
2
<<
7
)
|
(
1
<<
1
);
tmp
=
(
1
<<
12
)
|
(
2
<<
7
)
|
(
1
<<
1
);
mmio_clrsetbits_32
(
PHY_REG
(
i
,
911
),
0x1fff
,
tmp
);
mmio_clrsetbits_32
(
PHY_REG
(
i
,
919
),
0x1fff
,
tmp
);
...
...
@@ -1761,15 +1565,7 @@ static void gen_rk3399_phy_params(struct timing_related_config *timing_config,
/* DENALI_PHY_911 13bits offset_16 */
/* PHY_LP4_BOOT_PLL_CTRL_CA */
/* DENALI_PHY_919 13bits offset_16 */
if
(
pdram_timing
->
mhz
<=
150
)
tmp
=
3
;
else
if
(
pdram_timing
->
mhz
<=
300
)
tmp
=
2
;
else
if
(
pdram_timing
->
mhz
<=
600
)
tmp
=
1
;
else
tmp
=
0
;
tmp
=
(
tmp
<<
9
)
|
(
2
<<
7
)
|
(
1
<<
5
)
|
(
1
<<
1
);
tmp
=
(
2
<<
7
)
|
(
1
<<
5
)
|
(
1
<<
1
);
mmio_clrsetbits_32
(
PHY_REG
(
i
,
911
),
0x1fff
<<
16
,
tmp
<<
16
);
mmio_clrsetbits_32
(
PHY_REG
(
i
,
919
),
0x1fff
<<
16
,
tmp
<<
16
);
...
...
@@ -1791,7 +1587,6 @@ static void gen_rk3399_phy_params(struct timing_related_config *timing_config,
break
;
}
mmio_clrsetbits_32
(
PHY_REG
(
i
,
947
),
0x7
<<
8
,
tmp
<<
8
);
mmio_setbits_32
(
PHY_REG
(
i
,
927
),
(
1
<<
22
));
if
(
timing_config
->
dram_type
==
DDR3
)
{
mem_delay_ps
=
0
;
...
...
@@ -1812,12 +1607,6 @@ static void gen_rk3399_phy_params(struct timing_related_config *timing_config,
gate_delay_ps
=
delay_frac_ps
+
1000
-
(
trpre_min_ps
/
2
);
gate_delay_frac_ps
=
gate_delay_ps
%
1000
;
tmp
=
gate_delay_frac_ps
*
0x200
/
1000
;
/* PHY_RDDQS_GATE_BYPASS_SLAVE_DELAY */
/* DENALI_PHY_2/130/258/386 10bits offset_0 */
mmio_clrsetbits_32
(
PHY_REG
(
i
,
2
),
0x2ff
,
tmp
);
mmio_clrsetbits_32
(
PHY_REG
(
i
,
130
),
0x2ff
,
tmp
);
mmio_clrsetbits_32
(
PHY_REG
(
i
,
258
),
0x2ff
,
tmp
);
mmio_clrsetbits_32
(
PHY_REG
(
i
,
386
),
0x2ff
,
tmp
);
/* PHY_RDDQS_GATE_SLAVE_DELAY */
/* DENALI_PHY_77/205/333/461 10bits offset_16 */
mmio_clrsetbits_32
(
PHY_REG
(
i
,
77
),
0x2ff
<<
16
,
tmp
<<
16
);
...
...
@@ -1832,12 +1621,6 @@ static void gen_rk3399_phy_params(struct timing_related_config *timing_config,
mmio_clrsetbits_32
(
PHY_REG
(
i
,
138
),
0xf
,
tmp
);
mmio_clrsetbits_32
(
PHY_REG
(
i
,
266
),
0xf
,
tmp
);
mmio_clrsetbits_32
(
PHY_REG
(
i
,
394
),
0xf
,
tmp
);
/* PHY_RDDQS_LATENCY_ADJUST */
/* DENALI_PHY_78/206/334/462 4bits offset_0 */
mmio_clrsetbits_32
(
PHY_REG
(
i
,
78
),
0xf
,
tmp
);
mmio_clrsetbits_32
(
PHY_REG
(
i
,
206
),
0xf
,
tmp
);
mmio_clrsetbits_32
(
PHY_REG
(
i
,
334
),
0xf
,
tmp
);
mmio_clrsetbits_32
(
PHY_REG
(
i
,
462
),
0xf
,
tmp
);
/* PHY_GTLVL_LAT_ADJ_START */
/* DENALI_PHY_80/208/336/464 4bits offset_16 */
tmp
=
delay_frac_ps
/
1000
;
...
...
@@ -1922,6 +1705,8 @@ static void gen_rk3399_phy_params(struct timing_related_config *timing_config,
mmio_setbits_32
(
PHY_REG
(
i
,
340
),
0x1
<<
16
);
mmio_setbits_32
(
PHY_REG
(
i
,
468
),
0x1
<<
16
);
}
gen_rk3399_phy_dll_bypass
(
pdram_timing
->
mhz
,
i
,
fn
,
timing_config
->
dram_type
);
}
}
...
...
@@ -1944,22 +1729,6 @@ static int to_get_clk_index(unsigned int mhz)
return
i
;
}
uint32_t
rkclk_prepare_pll_timing
(
unsigned
int
mhz
)
{
unsigned
int
refdiv
,
postdiv1
,
fbdiv
,
postdiv2
;
int
index
;
index
=
to_get_clk_index
(
mhz
);
refdiv
=
dpll_rates_table
[
index
].
refdiv
;
fbdiv
=
dpll_rates_table
[
index
].
fbdiv
;
postdiv1
=
dpll_rates_table
[
index
].
postdiv1
;
postdiv2
=
dpll_rates_table
[
index
].
postdiv2
;
mmio_write_32
(
DCF_PARAM_ADDR
+
PARAM_DPLL_CON0
,
FBDIV
(
fbdiv
));
mmio_write_32
(
DCF_PARAM_ADDR
+
PARAM_DPLL_CON1
,
POSTDIV2
(
postdiv2
)
|
POSTDIV1
(
postdiv1
)
|
REFDIV
(
refdiv
));
return
(
24
*
fbdiv
)
/
refdiv
/
postdiv1
/
postdiv2
;
}
uint32_t
ddr_get_rate
(
void
)
{
uint32_t
refdiv
,
postdiv1
,
fbdiv
,
postdiv2
;
...
...
@@ -2051,90 +1820,21 @@ void resume_low_power(uint32_t low_power)
}
}
static
void
wait_dcf_done
(
void
)
{
while
((
mmio_read_32
(
DCF_BASE
+
DCF_DCF_ISR
)
&
(
DCF_DONE
))
==
0
)
continue
;
}
void
clr_dcf_irq
(
void
)
{
/* clear dcf irq status */
mmio_write_32
(
DCF_BASE
+
DCF_DCF_ISR
,
DCF_TIMEOUT
|
DCF_ERR
|
DCF_DONE
);
}
static
void
enable_dcf
(
uint32_t
dcf_addr
)
static
void
dram_low_power_config
(
void
)
{
/* config DCF start addr */
mmio_write_32
(
DCF_BASE
+
DCF_DCF_ADDR
,
dcf_addr
);
/* wait dcf done */
while
(
mmio_read_32
(
DCF_BASE
+
DCF_DCF_CTRL
)
&
1
)
continue
;
/* clear dcf irq status */
mmio_write_32
(
DCF_BASE
+
DCF_DCF_ISR
,
DCF_TIMEOUT
|
DCF_ERR
|
DCF_DONE
);
/* DCF start */
mmio_setbits_32
(
DCF_BASE
+
DCF_DCF_CTRL
,
DCF_START
);
}
void
dcf_code_init
(
void
)
{
memcpy
((
void
*
)
DCF_START_ADDR
,
(
void
*
)
dcf_code
,
sizeof
(
dcf_code
));
/* set dcf master secure */
mmio_write_32
(
SGRF_BASE
+
0xe01c
,
((
0x3
<<
0
)
<<
16
)
|
(
0
<<
0
));
mmio_write_32
(
DCF_BASE
+
DCF_DCF_TOSET
,
0x80000000
);
}
static
void
dcf_start
(
uint32_t
freq
,
uint32_t
index
)
{
mmio_write_32
(
CRU_BASE
+
CRU_SOFTRST_CON
(
10
),
(
0x1
<<
(
1
+
16
))
|
(
1
<<
1
));
mmio_write_32
(
CRU_BASE
+
CRU_SOFTRST_CON
(
11
),
(
0x1
<<
(
0
+
16
))
|
(
1
<<
0
));
mmio_write_32
(
DCF_PARAM_ADDR
+
PARAM_FREQ_SELECT
,
index
<<
4
);
mmio_write_32
(
DCF_PARAM_ADDR
+
PARAM_DRAM_FREQ
,
freq
);
rkclk_prepare_pll_timing
(
freq
);
udelay
(
10
);
mmio_write_32
(
CRU_BASE
+
CRU_SOFTRST_CON
(
10
),
(
0x1
<<
(
1
+
16
))
|
(
0
<<
1
));
mmio_write_32
(
CRU_BASE
+
CRU_SOFTRST_CON
(
11
),
(
0x1
<<
(
0
+
16
))
|
(
0
<<
0
));
udelay
(
10
);
enable_dcf
(
DCF_START_ADDR
);
}
static
void
dram_low_power_config
(
struct
drv_odt_lp_config
*
lp_config
)
{
uint32_t
tmp
,
tmp1
,
i
;
uint32_t
tmp
,
i
;
uint32_t
ch_cnt
=
rk3399_dram_status
.
timing_config
.
ch_cnt
;
uint32_t
dram_type
=
rk3399_dram_status
.
timing_config
.
dram_type
;
uint32_t
*
low_power
=
&
rk3399_dram_status
.
low_power_stat
;
if
(
dram_type
==
LPDDR4
)
tmp
=
(
lp_config
->
srpd_lite_idle
<<
16
)
|
lp_config
->
pd_idle
;
else
tmp
=
lp_config
->
pd_idle
;
if
(
dram_type
==
DDR3
)
tmp
1
=
(
2
<<
16
)
|
(
0x7
<<
8
)
|
7
;
tmp
=
(
2
<<
16
)
|
(
0x7
<<
8
);
else
tmp
1
=
(
3
<<
16
)
|
(
0x7
<<
8
)
|
7
;
tmp
=
(
3
<<
16
)
|
(
0x7
<<
8
);
*
low_power
=
0
;
for
(
i
=
0
;
i
<
ch_cnt
;
i
++
)
{
mmio_write_32
(
CTL_REG
(
i
,
102
),
tmp
);
mmio_clrsetbits_32
(
CTL_REG
(
i
,
103
),
0xffff
,
(
lp_config
->
sr_mc_gate_idle
<<
8
)
|
lp_config
->
sr_idle
);
mmio_clrsetbits_32
(
CTL_REG
(
i
,
101
),
0x70f0f
,
tmp1
);
*
low_power
|=
(
7
<<
(
8
*
i
));
}
for
(
i
=
0
;
i
<
ch_cnt
;
i
++
)
mmio_clrsetbits_32
(
CTL_REG
(
i
,
101
),
0x70f0f
,
tmp
);
/* standby idle */
mmio_write_32
(
CIC_BASE
+
CIC_IDLE_TH
,
lp_config
->
standby_idle
);
mmio_write_32
(
CIC_BASE
+
CIC_CG_WAIT_TH
,
0x640008
);
if
(
ch_cnt
==
2
)
{
...
...
@@ -2142,35 +1842,21 @@ static void dram_low_power_config(struct drv_odt_lp_config *lp_config)
(((
0x1
<<
4
)
|
(
0x1
<<
5
)
|
(
0x1
<<
6
)
|
(
0x1
<<
7
))
<<
16
)
|
((
0x1
<<
4
)
|
(
0x0
<<
5
)
|
(
0x1
<<
6
)
|
(
0x1
<<
7
)));
if
(
lp_config
->
standby_idle
)
{
tmp
=
0x002a002a
;
*
low_power
|=
(
1
<<
11
);
}
else
tmp
=
0
;
mmio_write_32
(
CIC_BASE
+
CIC_CTRL1
,
tmp
);
mmio_write_32
(
CIC_BASE
+
CIC_CTRL1
,
0x002a0028
);
}
mmio_write_32
(
GRF_BASE
+
GRF_DDRC0_CON1
,
(((
0x1
<<
4
)
|
(
0x1
<<
5
)
|
(
0x1
<<
6
)
|
(
0x1
<<
7
))
<<
16
)
|
((
0x1
<<
4
)
|
(
0x0
<<
5
)
|
(
0x1
<<
6
)
|
(
0x1
<<
7
)));
if
(
lp_config
->
standby_idle
)
{
tmp
=
0x00150015
;
*
low_power
|=
(
1
<<
3
);
}
else
tmp
=
0
;
mmio_write_32
(
CIC_BASE
+
CIC_CTRL1
,
tmp
);
mmio_write_32
(
CIC_BASE
+
CIC_CTRL1
,
0x00150014
);
}
static
void
dram_related_init
(
struct
ddr_dts_config_timing
*
dts_timing
)
void
dram_dfs_init
(
void
)
{
uint32_t
trefi0
,
trefi1
;
uint32_t
i
;
dcf_code_init
();
uint32_t
trefi0
,
trefi1
,
boot_freq
;
/* get sdram config for os reg */
drv_odt_lp_cfg_init
(
sdram_config
.
dramtype
,
dts_timing
,
get_dram_drv_odt_val
(
sdram_config
.
dramtype
,
&
rk3399_dram_status
.
drv_odt_lp_cfg
);
sdram_timing_cfg_init
(
&
rk3399_dram_status
.
timing_config
,
&
sdram_config
,
...
...
@@ -2187,30 +1873,106 @@ static void dram_related_init(struct ddr_dts_config_timing *dts_timing)
rk3399_dram_status
.
index_freq
[
0
]
/=
2
;
rk3399_dram_status
.
index_freq
[
1
]
/=
2
;
}
rk3399_dram_status
.
index_freq
[(
rk3399_dram_status
.
current_index
+
1
)
&
0x1
]
=
0
;
boot_freq
=
rk3399_dram_status
.
index_freq
[
rk3399_dram_status
.
current_index
];
boot_freq
=
dpll_rates_table
[
to_get_clk_index
(
boot_freq
)].
mhz
;
rk3399_dram_status
.
boot_freq
=
boot_freq
;
rk3399_dram_status
.
index_freq
[
rk3399_dram_status
.
current_index
]
=
boot_freq
;
rk3399_dram_status
.
index_freq
[(
rk3399_dram_status
.
current_index
+
1
)
&
0x1
]
=
0
;
rk3399_dram_status
.
low_power_stat
=
0
;
/*
* following register decide if NOC stall the access request
* or return error when NOC being idled. when doing ddr frequency
* scaling in M0 or DCF, we need to make sure noc stall the access
* request, if return error cpu may data abort when ddr frequency
* changing. it don't need to set this register every times,
* so we init this register in function dram_dfs_init().
*/
mmio_write_32
(
GRF_BASE
+
GRF_SOC_CON
(
0
),
0xffffffff
);
mmio_write_32
(
GRF_BASE
+
GRF_SOC_CON
(
1
),
0xffffffff
);
mmio_write_32
(
GRF_BASE
+
GRF_SOC_CON
(
2
),
0xffffffff
);
mmio_write_32
(
GRF_BASE
+
GRF_SOC_CON
(
3
),
0xffffffff
);
mmio_write_32
(
GRF_BASE
+
GRF_SOC_CON
(
4
),
0x70007000
);
/* disable all training by ctl and pi */
for
(
i
=
0
;
i
<
rk3399_dram_status
.
timing_config
.
ch_cnt
;
i
++
)
{
mmio_clrbits_32
(
CTL_REG
(
i
,
70
),
(
1
<<
24
)
|
(
1
<<
16
)
|
(
1
<<
8
)
|
1
);
mmio_clrbits_32
(
CTL_REG
(
i
,
71
),
1
);
/* Disable multicast */
mmio_clrbits_32
(
PHY_REG
(
0
,
896
),
1
);
mmio_clrbits_32
(
PHY_REG
(
1
,
896
),
1
);
mmio_clrbits_32
(
PI_REG
(
i
,
60
),
0x3
<<
8
);
mmio_clrbits_32
(
PI_REG
(
i
,
80
),
(
0x3
<<
24
)
|
(
0x3
<<
16
));
mmio_clrbits_32
(
PI_REG
(
i
,
100
),
0x3
<<
8
);
mmio_clrbits_32
(
PI_REG
(
i
,
124
),
0x3
<<
16
);
}
dram_low_power_config
();
}
/*
* arg0: bit0-7: sr_idle; bit8-15:sr_mc_gate_idle; bit16-31: standby idle
* arg1: bit0-11: pd_idle; bit 16-27: srpd_lite_idle
* arg2: bit0: if odt en
*/
uint32_t
dram_set_odt_pd
(
uint32_t
arg0
,
uint32_t
arg1
,
uint32_t
arg2
)
{
struct
drv_odt_lp_config
*
lp_cfg
=
&
rk3399_dram_status
.
drv_odt_lp_cfg
;
uint32_t
*
low_power
=
&
rk3399_dram_status
.
low_power_stat
;
uint32_t
dram_type
,
ch_count
,
pd_tmp
,
sr_tmp
,
i
;
dram_type
=
rk3399_dram_status
.
timing_config
.
dram_type
;
ch_count
=
rk3399_dram_status
.
timing_config
.
ch_cnt
;
lp_cfg
->
sr_idle
=
arg0
&
0xff
;
lp_cfg
->
sr_mc_gate_idle
=
(
arg0
>>
8
)
&
0xff
;
lp_cfg
->
standby_idle
=
(
arg0
>>
16
)
&
0xffff
;
lp_cfg
->
pd_idle
=
arg1
&
0xfff
;
lp_cfg
->
srpd_lite_idle
=
(
arg1
>>
16
)
&
0xfff
;
rk3399_dram_status
.
timing_config
.
odt
=
arg2
&
0x1
;
exit_low_power
();
/* init drv odt */
if
(
rk3399_dram_status
.
index_freq
[
rk3399_dram_status
.
current_index
]
<
rk3399_dram_status
.
drv_odt_lp_cfg
.
odt_dis_freq
)
rk3399_dram_status
.
timing_config
.
odt
=
0
;
*
low_power
=
0
;
/* pd_idle en */
if
(
lp_cfg
->
pd_idle
)
*
low_power
|=
((
1
<<
0
)
|
(
1
<<
8
));
/* sr_idle en srpd_lite_idle */
if
(
lp_cfg
->
sr_idle
|
lp_cfg
->
srpd_lite_idle
)
*
low_power
|=
((
1
<<
1
)
|
(
1
<<
9
));
/* sr_mc_gate_idle */
if
(
lp_cfg
->
sr_mc_gate_idle
)
*
low_power
|=
((
1
<<
2
)
|
(
1
<<
10
));
/* standbyidle */
if
(
lp_cfg
->
standby_idle
)
{
if
(
rk3399_dram_status
.
timing_config
.
ch_cnt
==
2
)
*
low_power
|=
((
1
<<
3
)
|
(
1
<<
11
));
else
rk3399_dram_status
.
timing_config
.
odt
=
1
;
gen_rk3399_set_ds_odt
(
&
rk3399_dram_status
.
timing_config
,
&
rk3399_dram_status
.
drv_odt_lp_cfg
);
dram_low_power_config
(
&
rk3399_dram_status
.
drv_odt_lp_cfg
);
*
low_power
|=
(
1
<<
3
);
}
pd_tmp
=
arg1
;
if
(
dram_type
!=
LPDDR4
)
pd_tmp
=
arg1
&
0xfff
;
sr_tmp
=
arg0
&
0xffff
;
for
(
i
=
0
;
i
<
ch_count
;
i
++
)
{
mmio_write_32
(
CTL_REG
(
i
,
102
),
pd_tmp
);
mmio_clrsetbits_32
(
CTL_REG
(
i
,
103
),
0xffff
,
sr_tmp
);
}
mmio_write_32
(
CIC_BASE
+
CIC_IDLE_TH
,
(
arg0
>>
16
)
&
0xffff
);
return
0
;
}
static
void
m0_configure_ddr
(
struct
pll_div
pll_div
,
uint32_t
ddr_index
)
{
/* set PARAM to M0_FUNC_DRAM */
mmio_write_32
(
M0_PARAM_ADDR
+
PARAM_M0_FUNC
,
M0_FUNC_DRAM
);
mmio_write_32
(
M0_PARAM_ADDR
+
PARAM_DPLL_CON0
,
FBDIV
(
pll_div
.
fbdiv
));
mmio_write_32
(
M0_PARAM_ADDR
+
PARAM_DPLL_CON1
,
POSTDIV2
(
pll_div
.
postdiv2
)
|
POSTDIV1
(
pll_div
.
postdiv1
)
|
REFDIV
(
pll_div
.
refdiv
));
mmio_write_32
(
M0_PARAM_ADDR
+
PARAM_DRAM_FREQ
,
pll_div
.
mhz
);
mmio_write_32
(
M0_PARAM_ADDR
+
PARAM_FREQ_SELECT
,
ddr_index
<<
4
);
dmbst
();
}
static
uint32_t
prepare_ddr_timing
(
uint32_t
mhz
)
...
...
@@ -2220,20 +1982,15 @@ static uint32_t prepare_ddr_timing(uint32_t mhz)
rk3399_dram_status
.
timing_config
.
freq
=
mhz
;
if
(
mhz
<
rk3399_dram_status
.
drv_odt_lp_cfg
.
ddr3_dll_dis_freq
)
if
(
mhz
<
300
)
rk3399_dram_status
.
timing_config
.
dllbp
=
1
;
else
rk3399_dram_status
.
timing_config
.
dllbp
=
0
;
if
(
mhz
<
rk3399_dram_status
.
drv_odt_lp_cfg
.
odt_dis_freq
)
{
rk3399_dram_status
.
timing_config
.
odt
=
0
;
}
else
{
rk3399_dram_status
.
timing_config
.
odt
=
1
;
if
(
rk3399_dram_status
.
timing_config
.
odt
==
1
)
gen_rk3399_set_odt
(
1
);
}
index
=
(
rk3399_dram_status
.
current_index
+
1
)
&
0x1
;
if
(
rk3399_dram_status
.
index_freq
[
index
]
==
mhz
)
goto
out
;
/*
* checking if having available gate traiing timing for
...
...
@@ -2249,8 +2006,6 @@ static uint32_t prepare_ddr_timing(uint32_t mhz)
&
dram_timing
,
index
);
rk3399_dram_status
.
index_freq
[
index
]
=
mhz
;
out:
return
index
;
}
...
...
@@ -2271,33 +2026,39 @@ void print_dram_status_info(void)
uint32_t
ddr_set_rate
(
uint32_t
hz
)
{
uint32_t
low_power
,
index
;
uint32_t
low_power
,
index
,
ddr_
index
;
uint32_t
mhz
=
hz
/
(
1000
*
1000
);
if
(
mhz
==
rk3399_dram_status
.
index_freq
[
rk3399_dram_status
.
current_index
])
goto
out
;
return
mhz
;
index
=
to_get_clk_index
(
mhz
);
mhz
=
dpll_rates_table
[
index
].
mhz
;
low_power
=
exit_low_power
();
index
=
prepare_ddr_timing
(
mhz
);
if
(
index
>
1
)
ddr_index
=
prepare_ddr_timing
(
mhz
);
gen_rk3399_enable_training
(
rk3399_dram_status
.
timing_config
.
ch_cnt
,
mhz
);
if
(
ddr_index
>
1
)
goto
out
;
dcf_start
(
mhz
,
index
);
wait_dcf_done
();
/*
* Make sure the clock is enabled. The M0 clocks should be on all of the
* time during S0.
*/
m0_configure_ddr
(
dpll_rates_table
[
index
],
ddr_index
);
m0_start
();
m0_wait_done
();
m0_stop
();
if
(
rk3399_dram_status
.
timing_config
.
odt
==
0
)
gen_rk3399_set_odt
(
0
);
rk3399_dram_status
.
current_index
=
index
;
if
(
mhz
<
dts_parameter
.
auto_pd_dis_freq
)
low_power
|=
rk3399_dram_status
.
low_power_stat
;
rk3399_dram_status
.
current_index
=
ddr_index
;
low_power
=
rk3399_dram_status
.
low_power_stat
;
resume_low_power
(
low_power
);
out:
gen_rk3399_disable_training
(
rk3399_dram_status
.
timing_config
.
ch_cnt
);
return
mhz
;
}
...
...
@@ -2311,29 +2072,56 @@ uint32_t ddr_round_rate(uint32_t hz)
return
dpll_rates_table
[
index
].
mhz
*
1000
*
1000
;
}
uint32_t
dts_timing_receive
(
uint32_t
timing
,
uint32_t
index
)
void
ddr_prepare_for_sys_suspend
(
void
)
{
uint32_t
*
p
=
(
uint32_t
*
)
&
dts_parameter
;
static
uint32_t
receive_nums
;
uint32_t
mhz
=
rk3399_dram_status
.
index_freq
[
rk3399_dram_status
.
current_index
]
;
if
(
index
<
(
sizeof
(
dts_parameter
)
/
sizeof
(
uint32_t
)
-
1
))
{
p
[
index
]
=
(
uint32_t
)
timing
;
receive_nums
++
;
}
else
{
dts_parameter
.
available
=
0
;
return
-
1
;
}
/* receive all parameter */
if
(
receive_nums
==
(
sizeof
(
dts_parameter
)
/
sizeof
(
uint32_t
)
-
1
))
{
dts_parameter
.
available
=
1
;
receive_nums
=
0
;
}
/*
* If we're not currently at the boot (assumed highest) frequency, we
* need to change frequencies to configure out current index.
*/
rk3399_suspend_status
.
freq
=
mhz
;
exit_low_power
()
;
rk3399_suspend_status
.
low_power_stat
=
rk3399_dram_status
.
low_power_stat
;
rk3399_suspend_status
.
odt
=
rk3399_dram_status
.
timing_config
.
odt
;
rk3399_dram_status
.
low_power_stat
=
0
;
rk3399_dram_status
.
timing_config
.
odt
=
1
;
if
(
mhz
!=
rk3399_dram_status
.
boot_freq
)
ddr_set_rate
(
rk3399_dram_status
.
boot_freq
*
1000
*
1000
);
return
index
;
/*
* This will configure the other index to be the same frequency as the
* current one. We retrain both indices on resume, so both have to be
* setup for the same frequency.
*/
prepare_ddr_timing
(
rk3399_dram_status
.
boot_freq
);
}
void
ddr_
dfs_init
(
void
)
void
ddr_
prepare_for_sys_resume
(
void
)
{
dram_related_init
(
&
dts_parameter
);
/* Disable multicast */
mmio_clrbits_32
(
PHY_REG
(
0
,
896
),
1
);
mmio_clrbits_32
(
PHY_REG
(
1
,
896
),
1
);
/* The suspend code changes the current index, so reset it now. */
rk3399_dram_status
.
current_index
=
(
mmio_read_32
(
CTL_REG
(
0
,
111
))
>>
16
)
&
0x3
;
rk3399_dram_status
.
low_power_stat
=
rk3399_suspend_status
.
low_power_stat
;
rk3399_dram_status
.
timing_config
.
odt
=
rk3399_suspend_status
.
odt
;
/*
* Set the saved frequency from suspend if it's different than the
* current frequency.
*/
if
(
rk3399_suspend_status
.
freq
!=
rk3399_dram_status
.
index_freq
[
rk3399_dram_status
.
current_index
])
{
ddr_set_rate
(
rk3399_suspend_status
.
freq
*
1000
*
1000
);
return
;
}
gen_rk3399_set_odt
(
rk3399_dram_status
.
timing_config
.
odt
);
resume_low_power
(
rk3399_dram_status
.
low_power_stat
);
}
plat/rockchip/rk3399/drivers/dram/dfs.h
View file @
d6845d3d
...
...
@@ -48,65 +48,25 @@ struct rk3399_sdram_default_config {
unsigned
char
zqcsi
;
};
struct
ddr_dts_config_timing
{
unsigned
int
ddr3_speed_bin
;
unsigned
int
pd_idle
;
unsigned
int
sr_idle
;
unsigned
int
sr_mc_gate_idle
;
unsigned
int
srpd_lite_idle
;
unsigned
int
standby_idle
;
unsigned
int
auto_pd_dis_freq
;
unsigned
int
ddr3_dll_dis_freq
;
unsigned
int
phy_dll_dis_freq
;
unsigned
int
ddr3_odt_dis_freq
;
unsigned
int
ddr3_drv
;
unsigned
int
ddr3_odt
;
unsigned
int
phy_ddr3_ca_drv
;
unsigned
int
phy_ddr3_dq_drv
;
unsigned
int
phy_ddr3_odt
;
unsigned
int
lpddr3_odt_dis_freq
;
unsigned
int
lpddr3_drv
;
unsigned
int
lpddr3_odt
;
unsigned
int
phy_lpddr3_ca_drv
;
unsigned
int
phy_lpddr3_dq_drv
;
unsigned
int
phy_lpddr3_odt
;
unsigned
int
lpddr4_odt_dis_freq
;
unsigned
int
lpddr4_drv
;
unsigned
int
lpddr4_dq_odt
;
unsigned
int
lpddr4_ca_odt
;
unsigned
int
phy_lpddr4_ca_drv
;
unsigned
int
phy_lpddr4_ck_cs_drv
;
unsigned
int
phy_lpddr4_dq_drv
;
unsigned
int
phy_lpddr4_odt
;
uint32_t
available
;
};
struct
drv_odt_lp_config
{
uint32_t
ddr3_speed_bin
;
uint32_t
pd_idle
;
uint32_t
sr_idle
;
uint32_t
sr_mc_gate_idle
;
uint32_t
srpd_lite_idle
;
uint32_t
standby_idle
;
uint32_t
ddr3_dll_dis_freq
;
/* for ddr3 only */
uint32_t
phy_dll_dis_freq
;
uint32_t
odt_dis_freq
;
uint32_t
odt_en
;
uint32_t
dram_side_drv
;
uint32_t
dram_side_dq_odt
;
uint32_t
dram_side_ca_odt
;
uint32_t
phy_side_ca_drv
;
uint32_t
phy_side_ck_cs_drv
;
uint32_t
phy_side_dq_drv
;
uint32_t
phy_side_odt
;
};
void
ddr_dfs_init
(
void
);
uint32_t
ddr_set_rate
(
uint32_t
hz
);
uint32_t
ddr_round_rate
(
uint32_t
hz
);
uint32_t
ddr_get_rate
(
void
);
void
clr_dcf_irq
(
void
);
uint32_t
dts_timing_receive
(
uint32_t
timing
,
uint32_t
index
);
uint32_t
dram_set_odt_pd
(
uint32_t
arg0
,
uint32_t
arg1
,
uint32_t
arg2
);
void
dram_dfs_init
(
void
);
void
ddr_prepare_for_sys_suspend
(
void
);
void
ddr_prepare_for_sys_resume
(
void
);
#endif
plat/rockchip/rk3399/drivers/dram/dram.c
View file @
d6845d3d
...
...
@@ -30,6 +30,7 @@
#include <dram.h>
#include <plat_private.h>
#include <secure.h>
#include <soc.h>
#include <rk3399_def.h>
...
...
plat/rockchip/rk3399/drivers/dram/dram.h
View file @
d6845d3d
...
...
@@ -30,111 +30,11 @@
#ifndef __SOC_ROCKCHIP_RK3399_DRAM_H__
#define __SOC_ROCKCHIP_RK3399_DRAM_H__
#include <dram_regs.h>
#include <plat_private.h>
#include <stdint.h>
#define CTL_BASE(ch) (0xffa80000 + (ch) * 0x8000)
#define CTL_REG(ch, n) (CTL_BASE(ch) + (n) * 0x4)
#define PI_OFFSET 0x800
#define PI_BASE(ch) (CTL_BASE(ch) + PI_OFFSET)
#define PI_REG(ch, n) (PI_BASE(ch) + (n) * 0x4)
#define PHY_OFFSET 0x2000
#define PHY_BASE(ch) (CTL_BASE(ch) + PHY_OFFSET)
#define PHY_REG(ch, n) (PHY_BASE(ch) + (n) * 0x4)
#define MSCH_BASE(ch) (0xffa84000 + (ch) * 0x8000)
#define MSCH_ID_COREID 0x0
#define MSCH_ID_REVISIONID 0x4
#define MSCH_DEVICECONF 0x8
#define MSCH_DEVICESIZE 0xc
#define MSCH_DDRTIMINGA0 0x10
#define MSCH_DDRTIMINGB0 0x14
#define MSCH_DDRTIMINGC0 0x18
#define MSCH_DEVTODEV0 0x1c
#define MSCH_DDRMODE 0x110
#define MSCH_AGINGX0 0x1000
#define CIC_CTRL0 0x0
#define CIC_CTRL1 0x4
#define CIC_IDLE_TH 0x8
#define CIC_CG_WAIT_TH 0xc
#define CIC_STATUS0 0x10
#define CIC_STATUS1 0x14
#define CIC_CTRL2 0x18
#define CIC_CTRL3 0x1c
#define CIC_CTRL4 0x20
/* DENALI_CTL_00 */
#define START 1
/* DENALI_CTL_68 */
#define PWRUP_SREFRESH_EXIT (1 << 16)
/* DENALI_CTL_274 */
#define MEM_RST_VALID 1
#define PHY_DRV_ODT_Hi_Z 0x0
#define PHY_DRV_ODT_240 0x1
#define PHY_DRV_ODT_120 0x8
#define PHY_DRV_ODT_80 0x9
#define PHY_DRV_ODT_60 0xc
#define PHY_DRV_ODT_48 0xd
#define PHY_DRV_ODT_40 0xe
#define PHY_DRV_ODT_34_3 0xf
/*
* sys_reg bitfield struct
* [31] row_3_4_ch1
* [30] row_3_4_ch0
* [29:28] chinfo
* [27] rank_ch1
* [26:25] col_ch1
* [24] bk_ch1
* [23:22] cs0_row_ch1
* [21:20] cs1_row_ch1
* [19:18] bw_ch1
* [17:16] dbw_ch1;
* [15:13] ddrtype
* [12] channelnum
* [11] rank_ch0
* [10:9] col_ch0
* [8] bk_ch0
* [7:6] cs0_row_ch0
* [5:4] cs1_row_ch0
* [3:2] bw_ch0
* [1:0] dbw_ch0
*/
#define SYS_REG_ENC_ROW_3_4(n, ch) ((n) << (30 + (ch)))
#define SYS_REG_DEC_ROW_3_4(n, ch) (((n) >> (30 + (ch))) & 0x1)
#define SYS_REG_ENC_CHINFO(ch) (1 << (28 + (ch)))
#define SYS_REG_DEC_CHINFO(n, ch) (((n) >> (28 + (ch))) & 0x1)
#define SYS_REG_ENC_DDRTYPE(n) ((n) << 13)
#define SYS_REG_DEC_DDRTYPE(n) (((n) >> 13) & 0x7)
#define SYS_REG_ENC_NUM_CH(n) (((n) - 1) << 12)
#define SYS_REG_DEC_NUM_CH(n) (1 + (((n) >> 12) & 0x1))
#define SYS_REG_ENC_RANK(n, ch) (((n) - 1) << (11 + (ch) * 16))
#define SYS_REG_DEC_RANK(n, ch) (1 + (((n) >> (11 + (ch) * 16)) & 0x1))
#define SYS_REG_ENC_COL(n, ch) (((n) - 9) << (9 + (ch) * 16))
#define SYS_REG_DEC_COL(n, ch) (9 + (((n) >> (9 + (ch) * 16)) & 0x3))
#define SYS_REG_ENC_BK(n, ch) (((n) == 3 ? 0 : 1) << (8 + (ch) * 16))
#define SYS_REG_DEC_BK(n, ch) (3 - (((n) >> (8 + (ch) * 16)) & 0x1))
#define SYS_REG_ENC_CS0_ROW(n, ch) (((n) - 13) << (6 + (ch) * 16))
#define SYS_REG_DEC_CS0_ROW(n, ch) (13 + (((n) >> (6 + (ch) * 16)) & 0x3))
#define SYS_REG_ENC_CS1_ROW(n, ch) (((n) - 13) << (4 + (ch) * 16))
#define SYS_REG_DEC_CS1_ROW(n, ch) (13 + (((n) >> (4 + (ch) * 16)) & 0x3))
#define SYS_REG_ENC_BW(n, ch) ((2 >> (n)) << (2 + (ch) * 16))
#define SYS_REG_DEC_BW(n, ch) (2 >> (((n) >> (2 + (ch) * 16)) & 0x3))
#define SYS_REG_ENC_DBW(n, ch) ((2 >> (n)) << (0 + (ch) * 16))
#define SYS_REG_DEC_DBW(n, ch) (2 >> (((n) >> (0 + (ch) * 16)) & 0x3))
#define DDR_STRIDE(n) mmio_write_32(SGRF_BASE + SGRF_SOC_CON3_7(4), \
(0x1f<<(10+16))|((n)<<10))
#define CTL_REG_NUM 332
#define PHY_REG_NUM 959
#define PI_REG_NUM 200
enum
{
DDR3
=
3
,
LPDDR2
=
5
,
...
...
@@ -259,6 +159,7 @@ struct rk3399_sdram_params {
struct
rk3399_ddr_pctl_regs
pctl_regs
;
struct
rk3399_ddr_pi_regs
pi_regs
;
struct
rk3399_ddr_publ_regs
phy_regs
;
uint32_t
rx_cal_dqs
[
2
][
4
];
};
extern
__sramdata
struct
rk3399_sdram_params
sdram_config
;
...
...
plat/rockchip/rk3399/drivers/dram/dram_spec_timing.c
View file @
d6845d3d
...
...
@@ -267,6 +267,7 @@ static void ddr3_get_parameter(struct timing_related_config *timing_config,
break
;
}
if
(
timing_config
->
odt
)
switch
(
timing_config
->
dramodt
)
{
case
60
:
pdram_timing
->
mr
[
1
]
=
tmp
|
DDR3_RTT_NOM_60
;
...
...
@@ -282,6 +283,8 @@ static void ddr3_get_parameter(struct timing_related_config *timing_config,
pdram_timing
->
mr
[
1
]
=
tmp
|
DDR3_RTT_NOM_DIS
;
break
;
}
else
pdram_timing
->
mr
[
1
]
=
tmp
|
DDR3_RTT_NOM_DIS
;
pdram_timing
->
mr
[
2
]
=
DDR3_MR2_CWL
(
pdram_timing
->
cwl
);
pdram_timing
->
mr
[
3
]
=
0
;
...
...
@@ -664,6 +667,9 @@ static void lpddr2_get_parameter(struct timing_related_config *timing_config,
#define LPDDR3_TADR (20)
/* ns */
#define LPDDR3_TMRZ (3)
/* ns */
/* FSP */
#define LPDDR3_TFC_LONG (250)
/* ns */
/*
* Description: depend on input parameter "timing_config",
* and calculate all lpddr3
...
...
@@ -751,6 +757,7 @@ static void lpddr3_get_parameter(struct timing_related_config *timing_config,
break
;
}
pdram_timing
->
mr
[
0
]
=
0
;
if
(
timing_config
->
odt
)
switch
(
timing_config
->
dramodt
)
{
case
60
:
pdram_timing
->
mr11
=
LPDDR3_ODT_60
;
...
...
@@ -763,6 +770,8 @@ static void lpddr3_get_parameter(struct timing_related_config *timing_config,
pdram_timing
->
mr11
=
LPDDR3_ODT_240
;
break
;
}
else
pdram_timing
->
mr11
=
LPDDR3_ODT_DIS
;
pdram_timing
->
tinit1
=
(
LPDDR3_TINIT1
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
tinit2
=
LPDDR3_TINIT2
;
...
...
@@ -874,6 +883,9 @@ static void lpddr3_get_parameter(struct timing_related_config *timing_config,
pdram_timing
->
tadr
=
(
LPDDR3_TADR
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
tmrz
=
(
LPDDR3_TMRZ
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
tcacd
=
pdram_timing
->
tadr
+
2
;
/* FSP */
pdram_timing
->
tfc_long
=
(
LPDDR3_TFC_LONG
*
nmhz
+
999
)
/
1000
;
}
#define LPDDR4_TINIT1 (200000)
/* 200us */
...
...
@@ -1113,6 +1125,7 @@ static void lpddr4_get_parameter(struct timing_related_config *timing_config,
break
;
}
pdram_timing
->
mr
[
0
]
=
0
;
if
(
timing_config
->
odt
)
{
switch
(
timing_config
->
dramodt
)
{
case
240
:
tmp
=
LPDDR4_DQODT_240
;
...
...
@@ -1134,6 +1147,7 @@ static void lpddr4_get_parameter(struct timing_related_config *timing_config,
tmp
=
LPDDR4_DQODT_40
;
break
;
}
switch
(
timing_config
->
caodt
)
{
case
240
:
pdram_timing
->
mr11
=
LPDDR4_CAODT_240
|
tmp
;
...
...
@@ -1155,6 +1169,9 @@ static void lpddr4_get_parameter(struct timing_related_config *timing_config,
pdram_timing
->
mr11
=
LPDDR4_CAODT_40
|
tmp
;
break
;
}
}
else
{
pdram_timing
->
mr11
=
LPDDR4_CAODT_DIS
|
tmp
;
}
pdram_timing
->
tinit1
=
(
LPDDR4_TINIT1
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
tinit2
=
(
LPDDR4_TINIT2
*
nmhz
+
999
)
/
1000
;
...
...
plat/rockchip/rk3399/drivers/dram/suspend.c
View file @
d6845d3d
...
...
@@ -34,6 +34,7 @@
#include <dram.h>
#include <pmu_regs.h>
#include <rk3399_def.h>
#include <secure.h>
#include <soc.h>
#include <suspend.h>
...
...
@@ -571,14 +572,15 @@ static __sramfunc void pctl_cfg(uint32_t ch,
sram_regcpy
(
PHY_REG
(
ch
,
768
),
(
uintptr_t
)
&
params_phy
[
768
],
38
);
}
static
__sramfunc
int
dram_switch_to_
phy
_index
1
(
static
__sramfunc
int
dram_switch_to_
next
_index
(
struct
rk3399_sdram_params
*
sdram_params
)
{
uint32_t
ch
,
ch_count
;
uint32_t
fn
=
((
mmio_read_32
(
CTL_REG
(
0
,
111
))
>>
16
)
+
1
)
&
0x1
;
mmio_write_32
(
CIC_BASE
+
CIC_CTRL0
,
(((
0x3
<<
4
)
|
(
1
<<
2
)
|
1
)
<<
16
)
|
(
1
<<
4
)
|
(
1
<<
2
)
|
1
);
(
fn
<<
4
)
|
(
1
<<
2
)
|
1
);
while
(
!
(
mmio_read_32
(
CIC_BASE
+
CIC_STATUS0
)
&
(
1
<<
2
)))
;
...
...
@@ -591,7 +593,7 @@ static __sramfunc int dram_switch_to_phy_index1(
/* LPDDR4 f2 cann't do training, all training will fail */
for
(
ch
=
0
;
ch
<
ch_count
;
ch
++
)
{
mmio_clrsetbits_32
(
PHY_REG
(
ch
,
896
),
(
0x3
<<
8
)
|
1
,
1
<<
8
);
fn
<<
8
);
/* data_training failed */
if
(
data_training
(
ch
,
sdram_params
,
PI_FULL_TRAINING
))
...
...
@@ -609,6 +611,7 @@ static __sramfunc int pctl_start(uint32_t channel_mask,
struct
rk3399_sdram_params
*
sdram_params
)
{
uint32_t
count
;
uint32_t
byte
;
mmio_setbits_32
(
CTL_REG
(
0
,
68
),
PWRUP_SREFRESH_EXIT
);
mmio_setbits_32
(
CTL_REG
(
1
,
68
),
PWRUP_SREFRESH_EXIT
);
...
...
@@ -640,6 +643,12 @@ static __sramfunc int pctl_start(uint32_t channel_mask,
}
mmio_clrbits_32
(
CTL_REG
(
0
,
68
),
PWRUP_SREFRESH_EXIT
);
/* Restore the PHY_RX_CAL_DQS value */
for
(
byte
=
0
;
byte
<
4
;
byte
++
)
mmio_clrsetbits_32
(
PHY_REG
(
0
,
57
+
128
*
byte
),
0xfff
<<
16
,
sdram_params
->
rx_cal_dqs
[
0
][
byte
]);
}
if
(
channel_mask
&
(
1
<<
1
))
{
count
=
0
;
...
...
@@ -653,6 +662,12 @@ static __sramfunc int pctl_start(uint32_t channel_mask,
}
mmio_clrbits_32
(
CTL_REG
(
1
,
68
),
PWRUP_SREFRESH_EXIT
);
/* Restore the PHY_RX_CAL_DQS value */
for
(
byte
=
0
;
byte
<
4
;
byte
++
)
mmio_clrsetbits_32
(
PHY_REG
(
1
,
57
+
128
*
byte
),
0xfff
<<
16
,
sdram_params
->
rx_cal_dqs
[
1
][
byte
]);
}
return
0
;
...
...
@@ -665,7 +680,7 @@ void dmc_save(void)
uint32_t
*
params_pi
;
uint32_t
*
params_phy
;
uint32_t
refdiv
,
postdiv2
,
postdiv1
,
fbdiv
;
uint32_t
tmp
;
uint32_t
tmp
,
ch
,
byte
;
params_ctl
=
sdram_params
->
pctl_regs
.
denali_ctl
;
params_pi
=
sdram_params
->
pi_regs
.
denali_pi
;
...
...
@@ -705,6 +720,12 @@ void dmc_save(void)
sram_regcpy
((
uintptr_t
)
&
params_phy
[
768
],
PHY_REG
(
0
,
768
),
38
);
sram_regcpy
((
uintptr_t
)
&
params_phy
[
896
],
PHY_REG
(
0
,
896
),
63
);
for
(
ch
=
0
;
ch
<
sdram_params
->
num_channels
;
ch
++
)
{
for
(
byte
=
0
;
byte
<
4
;
byte
++
)
sdram_params
->
rx_cal_dqs
[
ch
][
byte
]
=
(
0xfff
<<
16
)
&
mmio_read_32
(
PHY_REG
(
ch
,
57
+
byte
*
128
));
}
/* set DENALI_PHY_957_DATA.PHY_DLL_RST_EN = 0x1 */
params_phy
[
957
]
&=
~
(
0x3
<<
24
);
params_phy
[
957
]
|=
1
<<
24
;
...
...
@@ -754,5 +775,5 @@ retry:
dram_all_config
(
sdram_params
);
/* Switch to index 1 and prepare for DDR frequency switch. */
dram_switch_to_
phy
_index
1
(
sdram_params
);
dram_switch_to_
next
_index
(
sdram_params
);
}
plat/rockchip/rk3399/drivers/m0/Makefile
View file @
d6845d3d
...
...
@@ -46,32 +46,29 @@ export Q
.SUFFIXES
:
INCLUDES
+=
-Iinclude
/
INCLUDES
+=
-Iinclude
/
\
-I
../../include/shared/
# NOTE: Add C source files here
C_SOURCES
:=
src/startup.c
\
src/main.c
src/main.c
\
src/suspend.c
\
src/dram.c
\
src/stopwatch.c
# Flags definition
CFLAGS
:=
-g
ASFLAGS
:=
-g
-Wa
,--gdwarf-2
ASFLAGS
+=
-mcpu
=
$(ARCH)
-mthumb
-Wall
-ffunction-sections
-O3
CFLAGS
+=
-mcpu
=
$(ARCH)
-mthumb
-Wall
-ffunction-sections
-O3
LDFLAGS
:=
-mcpu
=
$(ARCH)
-mthumb
-g
-nostartfiles
-nostdlib
-O3
LDFLAGS
+=
-Wl
,--gc-sections
-Wl
,--build-id
=
none
COMMON_FLAGS
:=
-g
-mcpu
=
$(ARCH)
-mthumb
-Wall
-O3
-nostdlib
-mfloat-abi
=
soft
CFLAGS
:=
-ffunction-sections
-fdata-sections
-fomit-frame-pointer
-fno-common
ASFLAGS
:=
-Wa
,--gdwarf-2
LDFLAGS
:=
-Wl
,--gc-sections
-Wl
,--build-id
=
none
# Cross tool
CC
:=
${M0_CROSS_COMPILE}
gcc
CPP
:=
${M0_CROSS_COMPILE}
cpp
AS
:=
${M0_CROSS_COMPILE}
gcc
AR
:=
${M0_CROSS_COMPILE}
ar
LD
:=
${M0_CROSS_COMPILE}
ld
OC
:=
${M0_CROSS_COMPILE}
objcopy
OD
:=
${M0_CROSS_COMPILE}
objdump
NM
:=
${M0_CROSS_COMPILE}
nm
PP
:=
${M0_CROSS_COMPILE}
gcc
-E
${CFLAGS}
# NOTE: The line continuation '\' is required in the next define otherwise we
# end up with a line-feed characer at the end of the last c filename.
...
...
@@ -83,10 +80,11 @@ endef
SOURCES
:=
$(C_SOURCES)
OBJS
:=
$(
addprefix
$(BUILD)
/,
$(
call
SOURCES_TO_OBJS,
$(SOURCES)
))
LINKERFILE
:=
src/rk3399m0
.ld
LINKERFILE
:=
$(BUILD)
/
$(PLAT_M0)
.ld
MAPFILE
:=
$(BUILD)
/
$(PLAT_M0)
.map
ELF
:=
$(BUILD)
/
$(PLAT_M0)
.elf
BIN
:=
$(BUILD)
/
$(PLAT_M0)
.bin
LINKERFILE_SRC
:=
src/
$(PLAT_M0)
.ld.S
# Function definition related compilation
define
MAKE_C
...
...
@@ -95,7 +93,7 @@ $(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2))))
$(OBJ)
:
$(2)
@
echo
" CC
$$
<"
$
$(Q)
$
$(CC)
$
$(CFLAGS)
$
$(INCLUDES)
-MMD
-MT
$$
@
-c
$$
<
-o
$$
@
$
$(Q)
$
$(CC)
$
$(COMMON_FLAGS)
$
$(CFLAGS)
$
$(INCLUDES)
-MMD
-MT
$$
@
-c
$$
<
-o
$$
@
endef
define
MAKE_S
...
...
@@ -103,7 +101,7 @@ $(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2))))
$(OBJ)
:
$(2)
@
echo
" AS
$$
<"
$
$(Q)
$
$(
A
S)
$
$(ASFLAGS)
-c
$$
<
-o
$$
@
$
$(Q)
$
$(
CC)
-x
assembler-with-cpp
$
$(COMMON_FLAG
S)
$
$(ASFLAGS)
-c
$$
<
-o
$$
@
endef
define
MAKE_OBJS
...
...
@@ -118,13 +116,15 @@ define MAKE_OBJS
$(and $(REMAIN),$(error Unexpected source files present
:
$(REMAIN)))
endef
.PHONY
:
all
all
:
$(BIN)
.DEFAULT_GOAL
:=
$(BIN)
$(LINKERFILE)
:
$(LINKERFILE_SRC)
$(CC)
$(COMMON_FLAGS)
$(INCLUDES)
-P
-E
-D__LINKER__
-MMD
-MF
$@
.d
-MT
$@
-o
$@
$<
-include
$(LINKERFILE).d
$(ELF)
:
$(OBJS) $(LINKERFILE)
@
echo
" LD
$@
"
$(Q)$(CC)
-o
$@
$(LDFLAGS)
-Wl
,-Map
=
$(MAPFILE)
-Wl
,-T
$(LINKERFILE)
\
$(OBJS)
$(Q)$(CC)
-o
$@
$(COMMON_FLAGS)
$(LDFLAGS)
-Wl
,-Map
=
$(MAPFILE)
-Wl
,-T
$(LINKERFILE)
$(OBJS)
$(BIN)
:
$(ELF)
@
echo
" BIN
$@
"
...
...
plat/rockchip/rk3399/drivers/
pmu/rk3399m0
.h
→
plat/rockchip/rk3399/drivers/
m0/include/addressmap
.h
View file @
d6845d3d
...
...
@@ -28,13 +28,12 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __RK3399M0_H__
#define __RK3399M0_H__
#ifndef __
ROCKCHIP_
RK3399
_
M0_
INCLUDE_SHARED_ADDRESSMAP_
H__
#define __
ROCKCHIP_
RK3399
_
M0_
INCLUDE_SHARED_ADDRESSMAP_
H__
/* pmu_fw.c */
extern
char
rk3399m0_bin
[];
extern
char
rk3399m0_bin_end
[];
#include <addressmap_shared.h>
#define M0_BINCODE_BASE ((uintptr_t)rk3399m0_bin)
/* Registers base address for M0 */
#define MMIO_BASE 0x40000000
#endif
/* __RK3399M0_H__ */
#endif
/* __
ROCKCHIP_
RK3399
_
M0_
INCLUDE_SHARED_ADDRESSMAP_
H__ */
plat/rockchip/rk3399/drivers/m0/include/rk3399_mcu.h
View file @
d6845d3d
...
...
@@ -31,11 +31,28 @@
#ifndef __RK3399_MCU_H__
#define __RK3399_MCU_H__
#define readl(c) ({unsigned int __v = \
#include <addressmap.h>
typedef
unsigned
int
uint32_t
;
#define mmio_read_32(c) ({unsigned int __v = \
(*(volatile unsigned int *)(c)); __v; })
#define writel(v, c) ((*(volatile unsigned int *) (c)) = (v))
#define mmio_write_32(c, v) ((*(volatile unsigned int *)(c)) = (v))
#define mmio_clrbits_32(addr, clear) \
mmio_write_32(addr, (mmio_read_32(addr) & ~(clear)))
#define mmio_setbits_32(addr, set) \
mmio_write_32(addr, (mmio_read_32(addr)) | (set))
#define mmio_clrsetbits_32(addr, clear, set) \
mmio_write_32(addr, (mmio_read_32(addr) & ~(clear)) | (set))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MCU_BASE 0x40000000
#define PMU_BASE (MCU_BASE + 0x07310000)
void
handle_suspend
(
void
);
void
handle_dram
(
void
);
void
stopwatch_init_usecs_expire
(
unsigned
int
usecs
);
int
stopwatch_expired
(
void
);
void
stopwatch_reset
(
void
);
#endif
/* __RK3399_MCU_H__ */
plat/rockchip/rk3399/drivers/m0/src/dram.c
0 → 100644
View file @
d6845d3d
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <dram_regs.h>
#include <m0_param.h>
#include <pmu_bits.h>
#include <pmu_regs.h>
#include "misc_regs.h"
#include "rk3399_mcu.h"
static
uint32_t
gatedis_con0
;
static
void
idle_port
(
void
)
{
gatedis_con0
=
mmio_read_32
(
PMUCRU_BASE
+
PMU_CRU_GATEDIS_CON0
);
mmio_write_32
(
PMUCRU_BASE
+
PMU_CRU_GATEDIS_CON0
,
0x3fffffff
);
mmio_setbits_32
(
PMU_BASE
+
PMU_BUS_IDLE_REQ
,
(
1
<<
PMU_IDLE_REQ_MSCH0
)
|
(
1
<<
PMU_IDLE_REQ_MSCH1
));
while
((
mmio_read_32
(
PMU_BASE
+
PMU_BUS_IDLE_ST
)
&
((
1
<<
PMU_IDLE_ST_MSCH1
)
|
(
1
<<
PMU_IDLE_ST_MSCH0
)))
!=
((
1
<<
PMU_IDLE_ST_MSCH1
)
|
(
1
<<
PMU_IDLE_ST_MSCH0
)))
continue
;
}
static
void
deidle_port
(
void
)
{
mmio_clrbits_32
(
PMU_BASE
+
PMU_BUS_IDLE_REQ
,
(
1
<<
PMU_IDLE_REQ_MSCH0
)
|
(
1
<<
PMU_IDLE_REQ_MSCH1
));
while
(
mmio_read_32
(
PMU_BASE
+
PMU_BUS_IDLE_ST
)
&
((
1
<<
PMU_IDLE_ST_MSCH1
)
|
(
1
<<
PMU_IDLE_ST_MSCH0
)))
continue
;
/* document is wrong, PMU_CRU_GATEDIS_CON0 do not need set MASK BIT */
mmio_write_32
(
PMUCRU_BASE
+
PMU_CRU_GATEDIS_CON0
,
gatedis_con0
);
}
static
void
ddr_set_pll
(
void
)
{
mmio_write_32
(
CRU_BASE
+
CRU_DPLL_CON3
,
PLL_MODE
(
PLL_SLOW_MODE
));
mmio_write_32
(
CRU_BASE
+
CRU_DPLL_CON3
,
PLL_POWER_DOWN
(
1
));
mmio_write_32
(
CRU_BASE
+
CRU_DPLL_CON0
,
mmio_read_32
(
PARAM_ADDR
+
PARAM_DPLL_CON0
));
mmio_write_32
(
CRU_BASE
+
CRU_DPLL_CON1
,
mmio_read_32
(
PARAM_ADDR
+
PARAM_DPLL_CON1
));
mmio_write_32
(
CRU_BASE
+
CRU_DPLL_CON3
,
PLL_POWER_DOWN
(
0
));
while
((
mmio_read_32
(
CRU_BASE
+
CRU_DPLL_CON2
)
&
(
1u
<<
31
))
==
0
)
continue
;
mmio_write_32
(
CRU_BASE
+
CRU_DPLL_CON3
,
PLL_MODE
(
PLL_NORMAL_MODE
));
}
void
handle_dram
(
void
)
{
mmio_setbits_32
(
PHY_REG
(
0
,
927
),
(
1
<<
22
));
mmio_setbits_32
(
PHY_REG
(
1
,
927
),
(
1
<<
22
));
idle_port
();
mmio_write_32
(
CIC_BASE
+
CIC_CTRL0
,
(((
0x3
<<
4
)
|
(
1
<<
2
)
|
1
)
<<
16
)
|
(
1
<<
2
)
|
1
|
mmio_read_32
(
PARAM_ADDR
+
PARAM_FREQ_SELECT
));
while
((
mmio_read_32
(
CIC_BASE
+
CIC_STATUS0
)
&
(
1
<<
2
))
==
0
)
continue
;
ddr_set_pll
();
mmio_write_32
(
CIC_BASE
+
CIC_CTRL0
,
0x20002
);
while
((
mmio_read_32
(
CIC_BASE
+
CIC_STATUS0
)
&
(
1
<<
0
))
==
0
)
continue
;
deidle_port
();
mmio_clrbits_32
(
PHY_REG
(
0
,
927
),
(
1
<<
22
));
mmio_clrbits_32
(
PHY_REG
(
1
,
927
),
(
1
<<
22
));
}
plat/rockchip/rk3399/drivers/m0/src/main.c
View file @
d6845d3d
...
...
@@ -28,44 +28,24 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <m0_param.h>
#include "rk3399_mcu.h"
#define PMU_PWRMODE_CON 0x20
#define PMU_POWER_ST 0x78
#define M0_SCR 0xe000ed10
/* System Control Register (SCR) */
#define SCR_SLEEPDEEP_SHIFT (1 << 2)
static
void
system_wakeup
(
void
)
__attribute__
((
noreturn
))
void
main
(
void
)
{
unsigned
int
status_value
;
unsigned
int
mode_con
;
while
(
1
)
{
status_value
=
readl
(
PMU_BASE
+
PMU_POWER_ST
);
if
(
status_value
)
{
mode_con
=
readl
(
PMU_BASE
+
PMU_PWRMODE_CON
);
writel
(
mode_con
&
(
~
0x01
),
PMU_BASE
+
PMU_PWRMODE_CON
);
return
;
}
switch
(
mmio_read_32
(
PARAM_ADDR
+
PARAM_M0_FUNC
))
{
case
M0_FUNC_SUSPEND
:
handle_suspend
();
break
;
case
M0_FUNC_DRAM
:
handle_dram
();
break
;
default:
break
;
}
}
int
main
(
void
)
{
unsigned
int
reg_src
;
system_wakeup
();
reg_src
=
readl
(
M0_SCR
);
/* m0 enter deep sleep mode */
writel
(
reg_src
|
SCR_SLEEPDEEP_SHIFT
,
M0_SCR
);
mmio_write_32
(
PARAM_ADDR
+
PARAM_M0_DONE
,
M0_DONE_FLAG
);
for
(;;)
__asm
volatile
(
"wfi"
);
return
0
;
__asm__
volatile
(
"wfi"
);
}
plat/rockchip/rk3399/drivers/m0/src/rk3399m0.ld
→
plat/rockchip/rk3399/drivers/m0/src/rk3399m0.ld
.S
View file @
d6845d3d
...
...
@@ -28,12 +28,16 @@
*
POSSIBILITY
OF
SUCH
DAMAGE
.
*/
#include <m0_param.h>
OUTPUT_FORMAT
("
elf32
-
littlearm
")
SECTIONS
{
.
m0_bin
0
:
{
KEEP
(*(.
isr_vector
))
ASSERT
(.
==
0xc0
,
"ISR vector has the wrong size."
)
;
ASSERT
(.
==
PARAM_ADDR
,
"M0 params should go right behind ISR table."
)
;
.
+=
PARAM_M0_SIZE
;
*(.
text
*)
*(.
rodata
*)
*(.
data
*)
...
...
plat/rockchip/rk3399/drivers/m0/src/stopwatch.c
0 → 100644
View file @
d6845d3d
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <m0_param.h>
#include "rk3399_mcu.h"
/* use 24MHz SysTick */
#define US_TO_CYCLE(US) (US * 24)
#define SYST_CST 0xe000e010
/* enable counter */
#define ENABLE (1 << 0)
/* count down to 0 does not cause SysTick exception to pend */
#define TICKINT (1 << 1)
/* core clock used for SysTick */
#define CLKSOURCE (1 << 2)
#define COUNTFLAG (1 << 16)
#define SYST_RVR 0xe000e014
#define MAX_VALUE 0xffffff
#define MAX_USECS (MAX_VALUE / US_TO_CYCLE(1))
#define SYST_CVR 0xe000e018
#define SYST_CALIB 0xe000e01c
unsigned
int
remaining_usecs
;
static
inline
void
stopwatch_set_usecs
(
void
)
{
unsigned
int
cycle
;
unsigned
int
usecs
=
MIN
(
MAX_USECS
,
remaining_usecs
);
remaining_usecs
-=
usecs
;
cycle
=
US_TO_CYCLE
(
usecs
);
mmio_write_32
(
SYST_RVR
,
cycle
);
mmio_write_32
(
SYST_CVR
,
0
);
mmio_write_32
(
SYST_CST
,
ENABLE
|
TICKINT
|
CLKSOURCE
);
}
void
stopwatch_init_usecs_expire
(
unsigned
int
usecs
)
{
/*
* Enter an inifite loop if the stopwatch is in use. This will allow the
* state to be analyzed with a debugger.
*/
if
(
mmio_read_32
(
SYST_CST
)
&
ENABLE
)
while
(
1
)
;
remaining_usecs
=
usecs
;
stopwatch_set_usecs
();
}
int
stopwatch_expired
(
void
)
{
int
val
=
mmio_read_32
(
SYST_CST
);
if
((
val
&
COUNTFLAG
)
||
!
(
val
&
ENABLE
))
{
if
(
!
remaining_usecs
)
return
1
;
stopwatch_set_usecs
();
}
return
0
;
}
void
stopwatch_reset
(
void
)
{
mmio_clrbits_32
(
SYST_CST
,
ENABLE
);
remaining_usecs
=
0
;
}
plat/rockchip/rk3399/drivers/m0/src/suspend.c
0 → 100644
View file @
d6845d3d
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <pmu_regs.h>
#include "rk3399_mcu.h"
#define M0_SCR 0xe000ed10
/* System Control Register (SCR) */
#define SCR_SLEEPDEEP_SHIFT (1 << 2)
void
handle_suspend
(
void
)
{
unsigned
int
status_value
;
while
(
1
)
{
status_value
=
mmio_read_32
(
PMU_BASE
+
PMU_POWER_ST
);
if
(
status_value
)
{
mmio_clrbits_32
(
PMU_BASE
+
PMU_PWRMODE_CON
,
0x01
);
return
;
}
}
/* m0 enter deep sleep mode */
mmio_setbits_32
(
M0_SCR
,
SCR_SLEEPDEEP_SHIFT
);
}
plat/rockchip/rk3399/drivers/pmu/m0_ctl.c
0 → 100644
View file @
d6845d3d
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <arch_helpers.h>
#include <assert.h>
#include <debug.h>
#include <delay_timer.h>
#include <mmio.h>
#include <m0_ctl.h>
#include <plat_private.h>
#include <rk3399_def.h>
#include <secure.h>
#include <soc.h>
void
m0_init
(
void
)
{
/* secure config for M0 */
mmio_write_32
(
SGRF_BASE
+
SGRF_PMU_CON
(
0
),
WMSK_BIT
(
7
));
mmio_write_32
(
SGRF_BASE
+
SGRF_SOC_CON
(
6
),
WMSK_BIT
(
12
));
/* set the execute address for M0 */
mmio_write_32
(
SGRF_BASE
+
SGRF_PMU_CON
(
3
),
BITS_WITH_WMASK
((
M0_BINCODE_BASE
>>
12
)
&
0xffff
,
0xffff
,
0
));
mmio_write_32
(
SGRF_BASE
+
SGRF_PMU_CON
(
7
),
BITS_WITH_WMASK
((
M0_BINCODE_BASE
>>
28
)
&
0xf
,
0xf
,
0
));
/* document is wrong, PMU_CRU_GATEDIS_CON0 do not need set MASK BIT */
mmio_setbits_32
(
PMUCRU_BASE
+
PMUCRU_GATEDIS_CON0
,
0x02
);
/*
* To switch the parent to xin24M and div == 1,
*
* We need to close most of the PLLs and clocks except the OSC 24MHz
* durning suspend, and this should be enough to supplies the ddrfreq,
* For the simple handle, we just keep the fixed 24MHz to supply the
* suspend and ddrfreq directly.
*/
mmio_write_32
(
PMUCRU_BASE
+
PMUCRU_CLKSEL_CON0
,
BIT_WITH_WMSK
(
15
)
|
BITS_WITH_WMASK
(
0x0
,
0x1f
,
8
));
mmio_write_32
(
PMUCRU_BASE
+
PMUCRU_CLKGATE_CON2
,
WMSK_BIT
(
5
));
}
void
m0_start
(
void
)
{
/* enable clocks for M0 */
mmio_write_32
(
PMUCRU_BASE
+
PMUCRU_CLKGATE_CON2
,
BITS_WITH_WMASK
(
0x0
,
0xf
,
0
));
/* clean the PARAM_M0_DONE flag, mean that M0 will start working */
mmio_write_32
(
M0_PARAM_ADDR
+
PARAM_M0_DONE
,
0
);
dmbst
();
mmio_write_32
(
PMUCRU_BASE
+
PMUCRU_SOFTRST_CON0
,
BITS_WITH_WMASK
(
0x0
,
0x4
,
0
));
udelay
(
5
);
/* start M0 */
mmio_write_32
(
PMUCRU_BASE
+
PMUCRU_SOFTRST_CON0
,
BITS_WITH_WMASK
(
0x0
,
0x20
,
0
));
dmbst
();
}
void
m0_stop
(
void
)
{
/* stop M0 */
mmio_write_32
(
PMUCRU_BASE
+
PMUCRU_SOFTRST_CON0
,
BITS_WITH_WMASK
(
0x24
,
0x24
,
0
));
/* disable clocks for M0 */
mmio_write_32
(
PMUCRU_BASE
+
PMUCRU_CLKGATE_CON2
,
BITS_WITH_WMASK
(
0xf
,
0xf
,
0
));
}
void
m0_wait_done
(
void
)
{
do
{
/*
* Don't starve the M0 for access to SRAM, so delay before
* reading the PARAM_M0_DONE value again.
*/
udelay
(
5
);
dsb
();
}
while
(
mmio_read_32
(
M0_PARAM_ADDR
+
PARAM_M0_DONE
)
!=
M0_DONE_FLAG
);
/*
* Let the M0 settle into WFI before we leave. This is so we don't reset
* the M0 in a bad spot which can cause problems with the M0.
*/
udelay
(
10
);
dsb
();
}
plat/rockchip/rk3399/drivers/pmu/m0_ctl.h
0 → 100644
View file @
d6845d3d
/*
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __M0_CTL_H__
#define __M0_CTL_H__
#include <m0_param.h>
#define M0_BINCODE_BASE ((uintptr_t)rk3399m0_bin)
#define M0_PARAM_ADDR (M0_BINCODE_BASE + PARAM_ADDR)
/* pmu_fw.c */
extern
char
rk3399m0_bin
[];
extern
char
rk3399m0_bin_end
[];
extern
void
m0_init
(
void
);
extern
void
m0_start
(
void
);
extern
void
m0_stop
(
void
);
extern
void
m0_wait_done
(
void
);
#endif
/* __M0_CTL_H__ */
plat/rockchip/rk3399/drivers/pmu/pmu.c
View file @
d6845d3d
...
...
@@ -33,21 +33,23 @@
#include <bakery_lock.h>
#include <debug.h>
#include <delay_timer.h>
#include <dfs.h>
#include <errno.h>
#include <gpio.h>
#include <mmio.h>
#include <m0_ctl.h>
#include <platform.h>
#include <platform_def.h>
#include <plat_params.h>
#include <plat_private.h>
#include <rk3399_def.h>
#include <pmu_sram.h>
#include <secure.h>
#include <soc.h>
#include <pmu.h>
#include <pmu_com.h>
#include <pwm.h>
#include <bl31.h>
#include <rk3399m0.h>
#include <suspend.h>
DEFINE_BAKERY_LOCK
(
rockchip_pd_lock
);
...
...
@@ -1065,36 +1067,10 @@ static void resume_gpio(void)
}
}
static
void
m0_c
lock_init
(
void
)
static
void
m0_c
onfigure_suspend
(
void
)
{
/* enable clocks for M0 */
mmio_write_32
(
PMUCRU_BASE
+
PMUCRU_CLKGATE_CON2
,
BITS_WITH_WMASK
(
0x0
,
0x2f
,
0
));
/* switch the parent to xin24M and div == 1 */
mmio_write_32
(
PMUCRU_BASE
+
PMUCRU_CLKSEL_CON0
,
BIT_WITH_WMSK
(
15
)
|
BITS_WITH_WMASK
(
0x0
,
0x1f
,
8
));
/* start M0 */
mmio_write_32
(
PMUCRU_BASE
+
PMUCRU_SOFTRST_CON0
,
BITS_WITH_WMASK
(
0x0
,
0x24
,
0
));
/* gating disable for M0 */
mmio_write_32
(
PMUCRU_BASE
+
PMUCRU_GATEDIS_CON0
,
BIT_WITH_WMSK
(
1
));
}
static
void
m0_reset
(
void
)
{
/* stop M0 */
mmio_write_32
(
PMUCRU_BASE
+
PMUCRU_SOFTRST_CON0
,
BITS_WITH_WMASK
(
0x24
,
0x24
,
0
));
/* recover gating bit for M0 */
mmio_write_32
(
PMUCRU_BASE
+
PMUCRU_GATEDIS_CON0
,
WMSK_BIT
(
1
));
/* disable clocks for M0 */
mmio_write_32
(
PMUCRU_BASE
+
PMUCRU_CLKGATE_CON2
,
BITS_WITH_WMASK
(
0x2f
,
0x2f
,
0
));
/* set PARAM to M0_FUNC_SUSPEND */
mmio_write_32
(
M0_PARAM_ADDR
+
PARAM_M0_FUNC
,
M0_FUNC_SUSPEND
);
}
static
int
sys_pwr_domain_suspend
(
void
)
...
...
@@ -1102,6 +1078,7 @@ static int sys_pwr_domain_suspend(void)
uint32_t
wait_cnt
=
0
;
uint32_t
status
=
0
;
ddr_prepare_for_sys_suspend
();
dmc_save
();
pmu_scu_b_pwrdn
();
...
...
@@ -1117,11 +1094,12 @@ static int sys_pwr_domain_suspend(void)
sys_slp_config
();
m0_clock_init
();
m0_configure_suspend
();
m0_start
();
pmu_sgrf_rst_hld
();
mmio_write_32
(
SGRF_BASE
+
SGRF_SOC_CON
0_1
(
1
),
mmio_write_32
(
SGRF_BASE
+
SGRF_SOC_CON
(
1
),
(
PMUSRAM_BASE
>>
CPU_BOOT_ADDR_ALIGN
)
|
CPU_BOOT_ADDR_WMASK
);
...
...
@@ -1173,7 +1151,7 @@ static int sys_pwr_domain_resume(void)
udelay
(
300
);
enable_dvfs_plls
();
secure_watchdog_
restor
e
();
secure_watchdog_
enabl
e
();
/* restore clk_ddrc_bpll_src_en gate */
mmio_write_32
(
CRU_BASE
+
CRU_CLKGATE_CON
(
3
),
...
...
@@ -1189,7 +1167,7 @@ static int sys_pwr_domain_resume(void)
mmio_write_32
(
PMU_BASE
+
PMU_WAKEUP_STATUS
,
0xffffffff
);
mmio_write_32
(
PMU_BASE
+
PMU_WKUP_CFG4
,
0x00
);
mmio_write_32
(
SGRF_BASE
+
SGRF_SOC_CON
0_1
(
1
),
mmio_write_32
(
SGRF_BASE
+
SGRF_SOC_CON
(
1
),
(
cpu_warm_boot_addr
>>
CPU_BOOT_ADDR_ALIGN
)
|
CPU_BOOT_ADDR_WMASK
);
...
...
@@ -1241,8 +1219,9 @@ static int sys_pwr_domain_resume(void)
BIT
(
PMU_CLR_GIC
));
plat_rockchip_gic_cpuif_enable
();
m0_stop
();
m0_reset
();
ddr_prepare_for_sys_resume
();
return
0
;
}
...
...
@@ -1328,7 +1307,7 @@ void plat_rockchip_pmu_init(void)
psram_sleep_cfg
->
boot_mpidr
=
read_mpidr_el1
()
&
0xffff
;
/* config cpu's warm boot address */
mmio_write_32
(
SGRF_BASE
+
SGRF_SOC_CON
0_1
(
1
),
mmio_write_32
(
SGRF_BASE
+
SGRF_SOC_CON
(
1
),
(
cpu_warm_boot_addr
>>
CPU_BOOT_ADDR_ALIGN
)
|
CPU_BOOT_ADDR_WMASK
);
mmio_write_32
(
PMU_BASE
+
PMU_NOC_AUTO_ENA
,
NOC_AUTO_ENABLE
);
...
...
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