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
c2229abd
Commit
c2229abd
authored
Aug 25, 2016
by
davidcunado-arm
Committed by
GitHub
Aug 25, 2016
Browse files
Merge pull request #684 from rockchip-linux/add-sdram-for-rk3399
rockchip: add dram driver for rk3399
parents
079e522d
863edcea
Changes
9
Hide whitespace changes
Inline
Side-by-side
plat/rockchip/rk3399/drivers/dram/dcf_code.inc
0 → 100644
View file @
c2229abd
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/dram.c
0 → 100644
View file @
c2229abd
/*
* 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 <debug.h>
#include <mmio.h>
#include <plat_private.h>
#include "dram.h"
#include "dram_spec_timing.h"
#include "string.h"
#include "soc.h"
#include "pmu.h"
#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
;
};
static
const
struct
pll_div
dpll_rates_table
[]
=
{
/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2 */
{.
mhz
=
933
,
.
refdiv
=
3
,
.
fbdiv
=
350
,
.
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
},
{.
mhz
=
600
,
.
refdiv
=
1
,
.
fbdiv
=
50
,
.
postdiv1
=
2
,
.
postdiv2
=
1
},
{.
mhz
=
528
,
.
refdiv
=
1
,
.
fbdiv
=
66
,
.
postdiv1
=
3
,
.
postdiv2
=
1
},
{.
mhz
=
400
,
.
refdiv
=
1
,
.
fbdiv
=
50
,
.
postdiv1
=
3
,
.
postdiv2
=
1
},
{.
mhz
=
300
,
.
refdiv
=
1
,
.
fbdiv
=
50
,
.
postdiv1
=
4
,
.
postdiv2
=
1
},
{.
mhz
=
200
,
.
refdiv
=
1
,
.
fbdiv
=
50
,
.
postdiv1
=
3
,
.
postdiv2
=
2
},
};
static
struct
rk3399_ddr_cic_regs
*
const
rk3399_ddr_cic
=
(
void
*
)
CIC_BASE
;
static
struct
rk3399_ddr_pctl_regs
*
const
rk3399_ddr_pctl
[
2
]
=
{
(
void
*
)
DDRC0_BASE
,
(
void
*
)
DDRC1_BASE
};
static
struct
rk3399_ddr_pi_regs
*
const
rk3399_ddr_pi
[
2
]
=
{
(
void
*
)
DDRC0_PI_BASE
,
(
void
*
)
DDRC1_PI_BASE
};
static
struct
rk3399_ddr_publ_regs
*
const
rk3399_ddr_publ
[
2
]
=
{
(
void
*
)
DDRC0_PHY_BASE
,
(
void
*
)
DDRC1_PHY_BASE
};
struct
rk3399_dram_status
{
uint32_t
current_index
;
uint32_t
index_freq
[
2
];
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
};
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 write_32(addr, value)\
mmio_write_32((uintptr_t)(addr), (uint32_t)(value))
#define read_32(addr) \
mmio_read_32((uintptr_t)(addr))
#define clrbits_32(addr, clear)\
mmio_clrbits_32((uintptr_t)(addr), (uint32_t)(clear))
#define setbits_32(addr, set)\
mmio_setbits_32((uintptr_t)(addr), (uint32_t)(set))
#define clrsetbits_32(addr, clear, set)\
mmio_clrsetbits_32((uintptr_t)(addr), (uint32_t)(clear),\
(uint32_t)(set))
#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
unsigned
int
get_cs_die_capability
(
struct
rk3399_sdram_config
*
psdram_config
,
unsigned
int
channel
,
unsigned
int
cs
)
{
unsigned
int
die
;
unsigned
int
cs_cap
;
unsigned
int
row
[
2
];
row
[
0
]
=
psdram_config
->
ch
[
channel
].
cs0_row
;
row
[
1
]
=
psdram_config
->
ch
[
channel
].
cs1_row
;
die
=
psdram_config
->
ch
[
channel
].
bus_width
/
psdram_config
->
ch
[
channel
].
each_die_bus_width
;
cs_cap
=
(
1
<<
(
row
[
cs
]
+
(
psdram_config
->
ch
[
channel
].
bank
/
4
+
1
)
+
psdram_config
->
ch
[
channel
].
col
+
(
psdram_config
->
ch
[
channel
].
bus_width
/
16
)));
if
(
psdram_config
->
ch
[
channel
].
each_die_6gb_or_12gb
)
cs_cap
=
cs_cap
*
3
/
4
;
return
(
cs_cap
/
die
);
}
static
void
sdram_config_init
(
struct
rk3399_sdram_config
*
psdram_config
)
{
uint32_t
os_reg2_val
,
i
;
os_reg2_val
=
read_32
(
PMUGRF_BASE
+
PMUGRF_OSREG
(
2
));
for
(
i
=
0
;
i
<
READ_CH_CNT
(
os_reg2_val
);
i
++
)
{
psdram_config
->
ch
[
i
].
bank
=
1
<<
READ_BK_INFO
(
os_reg2_val
,
i
);
psdram_config
->
ch
[
i
].
bus_width
=
8
*
(
1
<<
READ_BW_INFO
(
os_reg2_val
,
i
));
psdram_config
->
ch
[
i
].
col
=
READ_COL_INFO
(
os_reg2_val
,
i
);
psdram_config
->
ch
[
i
].
cs0_row
=
READ_CS0_ROW_INFO
(
os_reg2_val
,
i
);
psdram_config
->
ch
[
i
].
cs1_row
=
READ_CS1_ROW_INFO
(
os_reg2_val
,
i
);
psdram_config
->
ch
[
i
].
cs_cnt
=
READ_CS_INFO
(
os_reg2_val
,
i
);
psdram_config
->
ch
[
i
].
each_die_6gb_or_12gb
=
READ_CH_ROW_INFO
(
os_reg2_val
,
i
);
psdram_config
->
ch
[
i
].
each_die_bus_width
=
8
*
(
1
<<
READ_DIE_BW_INFO
(
os_reg2_val
,
i
));
}
psdram_config
->
dramtype
=
READ_DRAMTYPE_INFO
(
os_reg2_val
);
psdram_config
->
channal_num
=
READ_CH_CNT
(
os_reg2_val
);
}
static
void
drv_odt_lp_cfg_init
(
uint32_t
dram_type
,
struct
ddr_dts_config_timing
*
dts_timing
,
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
;
}
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
));
}
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
));
}
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
;
};
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
;
}
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
;
}
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
;
break
;
}
}
static
void
sdram_timing_cfg_init
(
struct
timing_related_config
*
ptiming_config
,
struct
rk3399_sdram_config
*
psdram_config
,
struct
drv_odt_lp_config
*
drv_config
)
{
uint32_t
i
,
j
;
for
(
i
=
0
;
i
<
psdram_config
->
channal_num
;
i
++
)
{
ptiming_config
->
dram_info
[
i
].
speed_rate
=
drv_config
->
ddr3_speed_bin
;
ptiming_config
->
dram_info
[
i
].
cs_cnt
=
psdram_config
->
ch
[
i
].
cs_cnt
;
for
(
j
=
0
;
j
<
psdram_config
->
ch
[
i
].
cs_cnt
;
j
++
)
{
ptiming_config
->
dram_info
[
i
].
per_die_capability
[
j
]
=
get_cs_die_capability
(
psdram_config
,
i
,
j
);
}
}
ptiming_config
->
dram_type
=
psdram_config
->
dramtype
;
ptiming_config
->
ch_cnt
=
psdram_config
->
channal_num
;
switch
(
psdram_config
->
dramtype
)
{
case
DDR3
:
ptiming_config
->
bl
=
ddr3_default_config
.
bl
;
ptiming_config
->
ap
=
ddr3_default_config
.
ap
;
break
;
case
LPDDR3
:
ptiming_config
->
bl
=
lpddr3_default_config
.
bl
;
ptiming_config
->
ap
=
lpddr3_default_config
.
ap
;
break
;
case
LPDDR4
:
ptiming_config
->
bl
=
lpddr4_default_config
.
bl
;
ptiming_config
->
ap
=
lpddr4_default_config
.
ap
;
ptiming_config
->
rdbi
=
0
;
ptiming_config
->
wdbi
=
0
;
break
;
}
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
;
}
struct
lat_adj_pair
{
uint32_t
cl
;
uint32_t
rdlat_adj
;
uint32_t
cwl
;
uint32_t
wrlat_adj
;
};
const
struct
lat_adj_pair
ddr3_lat_adj
[]
=
{
{
6
,
5
,
5
,
4
},
{
8
,
7
,
6
,
5
},
{
10
,
9
,
7
,
6
},
{
11
,
9
,
8
,
7
},
{
13
,
0xb
,
9
,
8
},
{
14
,
0xb
,
0xa
,
9
}
};
const
struct
lat_adj_pair
lpddr3_lat_adj
[]
=
{
{
3
,
2
,
1
,
0
},
{
6
,
5
,
3
,
2
},
{
8
,
7
,
4
,
3
},
{
9
,
8
,
5
,
4
},
{
10
,
9
,
6
,
5
},
{
11
,
9
,
6
,
5
},
{
12
,
0xa
,
6
,
5
},
{
14
,
0xc
,
8
,
7
},
{
16
,
0xd
,
8
,
7
}
};
const
struct
lat_adj_pair
lpddr4_lat_adj
[]
=
{
{
6
,
5
,
4
,
2
},
{
10
,
9
,
6
,
4
},
{
14
,
0xc
,
8
,
6
},
{
20
,
0x11
,
0xa
,
8
},
{
24
,
0x15
,
0xc
,
0xa
},
{
28
,
0x18
,
0xe
,
0xc
},
{
32
,
0x1b
,
0x10
,
0xe
},
{
36
,
0x1e
,
0x12
,
0x10
}
};
static
uint32_t
get_rdlat_adj
(
uint32_t
dram_type
,
uint32_t
cl
)
{
const
struct
lat_adj_pair
*
p
;
uint32_t
cnt
;
uint32_t
i
;
if
(
dram_type
==
DDR3
)
{
p
=
ddr3_lat_adj
;
cnt
=
ARRAY_SIZE
(
ddr3_lat_adj
);
}
else
if
(
dram_type
==
LPDDR3
)
{
p
=
lpddr3_lat_adj
;
cnt
=
ARRAY_SIZE
(
lpddr3_lat_adj
);
}
else
{
p
=
lpddr4_lat_adj
;
cnt
=
ARRAY_SIZE
(
lpddr4_lat_adj
);
}
for
(
i
=
0
;
i
<
cnt
;
i
++
)
{
if
(
cl
==
p
[
i
].
cl
)
return
p
[
i
].
rdlat_adj
;
}
/* fail */
return
0xff
;
}
static
uint32_t
get_wrlat_adj
(
uint32_t
dram_type
,
uint32_t
cwl
)
{
const
struct
lat_adj_pair
*
p
;
uint32_t
cnt
;
uint32_t
i
;
if
(
dram_type
==
DDR3
)
{
p
=
ddr3_lat_adj
;
cnt
=
ARRAY_SIZE
(
ddr3_lat_adj
);
}
else
if
(
dram_type
==
LPDDR3
)
{
p
=
lpddr3_lat_adj
;
cnt
=
ARRAY_SIZE
(
lpddr3_lat_adj
);
}
else
{
p
=
lpddr4_lat_adj
;
cnt
=
ARRAY_SIZE
(
lpddr4_lat_adj
);
}
for
(
i
=
0
;
i
<
cnt
;
i
++
)
{
if
(
cwl
==
p
[
i
].
cwl
)
return
p
[
i
].
wrlat_adj
;
}
/* fail */
return
0xff
;
}
#define PI_REGS_DIMM_SUPPORT (0)
#define PI_ADD_LATENCY (0)
#define PI_DOUBLEFREEK (1)
#define PI_PAD_DELAY_PS_VALUE (1000)
#define PI_IE_ENABLE_VALUE (3000)
#define PI_TSEL_ENABLE_VALUE (700)
static
uint32_t
get_pi_rdlat_adj
(
struct
dram_timing_t
*
pdram_timing
)
{
/*[DLLSUBTYPE2] == "STD_DENALI_HS" */
uint32_t
rdlat
,
delay_adder
,
ie_enable
,
hs_offset
,
tsel_adder
,
extra_adder
,
tsel_enable
;
ie_enable
=
PI_IE_ENABLE_VALUE
;
tsel_enable
=
PI_TSEL_ENABLE_VALUE
;
rdlat
=
pdram_timing
->
cl
+
PI_ADD_LATENCY
;
delay_adder
=
ie_enable
/
(
1000000
/
pdram_timing
->
mhz
);
if
((
ie_enable
%
(
1000000
/
pdram_timing
->
mhz
))
!=
0
)
delay_adder
++
;
hs_offset
=
0
;
tsel_adder
=
0
;
extra_adder
=
0
;
/* rdlat = rdlat - (PREAMBLE_SUPPORT & 0x1); */
tsel_adder
=
tsel_enable
/
(
1000000
/
pdram_timing
->
mhz
);
if
((
tsel_enable
%
(
1000000
/
pdram_timing
->
mhz
))
!=
0
)
tsel_adder
++
;
delay_adder
=
delay_adder
-
1
;
if
(
tsel_adder
>
delay_adder
)
extra_adder
=
tsel_adder
-
delay_adder
;
else
extra_adder
=
0
;
if
(
PI_REGS_DIMM_SUPPORT
&&
PI_DOUBLEFREEK
)
hs_offset
=
2
;
else
hs_offset
=
1
;
if
(
delay_adder
>
(
rdlat
-
1
-
hs_offset
))
{
rdlat
=
rdlat
-
tsel_adder
;
}
else
{
if
((
rdlat
-
delay_adder
)
<
2
)
rdlat
=
2
;
else
rdlat
=
rdlat
-
delay_adder
-
extra_adder
;
}
return
rdlat
;
}
static
uint32_t
get_pi_wrlat
(
struct
dram_timing_t
*
pdram_timing
,
struct
timing_related_config
*
timing_config
)
{
uint32_t
tmp
;
if
(
timing_config
->
dram_type
==
LPDDR3
)
{
tmp
=
pdram_timing
->
cl
;
if
(
tmp
>=
14
)
tmp
=
8
;
else
if
(
tmp
>=
10
)
tmp
=
6
;
else
if
(
tmp
==
9
)
tmp
=
5
;
else
if
(
tmp
==
8
)
tmp
=
4
;
else
if
(
tmp
==
6
)
tmp
=
3
;
else
tmp
=
1
;
}
else
{
tmp
=
1
;
}
return
tmp
;
}
static
uint32_t
get_pi_wrlat_adj
(
struct
dram_timing_t
*
pdram_timing
,
struct
timing_related_config
*
timing_config
)
{
return
get_pi_wrlat
(
pdram_timing
,
timing_config
)
+
PI_ADD_LATENCY
-
1
;
}
static
uint32_t
get_pi_tdfi_phy_rdlat
(
struct
dram_timing_t
*
pdram_timing
,
struct
timing_related_config
*
timing_config
)
{
/* [DLLSUBTYPE2] == "STD_DENALI_HS" */
uint32_t
cas_lat
,
delay_adder
,
ie_enable
,
hs_offset
,
ie_delay_adder
;
uint32_t
mem_delay_ps
,
round_trip_ps
;
uint32_t
phy_internal_delay
,
lpddr_adder
,
dfi_adder
,
rdlat_delay
;
ie_enable
=
PI_IE_ENABLE_VALUE
;
delay_adder
=
ie_enable
/
(
1000000
/
pdram_timing
->
mhz
);
if
((
ie_enable
%
(
1000000
/
pdram_timing
->
mhz
))
!=
0
)
delay_adder
++
;
delay_adder
=
delay_adder
-
1
;
if
(
PI_REGS_DIMM_SUPPORT
&&
PI_DOUBLEFREEK
)
hs_offset
=
2
;
else
hs_offset
=
1
;
cas_lat
=
pdram_timing
->
cl
+
PI_ADD_LATENCY
;
if
(
delay_adder
>
(
cas_lat
-
1
-
hs_offset
))
{
ie_delay_adder
=
0
;
}
else
{
ie_delay_adder
=
ie_enable
/
(
1000000
/
pdram_timing
->
mhz
);
if
((
ie_enable
%
(
1000000
/
pdram_timing
->
mhz
))
!=
0
)
ie_delay_adder
++
;
}
if
(
timing_config
->
dram_type
==
DDR3
)
{
mem_delay_ps
=
0
;
}
else
if
(
timing_config
->
dram_type
==
LPDDR4
)
{
mem_delay_ps
=
3600
;
}
else
if
(
timing_config
->
dram_type
==
LPDDR3
)
{
mem_delay_ps
=
5500
;
}
else
{
printf
(
"get_pi_tdfi_phy_rdlat:dramtype unsupport
\n
"
);
return
0
;
}
round_trip_ps
=
1100
+
500
+
mem_delay_ps
+
500
+
600
;
delay_adder
=
round_trip_ps
/
(
1000000
/
pdram_timing
->
mhz
);
if
((
round_trip_ps
%
(
1000000
/
pdram_timing
->
mhz
))
!=
0
)
delay_adder
++
;
phy_internal_delay
=
5
+
2
+
4
;
lpddr_adder
=
mem_delay_ps
/
(
1000000
/
pdram_timing
->
mhz
);
if
((
mem_delay_ps
%
(
1000000
/
pdram_timing
->
mhz
))
!=
0
)
lpddr_adder
++
;
dfi_adder
=
0
;
phy_internal_delay
=
phy_internal_delay
+
2
;
rdlat_delay
=
delay_adder
+
phy_internal_delay
+
ie_delay_adder
+
lpddr_adder
+
dfi_adder
;
rdlat_delay
=
rdlat_delay
+
2
;
return
rdlat_delay
;
}
static
uint32_t
get_pi_todtoff_min
(
struct
dram_timing_t
*
pdram_timing
,
struct
timing_related_config
*
timing_config
)
{
uint32_t
tmp
,
todtoff_min_ps
;
if
(
timing_config
->
dram_type
==
LPDDR3
)
todtoff_min_ps
=
2500
;
else
if
(
timing_config
->
dram_type
==
LPDDR4
)
todtoff_min_ps
=
1500
;
else
todtoff_min_ps
=
0
;
/* todtoff_min */
tmp
=
todtoff_min_ps
/
(
1000000
/
pdram_timing
->
mhz
);
if
((
todtoff_min_ps
%
(
1000000
/
pdram_timing
->
mhz
))
!=
0
)
tmp
++
;
return
tmp
;
}
static
uint32_t
get_pi_todtoff_max
(
struct
dram_timing_t
*
pdram_timing
,
struct
timing_related_config
*
timing_config
)
{
uint32_t
tmp
,
todtoff_max_ps
;
if
((
timing_config
->
dram_type
==
LPDDR4
)
||
(
timing_config
->
dram_type
==
LPDDR3
))
todtoff_max_ps
=
3500
;
else
todtoff_max_ps
=
0
;
/* todtoff_max */
tmp
=
todtoff_max_ps
/
(
1000000
/
pdram_timing
->
mhz
);
if
((
todtoff_max_ps
%
(
1000000
/
pdram_timing
->
mhz
))
!=
0
)
tmp
++
;
return
tmp
;
}
static
void
gen_rk3399_ctl_params_f0
(
struct
timing_related_config
*
timing_config
,
struct
dram_timing_t
*
pdram_timing
)
{
uint32_t
i
;
uint32_t
tmp
,
tmp1
;
for
(
i
=
0
;
i
<
timing_config
->
ch_cnt
;
i
++
)
{
if
(
timing_config
->
dram_type
==
DDR3
)
{
tmp
=
((
700000
+
10
)
*
timing_config
->
freq
+
999
)
/
1000
;
tmp
+=
pdram_timing
->
txsnr
+
(
pdram_timing
->
tmrd
*
3
)
+
pdram_timing
->
tmod
+
pdram_timing
->
tzqinit
;
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
5
],
tmp
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
22
],
0xffff
,
pdram_timing
->
tdllk
);
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
32
],
(
pdram_timing
->
tmod
<<
8
)
|
pdram_timing
->
tmrd
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
59
],
0xffff
<<
16
,
(
pdram_timing
->
txsr
-
pdram_timing
->
trcd
)
<<
16
);
}
else
if
(
timing_config
->
dram_type
==
LPDDR4
)
{
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
5
],
pdram_timing
->
tinit1
+
pdram_timing
->
tinit3
);
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
32
],
(
pdram_timing
->
tmrd
<<
8
)
|
pdram_timing
->
tmrd
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
59
],
0xffff
<<
16
,
pdram_timing
->
txsr
<<
16
);
}
else
{
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
5
],
pdram_timing
->
tinit1
);
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
7
],
pdram_timing
->
tinit4
);
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
32
],
(
pdram_timing
->
tmrd
<<
8
)
|
pdram_timing
->
tmrd
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
59
],
0xffff
<<
16
,
pdram_timing
->
txsr
<<
16
);
}
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
6
],
pdram_timing
->
tinit3
);
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
8
],
pdram_timing
->
tinit5
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
23
],
(
0x7f
<<
16
),
((
pdram_timing
->
cl
*
2
)
<<
16
));
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
23
],
(
0x1f
<<
24
),
(
pdram_timing
->
cwl
<<
24
));
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
24
],
0x3f
,
pdram_timing
->
al
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
26
],
0xffff
<<
16
,
(
pdram_timing
->
trc
<<
24
)
|
(
pdram_timing
->
trrd
<<
16
));
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
27
],
(
pdram_timing
->
tfaw
<<
24
)
|
(
pdram_timing
->
trppb
<<
16
)
|
(
pdram_timing
->
twtr
<<
8
)
|
pdram_timing
->
tras_min
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
31
],
0xff
<<
24
,
max
(
4
,
pdram_timing
->
trtp
)
<<
24
);
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
33
],
(
pdram_timing
->
tcke
<<
24
)
|
pdram_timing
->
tras_max
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
34
],
0xff
,
max
(
1
,
pdram_timing
->
tckesr
));
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
39
],
(
0x3f
<<
16
)
|
(
0xff
<<
8
),
(
pdram_timing
->
twr
<<
16
)
|
(
pdram_timing
->
trcd
<<
8
));
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
42
],
0x1f
<<
16
,
pdram_timing
->
tmrz
<<
16
);
tmp
=
pdram_timing
->
tdal
?
pdram_timing
->
tdal
:
(
pdram_timing
->
twr
+
pdram_timing
->
trp
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
44
],
0xff
,
tmp
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
45
],
0xff
,
pdram_timing
->
trp
);
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
48
],
((
pdram_timing
->
trefi
-
8
)
<<
16
)
|
pdram_timing
->
trfc
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
52
],
0xffff
,
pdram_timing
->
txp
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
53
],
0xffff
<<
16
,
pdram_timing
->
txpdll
<<
16
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
55
],
0xf
<<
24
,
pdram_timing
->
tcscke
<<
24
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
55
],
0xff
,
pdram_timing
->
tmrri
);
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
56
],
(
pdram_timing
->
tzqcke
<<
24
)
|
(
pdram_timing
->
tmrwckel
<<
16
)
|
(
pdram_timing
->
tckehcs
<<
8
)
|
pdram_timing
->
tckelcs
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
60
],
0xffff
,
pdram_timing
->
txsnr
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
62
],
0xffff
<<
16
,
(
pdram_timing
->
tckehcmd
<<
24
)
|
(
pdram_timing
->
tckelcmd
<<
16
));
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
63
],
(
pdram_timing
->
tckelpd
<<
24
)
|
(
pdram_timing
->
tescke
<<
16
)
|
(
pdram_timing
->
tsr
<<
8
)
|
pdram_timing
->
tckckel
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
64
],
0xfff
,
(
pdram_timing
->
tcmdcke
<<
8
)
|
pdram_timing
->
tcsckeh
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
92
],
(
0xffff
<<
8
),
(
pdram_timing
->
tcksrx
<<
16
)
|
(
pdram_timing
->
tcksre
<<
8
));
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
108
],
(
0x1
<<
24
),
(
timing_config
->
dllbp
<<
24
));
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
122
],
(
0x3FF
<<
16
),
(
pdram_timing
->
tvrcg_enable
<<
16
));
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
123
],
(
pdram_timing
->
tfc_long
<<
16
)
|
pdram_timing
->
tvrcg_disable
);
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
124
],
(
pdram_timing
->
tvref_long
<<
16
)
|
(
pdram_timing
->
tckfspx
<<
8
)
|
pdram_timing
->
tckfspe
);
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
133
],
(
pdram_timing
->
mr
[
1
]
<<
16
)
|
pdram_timing
->
mr
[
0
]);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
134
],
0xffff
,
pdram_timing
->
mr
[
2
]);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
138
],
0xffff
,
pdram_timing
->
mr
[
3
]);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
139
],
0xff
<<
24
,
pdram_timing
->
mr11
<<
24
);
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
147
],
(
pdram_timing
->
mr
[
1
]
<<
16
)
|
pdram_timing
->
mr
[
0
]);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
148
],
0xffff
,
pdram_timing
->
mr
[
2
]);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
152
],
0xffff
,
pdram_timing
->
mr
[
3
]);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
153
],
0xff
<<
24
,
pdram_timing
->
mr11
<<
24
);
if
(
timing_config
->
dram_type
==
LPDDR4
)
{
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
140
],
0xffff
<<
16
,
pdram_timing
->
mr12
<<
16
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
142
],
0xffff
<<
16
,
pdram_timing
->
mr14
<<
16
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
145
],
0xffff
<<
16
,
pdram_timing
->
mr22
<<
16
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
154
],
0xffff
<<
16
,
pdram_timing
->
mr12
<<
16
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
156
],
0xffff
<<
16
,
pdram_timing
->
mr14
<<
16
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
159
],
0xffff
<<
16
,
pdram_timing
->
mr22
<<
16
);
}
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
179
],
0xfff
<<
8
,
pdram_timing
->
tzqinit
<<
8
);
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
180
],
(
pdram_timing
->
tzqcs
<<
16
)
|
(
pdram_timing
->
tzqinit
/
2
));
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
181
],
(
pdram_timing
->
tzqlat
<<
16
)
|
pdram_timing
->
tzqcal
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
212
],
0xff
<<
8
,
pdram_timing
->
todton
<<
8
);
if
(
timing_config
->
odt
)
{
setbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
213
],
1
<<
16
);
if
(
timing_config
->
freq
<
400
)
tmp
=
4
<<
24
;
else
tmp
=
8
<<
24
;
}
else
{
clrbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
213
],
1
<<
16
);
tmp
=
2
<<
24
;
}
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
216
],
0x1f
<<
24
,
tmp
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
221
],
(
0x3
<<
16
)
|
(
0xf
<<
8
),
(
pdram_timing
->
tdqsck
<<
16
)
|
(
pdram_timing
->
tdqsck_max
<<
8
));
tmp
=
(
get_wrlat_adj
(
timing_config
->
dram_type
,
pdram_timing
->
cwl
)
<<
8
)
|
get_rdlat_adj
(
timing_config
->
dram_type
,
pdram_timing
->
cl
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
284
],
0xffff
,
tmp
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
82
],
0xffff
<<
16
,
(
4
*
pdram_timing
->
trefi
)
<<
16
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
83
],
0xffff
,
(
2
*
pdram_timing
->
trefi
)
&
0xffff
);
if
((
timing_config
->
dram_type
==
LPDDR3
)
||
(
timing_config
->
dram_type
==
LPDDR4
))
{
tmp
=
get_pi_wrlat
(
pdram_timing
,
timing_config
);
tmp1
=
get_pi_todtoff_max
(
pdram_timing
,
timing_config
);
tmp
=
(
tmp
>
tmp1
)
?
(
tmp
-
tmp1
)
:
0
;
}
else
{
tmp
=
0
;
}
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
214
],
0x3f
<<
16
,
(
tmp
&
0x3f
)
<<
16
);
if
((
timing_config
->
dram_type
==
LPDDR3
)
||
(
timing_config
->
dram_type
==
LPDDR4
))
{
/* min_rl_preamble= cl+TDQSCK_MIN-1 */
tmp
=
pdram_timing
->
cl
+
get_pi_todtoff_min
(
pdram_timing
,
timing_config
)
-
1
;
/* todtoff_max */
tmp1
=
get_pi_todtoff_max
(
pdram_timing
,
timing_config
);
tmp
=
(
tmp
>
tmp1
)
?
(
tmp
-
tmp1
)
:
0
;
}
else
{
tmp
=
pdram_timing
->
cl
-
pdram_timing
->
cwl
;
}
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
215
],
0x3f
<<
8
,
(
tmp
&
0x3f
)
<<
8
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
275
],
0xff
<<
16
,
(
get_pi_tdfi_phy_rdlat
(
pdram_timing
,
timing_config
)
&
0xff
)
<<
16
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
277
],
0xffff
,
(
2
*
pdram_timing
->
trefi
)
&
0xffff
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
282
],
0xffff
,
(
2
*
pdram_timing
->
trefi
)
&
0xffff
);
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
283
],
20
*
pdram_timing
->
trefi
);
/* CTL_308 TDFI_CALVL_CAPTURE_F0:RW:16:10 */
tmp1
=
20000
/
(
1000000
/
pdram_timing
->
mhz
)
+
1
;
if
((
20000
%
(
1000000
/
pdram_timing
->
mhz
))
!=
0
)
tmp1
++
;
tmp
=
(
tmp1
>>
1
)
+
(
tmp1
%
2
)
+
5
;
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
308
],
0x3ff
<<
16
,
tmp
<<
16
);
/* CTL_308 TDFI_CALVL_CC_F0:RW:0:10 */
tmp
=
tmp
+
18
;
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
308
],
0x3ff
,
tmp
);
/* 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
(
tmp1
<
5
)
{
if
(
tmp1
==
0
)
tmp
=
0
;
else
tmp
=
tmp1
-
1
;
}
else
{
tmp
=
tmp1
-
5
;
}
}
else
{
tmp
=
tmp1
-
2
;
}
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
314
],
0xff
<<
8
,
tmp
<<
8
);
/* CTL_314 TDFI_RDCSLAT_F0:RW:0:8 */
if
((
timing_config
->
freq
<=
ENPER_CS_TRAINING_FREQ
)
&&
(
pdram_timing
->
cl
>=
5
))
tmp
=
pdram_timing
->
cl
-
5
;
else
tmp
=
pdram_timing
->
cl
-
2
;
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
314
],
0xff
,
tmp
);
}
}
static
void
gen_rk3399_ctl_params_f1
(
struct
timing_related_config
*
timing_config
,
struct
dram_timing_t
*
pdram_timing
)
{
uint32_t
i
;
uint32_t
tmp
,
tmp1
;
for
(
i
=
0
;
i
<
timing_config
->
ch_cnt
;
i
++
)
{
if
(
timing_config
->
dram_type
==
DDR3
)
{
tmp
=
((
700000
+
10
)
*
timing_config
->
freq
+
999
)
/
1000
;
tmp
+=
pdram_timing
->
txsnr
+
(
pdram_timing
->
tmrd
*
3
)
+
pdram_timing
->
tmod
+
pdram_timing
->
tzqinit
;
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
9
],
tmp
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
22
],
0xffff
<<
16
,
pdram_timing
->
tdllk
<<
16
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
34
],
0xffffff00
,
(
pdram_timing
->
tmod
<<
24
)
|
(
pdram_timing
->
tmrd
<<
16
)
|
(
pdram_timing
->
trtp
<<
8
));
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
60
],
0xffff
<<
16
,
(
pdram_timing
->
txsr
-
pdram_timing
->
trcd
)
<<
16
);
}
else
if
(
timing_config
->
dram_type
==
LPDDR4
)
{
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
9
],
pdram_timing
->
tinit1
+
pdram_timing
->
tinit3
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
34
],
0xffffff00
,
(
pdram_timing
->
tmrd
<<
24
)
|
(
pdram_timing
->
tmrd
<<
16
)
|
(
pdram_timing
->
trtp
<<
8
));
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
60
],
0xffff
<<
16
,
pdram_timing
->
txsr
<<
16
);
}
else
{
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
9
],
pdram_timing
->
tinit1
);
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
11
],
pdram_timing
->
tinit4
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
34
],
0xffffff00
,
(
pdram_timing
->
tmrd
<<
24
)
|
(
pdram_timing
->
tmrd
<<
16
)
|
(
pdram_timing
->
trtp
<<
8
));
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
60
],
0xffff
<<
16
,
pdram_timing
->
txsr
<<
16
);
}
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
10
],
pdram_timing
->
tinit3
);
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
12
],
pdram_timing
->
tinit5
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
24
],
(
0x7f
<<
8
),
((
pdram_timing
->
cl
*
2
)
<<
8
));
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
24
],
(
0x1f
<<
16
),
(
pdram_timing
->
cwl
<<
16
));
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
24
],
0x3f
<<
24
,
pdram_timing
->
al
<<
24
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
28
],
0xffffff00
,
(
pdram_timing
->
tras_min
<<
24
)
|
(
pdram_timing
->
trc
<<
16
)
|
(
pdram_timing
->
trrd
<<
8
));
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
29
],
0xffffff
,
(
pdram_timing
->
tfaw
<<
16
)
|
(
pdram_timing
->
trppb
<<
8
)
|
pdram_timing
->
twtr
);
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
35
],
(
pdram_timing
->
tcke
<<
24
)
|
pdram_timing
->
tras_max
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
36
],
0xff
,
max
(
1
,
pdram_timing
->
tckesr
));
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
39
],
(
0xff
<<
24
),
(
pdram_timing
->
trcd
<<
24
));
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
40
],
0x3f
,
pdram_timing
->
twr
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
42
],
0x1f
<<
24
,
pdram_timing
->
tmrz
<<
24
);
tmp
=
pdram_timing
->
tdal
?
pdram_timing
->
tdal
:
(
pdram_timing
->
twr
+
pdram_timing
->
trp
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
44
],
0xff
<<
8
,
tmp
<<
8
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
45
],
0xff
<<
8
,
pdram_timing
->
trp
<<
8
);
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
49
],
((
pdram_timing
->
trefi
-
8
)
<<
16
)
|
pdram_timing
->
trfc
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
52
],
0xffff
<<
16
,
pdram_timing
->
txp
<<
16
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
54
],
0xffff
,
pdram_timing
->
txpdll
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
55
],
0xff
<<
8
,
pdram_timing
->
tmrri
<<
8
);
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
57
],
(
pdram_timing
->
tmrwckel
<<
24
)
|
(
pdram_timing
->
tckehcs
<<
16
)
|
(
pdram_timing
->
tckelcs
<<
8
)
|
pdram_timing
->
tcscke
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
58
],
0xf
,
pdram_timing
->
tzqcke
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
61
],
0xffff
,
pdram_timing
->
txsnr
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
64
],
0xffff
<<
16
,
(
pdram_timing
->
tckehcmd
<<
24
)
|
(
pdram_timing
->
tckelcmd
<<
16
));
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
65
],
(
pdram_timing
->
tckelpd
<<
24
)
|
(
pdram_timing
->
tescke
<<
16
)
|
(
pdram_timing
->
tsr
<<
8
)
|
pdram_timing
->
tckckel
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
66
],
0xfff
,
(
pdram_timing
->
tcmdcke
<<
8
)
|
pdram_timing
->
tcsckeh
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
92
],
(
0xff
<<
24
),
(
pdram_timing
->
tcksre
<<
24
));
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
93
],
0xff
,
pdram_timing
->
tcksrx
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
108
],
(
0x1
<<
25
),
(
timing_config
->
dllbp
<<
25
));
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
125
],
(
pdram_timing
->
tvrcg_disable
<<
16
)
|
pdram_timing
->
tvrcg_enable
);
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
126
],
(
pdram_timing
->
tckfspx
<<
24
)
|
(
pdram_timing
->
tckfspe
<<
16
)
|
pdram_timing
->
tfc_long
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
127
],
0xffff
,
pdram_timing
->
tvref_long
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
134
],
0xffff
<<
16
,
pdram_timing
->
mr
[
0
]
<<
16
);
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
135
],
(
pdram_timing
->
mr
[
2
]
<<
16
)
|
pdram_timing
->
mr
[
1
]);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
138
],
0xffff
<<
16
,
pdram_timing
->
mr
[
3
]
<<
16
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
140
],
0xff
,
pdram_timing
->
mr11
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
148
],
0xffff
<<
16
,
pdram_timing
->
mr
[
0
]
<<
16
);
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
149
],
(
pdram_timing
->
mr
[
2
]
<<
16
)
|
pdram_timing
->
mr
[
1
]);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
152
],
0xffff
<<
16
,
pdram_timing
->
mr
[
3
]
<<
16
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
154
],
0xff
,
pdram_timing
->
mr11
);
if
(
timing_config
->
dram_type
==
LPDDR4
)
{
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
141
],
0xffff
,
pdram_timing
->
mr12
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
143
],
0xffff
,
pdram_timing
->
mr14
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
146
],
0xffff
,
pdram_timing
->
mr22
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
155
],
0xffff
,
pdram_timing
->
mr12
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
157
],
0xffff
,
pdram_timing
->
mr14
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
160
],
0xffff
,
pdram_timing
->
mr22
);
}
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
182
],
((
pdram_timing
->
tzqinit
/
2
)
<<
16
)
|
pdram_timing
->
tzqinit
);
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
183
],
(
pdram_timing
->
tzqcal
<<
16
)
|
pdram_timing
->
tzqcs
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
184
],
0x3f
,
pdram_timing
->
tzqlat
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
188
],
0xfff
,
pdram_timing
->
tzqreset
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
212
],
0xff
<<
16
,
pdram_timing
->
todton
<<
16
);
if
(
timing_config
->
odt
)
{
setbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
213
],
(
1
<<
24
));
if
(
timing_config
->
freq
<
400
)
tmp
=
4
<<
24
;
else
tmp
=
8
<<
24
;
}
else
{
clrbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
213
],
(
1
<<
24
));
tmp
=
2
<<
24
;
}
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
217
],
0x1f
<<
24
,
tmp
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
221
],
0xf
<<
24
,
(
pdram_timing
->
tdqsck_max
<<
24
));
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
222
],
0x3
,
pdram_timing
->
tdqsck
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
291
],
0xffff
,
(
get_wrlat_adj
(
timing_config
->
dram_type
,
pdram_timing
->
cwl
)
<<
8
)
|
get_rdlat_adj
(
timing_config
->
dram_type
,
pdram_timing
->
cl
));
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
84
],
0xffff
,
(
4
*
pdram_timing
->
trefi
)
&
0xffff
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
84
],
0xffff
<<
16
,
((
2
*
pdram_timing
->
trefi
)
&
0xffff
)
<<
16
);
if
((
timing_config
->
dram_type
==
LPDDR3
)
||
(
timing_config
->
dram_type
==
LPDDR4
))
{
tmp
=
get_pi_wrlat
(
pdram_timing
,
timing_config
);
tmp1
=
get_pi_todtoff_max
(
pdram_timing
,
timing_config
);
tmp
=
(
tmp
>
tmp1
)
?
(
tmp
-
tmp1
)
:
0
;
}
else
{
tmp
=
0
;
}
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
214
],
0x3f
<<
24
,
(
tmp
&
0x3f
)
<<
24
);
if
((
timing_config
->
dram_type
==
LPDDR3
)
||
(
timing_config
->
dram_type
==
LPDDR4
))
{
/* min_rl_preamble= cl+TDQSCK_MIN-1 */
tmp
=
pdram_timing
->
cl
+
get_pi_todtoff_min
(
pdram_timing
,
timing_config
)
-
1
;
/* todtoff_max */
tmp1
=
get_pi_todtoff_max
(
pdram_timing
,
timing_config
);
tmp
=
(
tmp
>
tmp1
)
?
(
tmp
-
tmp1
)
:
0
;
}
else
{
tmp
=
pdram_timing
->
cl
-
pdram_timing
->
cwl
;
}
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
215
],
0x3f
<<
16
,
(
tmp
&
0x3f
)
<<
16
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
275
],
0xff
<<
24
,
(
get_pi_tdfi_phy_rdlat
(
pdram_timing
,
timing_config
)
&
0xff
)
<<
24
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
284
],
0xffff
<<
16
,
((
2
*
pdram_timing
->
trefi
)
&
0xffff
)
<<
16
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
289
],
0xffff
,
(
2
*
pdram_timing
->
trefi
)
&
0xffff
);
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
290
],
20
*
pdram_timing
->
trefi
);
/* CTL_309 TDFI_CALVL_CAPTURE_F1:RW:16:10 */
tmp1
=
20000
/
(
1000000
/
pdram_timing
->
mhz
)
+
1
;
if
((
20000
%
(
1000000
/
pdram_timing
->
mhz
))
!=
0
)
tmp1
++
;
tmp
=
(
tmp1
>>
1
)
+
(
tmp1
%
2
)
+
5
;
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
309
],
0x3ff
<<
16
,
tmp
<<
16
);
/* CTL_309 TDFI_CALVL_CC_F1:RW:0:10 */
tmp
=
tmp
+
18
;
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
309
],
0x3ff
,
tmp
);
/* 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
(
tmp1
<
5
)
{
if
(
tmp1
==
0
)
tmp
=
0
;
else
tmp
=
tmp1
-
1
;
}
else
{
tmp
=
tmp1
-
5
;
}
}
else
{
tmp
=
tmp1
-
2
;
}
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
314
],
0xff
<<
24
,
tmp
<<
24
);
/* CTL_314 TDFI_RDCSLAT_F1:RW:16:8 */
if
((
timing_config
->
freq
<=
ENPER_CS_TRAINING_FREQ
)
&&
(
pdram_timing
->
cl
>=
5
))
tmp
=
pdram_timing
->
cl
-
5
;
else
tmp
=
pdram_timing
->
cl
-
2
;
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
314
],
0xff
<<
16
,
tmp
<<
16
);
}
}
static
void
gen_rk3399_ctl_params
(
struct
timing_related_config
*
timing_config
,
struct
dram_timing_t
*
pdram_timing
,
uint32_t
fn
)
{
if
(
fn
==
0
)
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
)
setbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
305
],
1
<<
16
);
if
(
tmp0
)
setbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
70
],
tmp0
);
if
(
tmp1
)
setbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
71
],
tmp1
);
}
#endif
}
static
void
gen_rk3399_pi_params_f0
(
struct
timing_related_config
*
timing_config
,
struct
dram_timing_t
*
pdram_timing
)
{
uint32_t
tmp
,
tmp1
,
tmp2
;
uint32_t
i
;
for
(
i
=
0
;
i
<
timing_config
->
ch_cnt
;
i
++
)
{
/* PI_02 PI_TDFI_PHYMSTR_MAX_F0:RW:0:32 */
tmp
=
4
*
pdram_timing
->
trefi
;
write_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
2
],
tmp
);
/* PI_03 PI_TDFI_PHYMSTR_RESP_F0:RW:0:16 */
tmp
=
2
*
pdram_timing
->
trefi
;
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
3
],
0xffff
,
tmp
);
/* PI_07 PI_TDFI_PHYUPD_RESP_F0:RW:16:16 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
7
],
0xffff
<<
16
,
tmp
<<
16
);
/* PI_42 PI_TDELAY_RDWR_2_BUS_IDLE_F0:RW:0:8 */
if
(
timing_config
->
dram_type
==
LPDDR4
)
tmp
=
2
;
else
tmp
=
0
;
tmp
=
(
pdram_timing
->
bl
/
2
)
+
4
+
(
get_pi_rdlat_adj
(
pdram_timing
)
-
2
)
+
tmp
+
get_pi_tdfi_phy_rdlat
(
pdram_timing
,
timing_config
);
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
42
],
0xff
,
tmp
);
/* PI_43 PI_WRLAT_F0:RW:0:5 */
if
(
timing_config
->
dram_type
==
LPDDR3
)
{
tmp
=
get_pi_wrlat
(
pdram_timing
,
timing_config
);
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
43
],
0x1f
,
tmp
);
}
/* PI_43 PI_ADDITIVE_LAT_F0:RW:8:6 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
43
],
0x3f
<<
8
,
PI_ADD_LATENCY
<<
8
);
/* PI_43 PI_CASLAT_LIN_F0:RW:16:7 */
tmp
=
pdram_timing
->
cl
*
2
;
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
43
],
0x7f
<<
16
,
tmp
<<
16
);
/* PI_46 PI_TREF_F0:RW:16:16 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
46
],
0xffff
<<
16
,
pdram_timing
->
trefi
<<
16
);
/* PI_46 PI_TRFC_F0:RW:0:10 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
46
],
0x3ff
,
pdram_timing
->
trfc
);
/* PI_66 PI_TODTL_2CMD_F0:RW:24:8 */
if
(
timing_config
->
dram_type
==
LPDDR3
)
{
tmp
=
get_pi_todtoff_max
(
pdram_timing
,
timing_config
);
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
66
],
0xff
<<
24
,
tmp
<<
24
);
}
/* PI_72 PI_WR_TO_ODTH_F0:RW:16:6 */
if
((
timing_config
->
dram_type
==
LPDDR3
)
||
(
timing_config
->
dram_type
==
LPDDR4
))
{
tmp1
=
get_pi_wrlat
(
pdram_timing
,
timing_config
);
tmp2
=
get_pi_todtoff_max
(
pdram_timing
,
timing_config
);
if
(
tmp1
>
tmp2
)
tmp
=
tmp1
-
tmp2
;
else
tmp
=
0
;
}
else
if
(
timing_config
->
dram_type
==
DDR3
)
{
tmp
=
0
;
}
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
72
],
0x3f
<<
16
,
tmp
<<
16
);
/* PI_73 PI_RD_TO_ODTH_F0:RW:8:6 */
if
((
timing_config
->
dram_type
==
LPDDR3
)
||
(
timing_config
->
dram_type
==
LPDDR4
))
{
/* min_rl_preamble= cl+TDQSCK_MIN-1 */
tmp1
=
pdram_timing
->
cl
+
get_pi_todtoff_min
(
pdram_timing
,
timing_config
)
-
1
;
/* todtoff_max */
tmp2
=
get_pi_todtoff_max
(
pdram_timing
,
timing_config
);
if
(
tmp1
>
tmp2
)
tmp
=
tmp1
-
tmp2
;
else
tmp
=
0
;
}
else
if
(
timing_config
->
dram_type
==
DDR3
)
{
tmp
=
pdram_timing
->
cl
-
pdram_timing
->
cwl
;
}
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
73
],
0x3f
<<
8
,
tmp
<<
8
);
/* PI_89 PI_RDLAT_ADJ_F0:RW:16:8 */
tmp
=
get_pi_rdlat_adj
(
pdram_timing
);
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
89
],
0xff
<<
16
,
tmp
<<
16
);
/* PI_90 PI_WRLAT_ADJ_F0:RW:16:8 */
tmp
=
get_pi_wrlat_adj
(
pdram_timing
,
timing_config
);
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
90
],
0xff
<<
16
,
tmp
<<
16
);
/* PI_91 PI_TDFI_WRCSLAT_F0:RW:16:8 */
tmp1
=
tmp
;
if
(
tmp1
<
5
)
{
if
(
tmp1
==
0
)
tmp
=
0
;
else
tmp
=
tmp1
-
1
;
}
else
{
tmp
=
tmp1
-
5
;
}
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
91
],
0xff
<<
16
,
tmp
<<
16
);
/* PI_95 PI_TDFI_CALVL_CAPTURE_F0:RW:16:10 */
tmp1
=
20000
/
(
1000000
/
pdram_timing
->
mhz
)
+
1
;
if
((
20000
%
(
1000000
/
pdram_timing
->
mhz
))
!=
0
)
tmp1
++
;
tmp
=
(
tmp1
>>
1
)
+
(
tmp1
%
2
)
+
5
;
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
95
],
0x3ff
<<
16
,
tmp
<<
16
);
/* PI_95 PI_TDFI_CALVL_CC_F0:RW:0:10 */
tmp
=
tmp
+
18
;
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
95
],
0x3ff
,
tmp
);
/* PI_102 PI_TMRZ_F0:RW:8:5 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
102
],
0x1f
<<
8
,
pdram_timing
->
tmrz
<<
8
);
/* PI_111 PI_TDFI_CALVL_STROBE_F0:RW:8:4 */
tmp1
=
2
*
1000
/
(
1000000
/
pdram_timing
->
mhz
);
if
((
2
*
1000
%
(
1000000
/
pdram_timing
->
mhz
))
!=
0
)
tmp1
++
;
/* pi_tdfi_calvl_strobe=tds_train+5 */
tmp
=
tmp1
+
5
;
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
111
],
0xf
<<
8
,
tmp
<<
8
);
/* PI_116 PI_TCKEHDQS_F0:RW:16:6 */
tmp
=
10000
/
(
1000000
/
pdram_timing
->
mhz
);
if
((
10000
%
(
1000000
/
pdram_timing
->
mhz
))
!=
0
)
tmp
++
;
if
(
pdram_timing
->
mhz
<=
100
)
tmp
=
tmp
+
1
;
else
tmp
=
tmp
+
8
;
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
116
],
0x3f
<<
16
,
tmp
<<
16
);
/* PI_125 PI_MR1_DATA_F0_0:RW+:8:16 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
125
],
0xffff
<<
8
,
pdram_timing
->
mr
[
1
]
<<
8
);
/* PI_133 PI_MR1_DATA_F0_1:RW+:0:16 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
133
],
0xffff
,
pdram_timing
->
mr
[
1
]);
/* PI_140 PI_MR1_DATA_F0_2:RW+:16:16 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
140
],
0xffff
<<
16
,
pdram_timing
->
mr
[
1
]
<<
16
);
/* PI_148 PI_MR1_DATA_F0_3:RW+:0:16 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
148
],
0xffff
,
pdram_timing
->
mr
[
1
]);
/* PI_126 PI_MR2_DATA_F0_0:RW+:0:16 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
126
],
0xffff
,
pdram_timing
->
mr
[
2
]);
/* PI_133 PI_MR2_DATA_F0_1:RW+:16:16 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
133
],
0xffff
<<
16
,
pdram_timing
->
mr
[
2
]
<<
16
);
/* PI_141 PI_MR2_DATA_F0_2:RW+:0:16 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
141
],
0xffff
,
pdram_timing
->
mr
[
2
]);
/* PI_148 PI_MR2_DATA_F0_3:RW+:16:16 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
148
],
0xffff
<<
16
,
pdram_timing
->
mr
[
2
]
<<
16
);
/* PI_156 PI_TFC_F0:RW:0:10 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
156
],
0x3ff
,
pdram_timing
->
trfc
);
/* PI_158 PI_TWR_F0:RW:24:6 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
158
],
0x3f
<<
24
,
pdram_timing
->
twr
<<
24
);
/* PI_158 PI_TWTR_F0:RW:16:6 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
158
],
0x3f
<<
16
,
pdram_timing
->
twtr
<<
16
);
/* PI_158 PI_TRCD_F0:RW:8:8 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
158
],
0xff
<<
8
,
pdram_timing
->
trcd
<<
8
);
/* PI_158 PI_TRP_F0:RW:0:8 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
158
],
0xff
,
pdram_timing
->
trp
);
/* PI_157 PI_TRTP_F0:RW:24:8 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
157
],
0xff
<<
24
,
pdram_timing
->
trtp
<<
24
);
/* PI_159 PI_TRAS_MIN_F0:RW:24:8 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
159
],
0xff
<<
24
,
pdram_timing
->
tras_min
<<
24
);
/* PI_159 PI_TRAS_MAX_F0:RW:0:17 */
tmp
=
pdram_timing
->
tras_max
*
99
/
100
;
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
159
],
0x1ffff
,
tmp
);
/* PI_160 PI_TMRD_F0:RW:16:6 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
160
],
0x3f
<<
16
,
pdram_timing
->
tmrd
<<
16
);
/*PI_160 PI_TDQSCK_MAX_F0:RW:0:4 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
160
],
0xf
,
pdram_timing
->
tdqsck_max
);
/* PI_187 PI_TDFI_CTRLUPD_MAX_F0:RW:8:16 */
tmp
=
2
*
pdram_timing
->
trefi
;
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
187
],
0xffff
<<
8
,
tmp
<<
8
);
/* PI_188 PI_TDFI_CTRLUPD_INTERVAL_F0:RW:0:32 */
tmp
=
20
*
pdram_timing
->
trefi
;
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
188
],
0xffffffff
,
tmp
);
}
}
static
void
gen_rk3399_pi_params_f1
(
struct
timing_related_config
*
timing_config
,
struct
dram_timing_t
*
pdram_timing
)
{
uint32_t
tmp
,
tmp1
,
tmp2
;
uint32_t
i
;
for
(
i
=
0
;
i
<
timing_config
->
ch_cnt
;
i
++
)
{
/* PI_04 PI_TDFI_PHYMSTR_MAX_F1:RW:0:32 */
tmp
=
4
*
pdram_timing
->
trefi
;
write_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
4
],
tmp
);
/* PI_05 PI_TDFI_PHYMSTR_RESP_F1:RW:0:16 */
tmp
=
2
*
pdram_timing
->
trefi
;
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
5
],
0xffff
,
tmp
);
/* PI_12 PI_TDFI_PHYUPD_RESP_F1:RW:0:16 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
12
],
0xffff
,
tmp
);
/* PI_42 PI_TDELAY_RDWR_2_BUS_IDLE_F1:RW:8:8 */
if
(
timing_config
->
dram_type
==
LPDDR4
)
tmp
=
2
;
else
tmp
=
0
;
tmp
=
(
pdram_timing
->
bl
/
2
)
+
4
+
(
get_pi_rdlat_adj
(
pdram_timing
)
-
2
)
+
tmp
+
get_pi_tdfi_phy_rdlat
(
pdram_timing
,
timing_config
);
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
42
],
0xff
<<
8
,
tmp
<<
8
);
/* PI_43 PI_WRLAT_F1:RW:24:5 */
if
(
timing_config
->
dram_type
==
LPDDR3
)
{
tmp
=
get_pi_wrlat
(
pdram_timing
,
timing_config
);
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
43
],
0x1f
<<
24
,
tmp
<<
24
);
}
/* PI_44 PI_ADDITIVE_LAT_F1:RW:0:6 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
44
],
0x3f
,
PI_ADD_LATENCY
);
/* PI_44 PI_CASLAT_LIN_F1:RW:8:7:=0x18 */
tmp
=
pdram_timing
->
cl
*
2
;
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
44
],
0x7f
<<
8
,
tmp
<<
8
);
/* PI_47 PI_TREF_F1:RW:16:16 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
47
],
0xffff
<<
16
,
pdram_timing
->
trefi
<<
16
);
/* PI_47 PI_TRFC_F1:RW:0:10 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
47
],
0x3ff
,
pdram_timing
->
trfc
);
/* PI_67 PI_TODTL_2CMD_F1:RW:8:8 */
if
(
timing_config
->
dram_type
==
LPDDR3
)
{
tmp
=
get_pi_todtoff_max
(
pdram_timing
,
timing_config
);
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
67
],
0xff
<<
8
,
tmp
<<
8
);
}
/* PI_72 PI_WR_TO_ODTH_F1:RW:24:6 */
if
((
timing_config
->
dram_type
==
LPDDR3
)
||
(
timing_config
->
dram_type
==
LPDDR4
))
{
tmp1
=
get_pi_wrlat
(
pdram_timing
,
timing_config
);
tmp2
=
get_pi_todtoff_max
(
pdram_timing
,
timing_config
);
if
(
tmp1
>
tmp2
)
tmp
=
tmp1
-
tmp2
;
else
tmp
=
0
;
}
else
if
(
timing_config
->
dram_type
==
DDR3
)
{
tmp
=
0
;
}
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
72
],
0x3f
<<
24
,
tmp
<<
24
);
/* PI_73 PI_RD_TO_ODTH_F1:RW:16:6 */
if
((
timing_config
->
dram_type
==
LPDDR3
)
||
(
timing_config
->
dram_type
==
LPDDR4
))
{
/* min_rl_preamble= cl+TDQSCK_MIN-1 */
tmp1
=
pdram_timing
->
cl
+
get_pi_todtoff_min
(
pdram_timing
,
timing_config
)
-
1
;
/* todtoff_max */
tmp2
=
get_pi_todtoff_max
(
pdram_timing
,
timing_config
);
if
(
tmp1
>
tmp2
)
tmp
=
tmp1
-
tmp2
;
else
tmp
=
0
;
}
else
if
(
timing_config
->
dram_type
==
DDR3
)
{
tmp
=
pdram_timing
->
cl
-
pdram_timing
->
cwl
;
}
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
73
],
0x3f
<<
16
,
tmp
<<
16
);
/*P I_89 PI_RDLAT_ADJ_F1:RW:24:8 */
tmp
=
get_pi_rdlat_adj
(
pdram_timing
);
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
89
],
0xff
<<
24
,
tmp
<<
24
);
/* PI_90 PI_WRLAT_ADJ_F1:RW:24:8 */
tmp
=
get_pi_wrlat_adj
(
pdram_timing
,
timing_config
);
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
90
],
0xff
<<
24
,
tmp
<<
24
);
/* PI_91 PI_TDFI_WRCSLAT_F1:RW:24:8 */
tmp1
=
tmp
;
if
(
tmp1
<
5
)
{
if
(
tmp1
==
0
)
tmp
=
0
;
else
tmp
=
tmp1
-
1
;
}
else
{
tmp
=
tmp1
-
5
;
}
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
91
],
0xff
<<
24
,
tmp
<<
24
);
/*PI_96 PI_TDFI_CALVL_CAPTURE_F1:RW:16:10 */
/* tadr=20ns */
tmp1
=
20000
/
(
1000000
/
pdram_timing
->
mhz
)
+
1
;
if
((
20000
%
(
1000000
/
pdram_timing
->
mhz
))
!=
0
)
tmp1
++
;
tmp
=
(
tmp1
>>
1
)
+
(
tmp1
%
2
)
+
5
;
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
96
],
0x3ff
<<
16
,
tmp
<<
16
);
/* PI_96 PI_TDFI_CALVL_CC_F1:RW:0:10 */
tmp
=
tmp
+
18
;
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
96
],
0x3ff
,
tmp
);
/*PI_103 PI_TMRZ_F1:RW:0:5 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
103
],
0x1f
,
pdram_timing
->
tmrz
);
/*PI_111 PI_TDFI_CALVL_STROBE_F1:RW:16:4 */
/* tds_train=ceil(2/ns) */
tmp1
=
2
*
1000
/
(
1000000
/
pdram_timing
->
mhz
);
if
((
2
*
1000
%
(
1000000
/
pdram_timing
->
mhz
))
!=
0
)
tmp1
++
;
/* pi_tdfi_calvl_strobe=tds_train+5 */
tmp
=
tmp1
+
5
;
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
111
],
0xf
<<
16
,
tmp
<<
16
);
/* PI_116 PI_TCKEHDQS_F1:RW:24:6 */
tmp
=
10000
/
(
1000000
/
pdram_timing
->
mhz
);
if
((
10000
%
(
1000000
/
pdram_timing
->
mhz
))
!=
0
)
tmp
++
;
if
(
pdram_timing
->
mhz
<=
100
)
tmp
=
tmp
+
1
;
else
tmp
=
tmp
+
8
;
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
116
],
0x3f
<<
24
,
tmp
<<
24
);
/* PI_128 PI_MR1_DATA_F1_0:RW+:0:16 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
128
],
0xffff
,
pdram_timing
->
mr
[
1
]);
/* PI_135 PI_MR1_DATA_F1_1:RW+:8:16 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
135
],
0xffff
<<
8
,
pdram_timing
->
mr
[
1
]
<<
8
);
/* PI_143 PI_MR1_DATA_F1_2:RW+:0:16 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
143
],
0xffff
,
pdram_timing
->
mr
[
1
]);
/* PI_150 PI_MR1_DATA_F1_3:RW+:8:16 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
150
],
0xffff
<<
8
,
pdram_timing
->
mr
[
1
]
<<
8
);
/* PI_128 PI_MR2_DATA_F1_0:RW+:16:16 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
128
],
0xffff
<<
16
,
pdram_timing
->
mr
[
2
]
<<
16
);
/* PI_136 PI_MR2_DATA_F1_1:RW+:0:16 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
136
],
0xffff
,
pdram_timing
->
mr
[
2
]);
/* PI_143 PI_MR2_DATA_F1_2:RW+:16:16 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
143
],
0xffff
<<
16
,
pdram_timing
->
mr
[
2
]
<<
16
);
/* PI_151 PI_MR2_DATA_F1_3:RW+:0:16 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
151
],
0xffff
,
pdram_timing
->
mr
[
2
]);
/* PI_156 PI_TFC_F1:RW:16:10 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
156
],
0x3ff
<<
16
,
pdram_timing
->
trfc
<<
16
);
/* PI_162 PI_TWR_F1:RW:8:6 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
162
],
0x3f
<<
8
,
pdram_timing
->
twr
<<
8
);
/* PI_162 PI_TWTR_F1:RW:0:6 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
162
],
0x3f
,
pdram_timing
->
twtr
);
/* PI_161 PI_TRCD_F1:RW:24:8 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
161
],
0xff
<<
24
,
pdram_timing
->
trcd
<<
24
);
/* PI_161 PI_TRP_F1:RW:16:8 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
161
],
0xff
<<
16
,
pdram_timing
->
trp
<<
16
);
/* PI_161 PI_TRTP_F1:RW:8:8 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
161
],
0xff
<<
8
,
pdram_timing
->
trtp
<<
8
);
/* PI_163 PI_TRAS_MIN_F1:RW:24:8 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
163
],
0xff
<<
24
,
pdram_timing
->
tras_min
<<
24
);
/* PI_163 PI_TRAS_MAX_F1:RW:0:17 */
tmp
=
pdram_timing
->
tras_max
*
99
/
100
;
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
163
],
0x1ffff
,
tmp
);
/* PI_164 PI_TMRD_F1:RW:16:6 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
164
],
0x3f
<<
16
,
pdram_timing
->
tmrd
<<
16
);
/* PI_164 PI_TDQSCK_MAX_F1:RW:0:4 */
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
164
],
0xf
,
pdram_timing
->
tdqsck_max
);
/* PI_189 PI_TDFI_CTRLUPD_MAX_F1:RW:0:16 */
tmp
=
2
*
pdram_timing
->
trefi
;
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
189
],
0xffff
,
tmp
);
/* PI_190 PI_TDFI_CTRLUPD_INTERVAL_F1:RW:0:32 */
tmp
=
20
*
pdram_timing
->
trefi
;
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
190
],
0xffffffff
,
tmp
);
}
}
static
void
gen_rk3399_pi_params
(
struct
timing_related_config
*
timing_config
,
struct
dram_timing_t
*
pdram_timing
,
uint32_t
fn
)
{
if
(
fn
==
0
)
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
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
80
],
3
<<
24
,
2
<<
24
);
#endif
#if EN_CA_TRAINING
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
100
],
3
<<
8
,
2
<<
8
);
#endif
#if EN_WRITE_LEVELING
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
60
],
3
<<
8
,
2
<<
8
);
#endif
#if EN_READ_LEVELING
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
80
],
3
<<
16
,
2
<<
16
);
#endif
#if EN_WDQ_LEVELING
clrsetbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
124
],
3
<<
16
,
2
<<
16
);
#endif
}
#endif
}
static
void
gen_rk3399_set_odt
(
uint32_t
odt_en
)
{
uint32_t
drv_odt_val
;
uint32_t
i
;
for
(
i
=
0
;
i
<
rk3399_dram_status
.
timing_config
.
ch_cnt
;
i
++
)
{
drv_odt_val
=
(
odt_en
|
(
0
<<
1
)
|
(
0
<<
2
))
<<
16
;
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
5
],
0x7
<<
16
,
drv_odt_val
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
133
],
0x7
<<
16
,
drv_odt_val
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
261
],
0x7
<<
16
,
drv_odt_val
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
389
],
0x7
<<
16
,
drv_odt_val
);
drv_odt_val
=
(
odt_en
|
(
0
<<
1
)
|
(
0
<<
2
))
<<
24
;
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
6
],
0x7
<<
24
,
drv_odt_val
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
134
],
0x7
<<
24
,
drv_odt_val
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
262
],
0x7
<<
24
,
drv_odt_val
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
390
],
0x7
<<
24
,
drv_odt_val
);
}
}
static
void
gen_rk3399_set_ds_odt
(
struct
timing_related_config
*
timing_config
,
struct
drv_odt_lp_config
*
drv_config
)
{
uint32_t
i
,
drv_odt_val
;
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
);
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 */
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
6
],
0xffffff
,
drv_odt_val
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
134
],
0xffffff
,
drv_odt_val
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
262
],
0xffffff
,
drv_odt_val
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
390
],
0xffffff
,
drv_odt_val
);
/* DQS drv odt set */
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
7
],
0xffffff
,
drv_odt_val
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
135
],
0xffffff
,
drv_odt_val
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
263
],
0xffffff
,
drv_odt_val
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
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
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
544
],
0xff
,
drv_odt_val
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
672
],
0xff
,
drv_odt_val
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
800
],
0xff
,
drv_odt_val
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
928
],
0xff
,
drv_odt_val
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
937
],
0xff
,
drv_odt_val
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
935
],
0xff
,
drv_odt_val
);
drv_odt_val
=
drv_config
->
phy_side_ck_cs_drv
|
(
drv_config
->
phy_side_ck_cs_drv
<<
4
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
929
],
0xff
,
drv_odt_val
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
939
],
0xff
,
drv_odt_val
);
}
}
static
void
gen_rk3399_phy_params
(
struct
timing_related_config
*
timing_config
,
struct
drv_odt_lp_config
*
drv_config
,
struct
dram_timing_t
*
pdram_timing
,
uint32_t
fn
)
{
uint32_t
tmp
,
i
,
div
,
j
;
uint32_t
mem_delay_ps
,
pad_delay_ps
,
total_delay_ps
,
delay_frac_ps
;
uint32_t
trpre_min_ps
,
gate_delay_ps
,
gate_delay_frac_ps
;
uint32_t
ie_enable
,
tsel_enable
,
cas_lat
,
rddata_en_ie_dly
,
tsel_adder
;
uint32_t
extra_adder
,
delta
,
hs_offset
;
for
(
i
=
0
;
i
<
timing_config
->
ch_cnt
;
i
++
)
{
pad_delay_ps
=
PI_PAD_DELAY_PS_VALUE
;
ie_enable
=
PI_IE_ENABLE_VALUE
;
tsel_enable
=
PI_TSEL_ENABLE_VALUE
;
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
896
],
(
0x3
<<
8
)
|
1
,
fn
<<
8
);
/* PHY_LOW_FREQ_SEL */
/* DENALI_PHY_913 1bit offset_0 */
if
(
timing_config
->
freq
>
400
)
clrbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
913
],
1
);
else
setbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
913
],
1
);
/* PHY_RPTR_UPDATE_x */
/* DENALI_PHY_87/215/343/471 4bit offset_16 */
tmp
=
2500
/
(
1000000
/
pdram_timing
->
mhz
)
+
3
;
if
((
2500
%
(
1000000
/
pdram_timing
->
mhz
))
!=
0
)
tmp
++
;
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
87
],
0xf
<<
16
,
tmp
<<
16
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
215
],
0xf
<<
16
,
tmp
<<
16
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
343
],
0xf
<<
16
,
tmp
<<
16
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
471
],
0xf
<<
16
,
tmp
<<
16
);
/* PHY_PLL_CTRL */
/* 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
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
911
],
0x1fff
,
tmp
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
919
],
0x1fff
,
tmp
);
/* PHY_PLL_CTRL_CA */
/* 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
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
911
],
0x1fff
<<
16
,
tmp
<<
16
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
919
],
0x1fff
<<
16
,
tmp
<<
16
);
/* PHY_TCKSRE_WAIT */
/* DENALI_PHY_922 4bits offset_24 */
if
(
pdram_timing
->
mhz
<=
400
)
tmp
=
1
;
else
if
(
pdram_timing
->
mhz
<=
800
)
tmp
=
3
;
else
if
(
pdram_timing
->
mhz
<=
1000
)
tmp
=
4
;
else
tmp
=
5
;
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
922
],
0xf
<<
24
,
tmp
<<
24
);
/* PHY_CAL_CLK_SELECT_0:RW8:3 */
div
=
pdram_timing
->
mhz
/
(
2
*
20
);
for
(
j
=
2
,
tmp
=
1
;
j
<=
128
;
j
<<=
1
,
tmp
++
)
{
if
(
div
<
j
)
break
;
}
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
947
],
0x7
<<
8
,
tmp
<<
8
);
setbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
927
],
(
1
<<
22
));
if
(
timing_config
->
dram_type
==
DDR3
)
{
mem_delay_ps
=
0
;
trpre_min_ps
=
1000
;
}
else
if
(
timing_config
->
dram_type
==
LPDDR4
)
{
mem_delay_ps
=
1500
;
trpre_min_ps
=
900
;
}
else
if
(
timing_config
->
dram_type
==
LPDDR3
)
{
mem_delay_ps
=
2500
;
trpre_min_ps
=
900
;
}
else
{
ERROR
(
"gen_rk3399_phy_params:dramtype unsupport
\n
"
);
return
;
}
total_delay_ps
=
mem_delay_ps
+
pad_delay_ps
;
delay_frac_ps
=
1000
*
total_delay_ps
/
(
1000000
/
pdram_timing
->
mhz
);
gate_delay_ps
=
delay_frac_ps
+
1000
-
(
trpre_min_ps
/
2
);
gate_delay_frac_ps
=
gate_delay_ps
-
gate_delay_ps
/
1000
*
1000
;
tmp
=
gate_delay_frac_ps
*
0x200
/
1000
;
/* PHY_RDDQS_GATE_BYPASS_SLAVE_DELAY */
/* DENALI_PHY_2/130/258/386 10bits offset_0 */
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
2
],
0x2ff
,
tmp
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
130
],
0x2ff
,
tmp
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
258
],
0x2ff
,
tmp
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
386
],
0x2ff
,
tmp
);
/* PHY_RDDQS_GATE_SLAVE_DELAY */
/* DENALI_PHY_77/205/333/461 10bits offset_16 */
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
77
],
0x2ff
<<
16
,
tmp
<<
16
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
205
],
0x2ff
<<
16
,
tmp
<<
16
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
333
],
0x2ff
<<
16
,
tmp
<<
16
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
461
],
0x2ff
<<
16
,
tmp
<<
16
);
tmp
=
gate_delay_ps
/
1000
;
/* PHY_LP4_BOOT_RDDQS_LATENCY_ADJUST */
/* DENALI_PHY_10/138/266/394 4bit offset_0 */
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
10
],
0xf
,
tmp
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
138
],
0xf
,
tmp
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
266
],
0xf
,
tmp
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
394
],
0xf
,
tmp
);
/* PHY_RDDQS_LATENCY_ADJUST */
/* DENALI_PHY_78/206/334/462 4bits offset_0 */
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
78
],
0xf
,
tmp
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
206
],
0xf
,
tmp
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
334
],
0xf
,
tmp
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
462
],
0xf
,
tmp
);
/* PHY_GTLVL_LAT_ADJ_START */
/* DENALI_PHY_80/208/336/464 4bits offset_16 */
tmp
=
delay_frac_ps
/
1000
;
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
80
],
0xf
<<
16
,
tmp
<<
16
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
208
],
0xf
<<
16
,
tmp
<<
16
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
336
],
0xf
<<
16
,
tmp
<<
16
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
464
],
0xf
<<
16
,
tmp
<<
16
);
cas_lat
=
pdram_timing
->
cl
+
PI_ADD_LATENCY
;
rddata_en_ie_dly
=
ie_enable
/
(
1000000
/
pdram_timing
->
mhz
);
if
((
ie_enable
%
(
1000000
/
pdram_timing
->
mhz
))
!=
0
)
rddata_en_ie_dly
++
;
rddata_en_ie_dly
=
rddata_en_ie_dly
-
1
;
tsel_adder
=
tsel_enable
/
(
1000000
/
pdram_timing
->
mhz
);
if
((
tsel_enable
%
(
1000000
/
pdram_timing
->
mhz
))
!=
0
)
tsel_adder
++
;
if
(
rddata_en_ie_dly
>
tsel_adder
)
extra_adder
=
rddata_en_ie_dly
-
tsel_adder
;
else
extra_adder
=
0
;
delta
=
cas_lat
-
rddata_en_ie_dly
;
if
(
PI_REGS_DIMM_SUPPORT
&&
PI_DOUBLEFREEK
)
hs_offset
=
2
;
else
hs_offset
=
1
;
if
(
rddata_en_ie_dly
>
(
cas_lat
-
1
-
hs_offset
))
{
tmp
=
0
;
}
else
{
if
((
delta
==
2
)
||
(
delta
==
1
))
tmp
=
rddata_en_ie_dly
-
0
-
extra_adder
;
else
tmp
=
extra_adder
;
}
/* PHY_LP4_BOOT_RDDATA_EN_TSEL_DLY */
/* DENALI_PHY_9/137/265/393 4bit offset_16 */
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
9
],
0xf
<<
16
,
tmp
<<
16
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
137
],
0xf
<<
16
,
tmp
<<
16
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
265
],
0xf
<<
16
,
tmp
<<
16
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
393
],
0xf
<<
16
,
tmp
<<
16
);
/* PHY_RDDATA_EN_TSEL_DLY */
/* DENALI_PHY_86/214/342/470 4bit offset_0 */
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
86
],
0xf
,
tmp
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
214
],
0xf
,
tmp
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
342
],
0xf
,
tmp
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
470
],
0xf
,
tmp
);
if
(
tsel_adder
>
rddata_en_ie_dly
)
extra_adder
=
tsel_adder
-
rddata_en_ie_dly
;
else
extra_adder
=
0
;
if
(
rddata_en_ie_dly
>
(
cas_lat
-
1
-
hs_offset
))
tmp
=
tsel_adder
;
else
tmp
=
rddata_en_ie_dly
-
0
+
extra_adder
;
/* PHY_LP4_BOOT_RDDATA_EN_DLY */
/* DENALI_PHY_9/137/265/393 4bit offset_8 */
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
9
],
0xf
<<
8
,
tmp
<<
8
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
137
],
0xf
<<
8
,
tmp
<<
8
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
265
],
0xf
<<
8
,
tmp
<<
8
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
393
],
0xf
<<
8
,
tmp
<<
8
);
/* PHY_RDDATA_EN_DLY */
/* DENALI_PHY_85/213/341/469 4bit offset_24 */
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
85
],
0xf
<<
24
,
tmp
<<
24
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
213
],
0xf
<<
24
,
tmp
<<
24
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
341
],
0xf
<<
24
,
tmp
<<
24
);
clrsetbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
469
],
0xf
<<
24
,
tmp
<<
24
);
if
(
pdram_timing
->
mhz
<=
ENPER_CS_TRAINING_FREQ
)
{
/*
* Note:Per-CS Training is not compatible at speeds
* under 533 MHz. If the PHY is running at a speed
* less than 533MHz, all phy_per_cs_training_en_X
* parameters must be cleared to 0.
*/
/*DENALI_PHY_84/212/340/468 1bit offset_16 */
clrbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
84
],
0x1
<<
16
);
clrbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
212
],
0x1
<<
16
);
clrbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
340
],
0x1
<<
16
);
clrbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
468
],
0x1
<<
16
);
}
else
{
setbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
84
],
0x1
<<
16
);
setbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
212
],
0x1
<<
16
);
setbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
340
],
0x1
<<
16
);
setbits_32
(
&
rk3399_ddr_publ
[
i
]
->
denali_phy
[
468
],
0x1
<<
16
);
}
}
}
static
int
to_get_clk_index
(
unsigned
int
mhz
)
{
int
pll_cnt
,
i
;
pll_cnt
=
sizeof
(
dpll_rates_table
)
/
sizeof
(
struct
pll_div
);
/* Assumming rate_table is in descending order */
for
(
i
=
0
;
i
<
pll_cnt
;
i
++
)
{
if
(
mhz
>=
dpll_rates_table
[
i
].
mhz
)
break
;
}
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
;
write_32
(
DCF_PARAM_ADDR
+
PARAM_DPLL_CON0
,
FBDIV
(
fbdiv
));
write_32
(
DCF_PARAM_ADDR
+
PARAM_DPLL_CON1
,
POSTDIV2
(
postdiv2
)
|
POSTDIV1
(
postdiv1
)
|
REFDIV
(
refdiv
));
return
(
24
*
fbdiv
)
/
refdiv
/
postdiv1
/
postdiv2
;
}
uint64_t
ddr_get_rate
(
void
)
{
uint32_t
refdiv
,
postdiv1
,
fbdiv
,
postdiv2
;
refdiv
=
mmio_read_32
(
CRU_BASE
+
CRU_PLL_CON
(
DPLL_ID
,
1
))
&
0x3f
;
fbdiv
=
mmio_read_32
(
CRU_BASE
+
CRU_PLL_CON
(
DPLL_ID
,
0
))
&
0xfff
;
postdiv1
=
(
mmio_read_32
(
CRU_BASE
+
CRU_PLL_CON
(
DPLL_ID
,
1
))
>>
8
)
&
0x7
;
postdiv2
=
(
mmio_read_32
(
CRU_BASE
+
CRU_PLL_CON
(
DPLL_ID
,
1
))
>>
12
)
&
0x7
;
return
(
24
/
refdiv
*
fbdiv
/
postdiv1
/
postdiv2
)
*
1000
*
1000
;
}
/*
* return: bit12: channel 1, external self-refresh
* bit11: channel 1, stdby_mode
* bit10: channel 1, self-refresh with controller and memory clock gate
* bit9: channel 1, self-refresh
* bit8: channel 1, power-down
*
* bit4: channel 1, external self-refresh
* bit3: channel 0, stdby_mode
* bit2: channel 0, self-refresh with controller and memory clock gate
* bit1: channel 0, self-refresh
* bit0: channel 0, power-down
*/
uint32_t
exit_low_power
(
void
)
{
struct
rk3399_ddr_pctl_regs
*
ddr_pctl_regs
;
uint32_t
low_power
=
0
;
uint32_t
channel_mask
;
uint32_t
channel
;
uint32_t
tmp
;
channel_mask
=
(
read_32
(
PMUGRF_BASE
+
PMUGRF_OSREG
(
2
))
>>
28
)
&
0x3
;
for
(
channel
=
0
;
channel
<
2
;
channel
++
)
{
ddr_pctl_regs
=
rk3399_ddr_pctl
[
channel
];
if
(
!
(
channel_mask
&
(
1
<<
channel
)))
continue
;
/* exit stdby mode */
write_32
(
&
rk3399_ddr_cic
->
cic_ctrl1
,
(
1
<<
(
channel
+
16
))
|
(
0
<<
channel
));
/* exit external self-refresh */
tmp
=
channel
?
12
:
8
;
low_power
|=
((
read_32
(
PMU_BASE
+
PMU_SFT_CON
)
>>
tmp
)
&
0x1
)
<<
(
4
+
8
*
channel
);
clrbits_32
(
PMU_BASE
+
PMU_SFT_CON
,
1
<<
tmp
);
while
(
!
(
read_32
(
PMU_BASE
+
PMU_DDR_SREF_ST
)
&
(
1
<<
channel
)))
;
/* exit auto low-power */
clrbits_32
(
&
ddr_pctl_regs
->
denali_ctl
[
101
],
0x7
);
/* lp_cmd to exit */
if
(((
read_32
(
&
ddr_pctl_regs
->
denali_ctl
[
100
])
>>
24
)
&
0x7f
)
!=
0x40
)
{
while
(
read_32
(
&
ddr_pctl_regs
->
denali_ctl
[
200
])
&
0x1
)
;
clrsetbits_32
(
&
ddr_pctl_regs
->
denali_ctl
[
93
],
0xff
<<
24
,
0x69
<<
24
);
while
(((
read_32
(
&
ddr_pctl_regs
->
denali_ctl
[
100
])
>>
24
)
&
0x7f
)
!=
0x40
)
;
}
}
return
low_power
;
}
void
resume_low_power
(
uint32_t
low_power
)
{
struct
rk3399_ddr_pctl_regs
*
ddr_pctl_regs
;
uint32_t
channel_mask
;
uint32_t
channel
;
uint32_t
tmp
;
uint32_t
val
;
channel_mask
=
(
read_32
(
PMUGRF_BASE
+
PMUGRF_OSREG
(
2
))
>>
28
)
&
0x3
;
for
(
channel
=
0
;
channel
<
2
;
channel
++
)
{
ddr_pctl_regs
=
rk3399_ddr_pctl
[
channel
];
if
(
!
(
channel_mask
&
(
1
<<
channel
)))
continue
;
/* resume external self-refresh */
tmp
=
channel
?
12
:
8
;
val
=
(
low_power
>>
(
4
+
8
*
channel
))
&
0x1
;
setbits_32
(
PMU_BASE
+
PMU_SFT_CON
,
val
<<
tmp
);
/* resume auto low-power */
val
=
(
low_power
>>
(
8
*
channel
))
&
0x7
;
setbits_32
(
&
ddr_pctl_regs
->
denali_ctl
[
101
],
val
);
/* resume stdby mode */
val
=
(
low_power
>>
(
3
+
8
*
channel
))
&
0x1
;
write_32
(
&
rk3399_ddr_cic
->
cic_ctrl1
,
(
1
<<
(
channel
+
16
))
|
(
val
<<
channel
));
}
}
static
void
wait_dcf_done
(
void
)
{
while
((
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
)
{
/* config DCF start addr */
write_32
(
DCF_BASE
+
DCF_DCF_ADDR
,
dcf_addr
);
/* wait dcf done */
while
(
read_32
(
DCF_BASE
+
DCF_DCF_CTRL
)
&
1
)
continue
;
/* clear dcf irq status */
write_32
(
DCF_BASE
+
DCF_DCF_ISR
,
DCF_TIMEOUT
|
DCF_ERR
|
DCF_DONE
);
/* DCF start */
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 */
write_32
(
SGRF_BASE
+
0xe01c
,
((
0x3
<<
0
)
<<
16
)
|
(
0
<<
0
));
write_32
(
DCF_BASE
+
DCF_DCF_TOSET
,
0x80000000
);
}
static
void
dcf_start
(
uint32_t
freq
,
uint32_t
index
)
{
write_32
(
CRU_BASE
+
CRU_SOFTRST_CON
(
10
),
(
0x1
<<
(
1
+
16
))
|
(
1
<<
1
));
write_32
(
CRU_BASE
+
CRU_SOFTRST_CON
(
11
),
(
0x1
<<
(
0
+
16
))
|
(
1
<<
0
));
write_32
(
DCF_PARAM_ADDR
+
PARAM_FREQ_SELECT
,
index
<<
4
);
write_32
(
DCF_PARAM_ADDR
+
PARAM_DRAM_FREQ
,
freq
);
rkclk_prepare_pll_timing
(
freq
);
udelay
(
10
);
write_32
(
CRU_BASE
+
CRU_SOFTRST_CON
(
10
),
(
0x1
<<
(
1
+
16
))
|
(
0
<<
1
));
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
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
)
tmp1
=
(
2
<<
16
)
|
(
0x7
<<
8
)
|
7
;
else
tmp1
=
(
3
<<
16
)
|
(
0x7
<<
8
)
|
7
;
*
low_power
=
0
;
for
(
i
=
0
;
i
<
ch_cnt
;
i
++
)
{
write_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
102
],
tmp
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
103
],
0xffff
,
(
lp_config
->
sr_mc_gate_idle
<<
8
)
|
lp_config
->
sr_idle
);
clrsetbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
101
],
0x70f0f
,
tmp1
);
*
low_power
|=
(
7
<<
(
8
*
i
));
}
/* standby idle */
write_32
(
&
rk3399_ddr_cic
->
cic_idle_th
,
lp_config
->
standby_idle
);
write_32
(
&
rk3399_ddr_cic
->
cic_cg_wait_th
,
0x640008
);
if
(
ch_cnt
==
2
)
{
write_32
(
GRF_BASE
+
GRF_DDRC1_CON1
,
(((
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
;
}
write_32
(
&
rk3399_ddr_cic
->
cic_ctrl1
,
tmp
);
}
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
;
}
write_32
(
&
rk3399_ddr_cic
->
cic_ctrl1
,
tmp
);
}
static
void
dram_related_init
(
struct
ddr_dts_config_timing
*
dts_timing
)
{
uint32_t
trefi0
,
trefi1
;
uint32_t
i
;
struct
rk3399_sdram_config
sdram_config
;
dcf_code_init
();
/* get sdram config for os reg */
sdram_config_init
(
&
sdram_config
);
drv_odt_lp_cfg_init
(
sdram_config
.
dramtype
,
dts_timing
,
&
rk3399_dram_status
.
drv_odt_lp_cfg
);
sdram_timing_cfg_init
(
&
rk3399_dram_status
.
timing_config
,
&
sdram_config
,
&
rk3399_dram_status
.
drv_odt_lp_cfg
);
trefi0
=
((
read_32
(
&
rk3399_ddr_pctl
[
0
]
->
denali_ctl
[
48
])
>>
16
)
&
0xffff
)
+
8
;
trefi1
=
((
read_32
(
&
rk3399_ddr_pctl
[
0
]
->
denali_ctl
[
49
])
>>
16
)
&
0xffff
)
+
8
;
rk3399_dram_status
.
index_freq
[
0
]
=
trefi0
*
10
/
39
;
rk3399_dram_status
.
index_freq
[
1
]
=
trefi1
*
10
/
39
;
rk3399_dram_status
.
current_index
=
(
read_32
(
&
rk3399_ddr_pctl
[
0
]
->
denali_ctl
[
111
])
>>
16
)
&
0x3
;
if
(
rk3399_dram_status
.
timing_config
.
dram_type
==
DDR3
)
{
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
;
/* disable all training by ctl and pi */
for
(
i
=
0
;
i
<
rk3399_dram_status
.
timing_config
.
ch_cnt
;
i
++
)
{
clrbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
70
],
(
1
<<
24
)
|
(
1
<<
16
)
|
(
1
<<
8
)
|
1
);
clrbits_32
(
&
rk3399_ddr_pctl
[
i
]
->
denali_ctl
[
71
],
1
);
clrbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
60
],
0x3
<<
8
);
clrbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
80
],
(
0x3
<<
24
)
|
(
0x3
<<
16
));
clrbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
100
],
0x3
<<
8
);
clrbits_32
(
&
rk3399_ddr_pi
[
i
]
->
denali_pi
[
124
],
0x3
<<
16
);
}
/* 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
;
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
);
}
static
uint32_t
prepare_ddr_timing
(
uint32_t
mhz
)
{
uint32_t
index
;
struct
dram_timing_t
dram_timing
;
rk3399_dram_status
.
timing_config
.
freq
=
mhz
;
if
(
mhz
<
rk3399_dram_status
.
drv_odt_lp_cfg
.
ddr3_dll_dis_freq
)
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
;
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
* target freq.
*/
dram_get_parameter
(
&
rk3399_dram_status
.
timing_config
,
&
dram_timing
);
gen_rk3399_ctl_params
(
&
rk3399_dram_status
.
timing_config
,
&
dram_timing
,
index
);
gen_rk3399_pi_params
(
&
rk3399_dram_status
.
timing_config
,
&
dram_timing
,
index
);
gen_rk3399_phy_params
(
&
rk3399_dram_status
.
timing_config
,
&
rk3399_dram_status
.
drv_odt_lp_cfg
,
&
dram_timing
,
index
);
rk3399_dram_status
.
index_freq
[
index
]
=
mhz
;
out:
return
index
;
}
void
print_dram_status_info
(
void
)
{
uint32_t
*
p
;
uint32_t
i
;
p
=
(
uint32_t
*
)
&
rk3399_dram_status
.
timing_config
;
INFO
(
"rk3399_dram_status.timing_config:
\n
"
);
for
(
i
=
0
;
i
<
sizeof
(
struct
timing_related_config
)
/
4
;
i
++
)
tf_printf
(
"%u
\n
"
,
p
[
i
]);
p
=
(
uint32_t
*
)
&
rk3399_dram_status
.
drv_odt_lp_cfg
;
INFO
(
"rk3399_dram_status.drv_odt_lp_cfg:
\n
"
);
for
(
i
=
0
;
i
<
sizeof
(
struct
drv_odt_lp_config
)
/
4
;
i
++
)
tf_printf
(
"%u
\n
"
,
p
[
i
]);
}
uint64_t
ddr_set_rate
(
uint64_t
hz
)
{
uint32_t
low_power
,
index
;
uint32_t
mhz
=
hz
/
(
1000
*
1000
);
if
(
mhz
==
rk3399_dram_status
.
index_freq
[
rk3399_dram_status
.
current_index
])
goto
out
;
low_power
=
exit_low_power
();
index
=
prepare_ddr_timing
(
mhz
);
if
(
index
>
1
)
{
/* set timing error, quit */
mhz
=
0
;
goto
out
;
}
dcf_start
(
mhz
,
index
);
wait_dcf_done
();
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
;
resume_low_power
(
low_power
);
out:
return
mhz
;
}
uint64_t
ddr_round_rate
(
uint64_t
hz
)
{
int
index
;
uint32_t
mhz
=
hz
/
(
1000
*
1000
);
index
=
to_get_clk_index
(
mhz
);
return
dpll_rates_table
[
index
].
mhz
*
1000
*
1000
;
}
uint64_t
dts_timing_receive
(
uint64_t
timing
,
uint64_t
index
)
{
uint32_t
*
p
=
(
uint32_t
*
)
&
dts_parameter
;
static
uint32_t
receive_nums
;
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
;
}
return
index
;
}
void
ddr_init
(
void
)
{
dram_related_init
(
&
dts_parameter
);
}
plat/rockchip/rk3399/drivers/dram/dram.h
0 → 100644
View file @
c2229abd
/*
* 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 __SOC_ROCKCHIP_RK3399_SDRAM_H__
#define __SOC_ROCKCHIP_RK3399_SDRAM_H__
struct
rk3399_ddr_cic_regs
{
uint32_t
cic_ctrl0
;
uint32_t
cic_ctrl1
;
uint32_t
cic_idle_th
;
uint32_t
cic_cg_wait_th
;
uint32_t
cic_status0
;
uint32_t
cic_status1
;
uint32_t
cic_ctrl2
;
uint32_t
cic_ctrl3
;
uint32_t
cic_ctrl4
;
};
/* DENALI_CTL_00 */
#define START (1)
/* DENALI_CTL_68 */
#define PWRUP_SREFRESH_EXIT (1 << 16)
/* DENALI_CTL_274 */
#define MEM_RST_VALID (1)
struct
rk3399_ddr_pctl_regs
{
uint32_t
denali_ctl
[
332
];
};
struct
rk3399_ddr_publ_regs
{
uint32_t
denali_phy
[
959
];
};
#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)
struct
rk3399_ddr_pi_regs
{
uint32_t
denali_pi
[
200
];
};
union
noc_ddrtiminga0
{
uint32_t
d32
;
struct
{
unsigned
acttoact
:
6
;
unsigned
reserved0
:
2
;
unsigned
rdtomiss
:
6
;
unsigned
reserved1
:
2
;
unsigned
wrtomiss
:
6
;
unsigned
reserved2
:
2
;
unsigned
readlatency
:
8
;
}
b
;
};
union
noc_ddrtimingb0
{
uint32_t
d32
;
struct
{
unsigned
rdtowr
:
5
;
unsigned
reserved0
:
3
;
unsigned
wrtord
:
5
;
unsigned
reserved1
:
3
;
unsigned
rrd
:
4
;
unsigned
reserved2
:
4
;
unsigned
faw
:
6
;
unsigned
reserved3
:
2
;
}
b
;
};
union
noc_ddrtimingc0
{
uint32_t
d32
;
struct
{
unsigned
burstpenalty
:
4
;
unsigned
reserved0
:
4
;
unsigned
wrtomwr
:
6
;
unsigned
reserved1
:
18
;
}
b
;
};
union
noc_devtodev0
{
uint32_t
d32
;
struct
{
unsigned
busrdtord
:
3
;
unsigned
reserved0
:
1
;
unsigned
busrdtowr
:
3
;
unsigned
reserved1
:
1
;
unsigned
buswrtord
:
3
;
unsigned
reserved2
:
1
;
unsigned
buswrtowr
:
3
;
unsigned
reserved3
:
17
;
}
b
;
};
union
noc_ddrmode
{
uint32_t
d32
;
struct
{
unsigned
autoprecharge
:
1
;
unsigned
bypassfiltering
:
1
;
unsigned
fawbank
:
1
;
unsigned
burstsize
:
2
;
unsigned
mwrsize
:
2
;
unsigned
reserved2
:
1
;
unsigned
forceorder
:
8
;
unsigned
forceorderstate
:
8
;
unsigned
reserved3
:
8
;
}
b
;
};
struct
rk3399_msch_regs
{
uint32_t
coreid
;
uint32_t
revisionid
;
uint32_t
ddrconf
;
uint32_t
ddrsize
;
union
noc_ddrtiminga0
ddrtiminga0
;
union
noc_ddrtimingb0
ddrtimingb0
;
union
noc_ddrtimingc0
ddrtimingc0
;
union
noc_devtodev0
devtodev0
;
uint32_t
reserved0
[(
0x110
-
0x20
)
/
4
];
union
noc_ddrmode
ddrmode
;
uint32_t
reserved1
[(
0x1000
-
0x114
)
/
4
];
uint32_t
agingx0
;
};
struct
rk3399_msch_timings
{
union
noc_ddrtiminga0
ddrtiminga0
;
union
noc_ddrtimingb0
ddrtimingb0
;
union
noc_ddrtimingc0
ddrtimingc0
;
union
noc_devtodev0
devtodev0
;
union
noc_ddrmode
ddrmode
;
uint32_t
agingx0
;
};
#if 1
struct
rk3399_sdram_channel
{
unsigned
char
rank
;
/* col = 0, means this channel is invalid */
unsigned
char
col
;
/* 3:8bank, 2:4bank */
unsigned
char
bk
;
/* channel buswidth, 2:32bit, 1:16bit, 0:8bit */
unsigned
char
bw
;
/* die buswidth, 2:32bit, 1:16bit, 0:8bit */
unsigned
char
dbw
;
/* row_3_4 = 1: 6Gb or 12Gb die
* row_3_4 = 0: normal die, power of 2
*/
unsigned
char
row_3_4
;
unsigned
char
cs0_row
;
unsigned
char
cs1_row
;
uint32_t
ddrconfig
;
struct
rk3399_msch_timings
noc_timings
;
};
struct
rk3399_sdram_params
{
struct
rk3399_sdram_channel
ch
[
2
];
uint32_t
ddr_freq
;
unsigned
char
dramtype
;
unsigned
char
num_channels
;
unsigned
char
stride
;
unsigned
char
odt
;
struct
rk3399_ddr_pctl_regs
pctl_regs
;
struct
rk3399_ddr_pi_regs
pi_regs
;
struct
rk3399_ddr_publ_regs
phy_regs
;
};
#endif
struct
rk3399_sdram_channel_config
{
uint32_t
bus_width
;
uint32_t
cs_cnt
;
uint32_t
cs0_row
;
uint32_t
cs1_row
;
uint32_t
bank
;
uint32_t
col
;
uint32_t
each_die_bus_width
;
uint32_t
each_die_6gb_or_12gb
;
};
struct
rk3399_sdram_config
{
struct
rk3399_sdram_channel_config
ch
[
2
];
uint32_t
dramtype
;
uint32_t
channal_num
;
};
struct
rk3399_sdram_default_config
{
unsigned
char
bl
;
/* 1:auto precharge, 0:never auto precharge */
unsigned
char
ap
;
/* dram driver strength */
unsigned
char
dramds
;
/* dram ODT, if odt=0, this parameter invalid */
unsigned
char
dramodt
;
/* ca ODT, if odt=0, this parameter invalid
* only used by LPDDR4
*/
unsigned
char
caodt
;
unsigned
char
burst_ref_cnt
;
/* zqcs period, unit(s) */
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
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
;
};
#define KHz (1000)
#define MHz (1000*KHz)
#define GHz (1000*MHz)
#define PI_CA_TRAINING (1 << 0)
#define PI_WRITE_LEVELING (1 << 1)
#define PI_READ_GATE_TRAINING (1 << 2)
#define PI_READ_LEVELING (1 << 3)
#define PI_WDQ_LEVELING (1 << 4)
#define PI_FULL_TARINING (0xff)
#define READ_CH_CNT(val) (1+((val>>12)&0x1))
#define READ_CH_INFO(val) ((val>>28)&0x3)
/* row_3_4:0=normal, 1=6Gb or 12Gb */
#define READ_CH_ROW_INFO(val, ch) ((val>>(30+(ch)))&0x1)
#define READ_DRAMTYPE_INFO(val) ((val>>13)&0x7)
#define READ_CS_INFO(val, ch) ((((val)>>(11+(ch)*16))&0x1)+1)
#define READ_BW_INFO(val, ch) (2>>(((val)>>(2+(ch)*16))&0x3))
#define READ_COL_INFO(val, ch) (9+(((val)>>(9+(ch)*16))&0x3))
#define READ_BK_INFO(val, ch) (3-(((val)>>(8+(ch)*16))&0x1))
#define READ_CS0_ROW_INFO(val, ch) (13+(((val)>>(6+(ch)*16))&0x3))
#define READ_CS1_ROW_INFO(val, ch) (13+(((val)>>(4+(ch)*16))&0x3))
#define READ_DIE_BW_INFO(val, ch) (2>>((val>>((ch)*16))&0x3))
#define __sramdata __attribute__((section(".sram.data")))
#define __sramconst __attribute__((section(".sram.rodata")))
#define __sramlocalfunc __attribute__((section(".sram.text")))
#define __sramfunc __attribute__((section(".sram.text"))) \
__attribute__((noinline))
#define DDR_SAVE_SP(save_sp) (save_sp = ddr_save_sp(((uint32_t)\
(SRAM_CODE_BASE + 0x2000) & (~7))))
#define DDR_RESTORE_SP(save_sp) ddr_save_sp(save_sp)
void
ddr_init
(
void
);
uint64_t
ddr_set_rate
(
uint64_t
hz
);
uint64_t
ddr_round_rate
(
uint64_t
hz
);
uint64_t
ddr_get_rate
(
void
);
void
clr_dcf_irq
(
void
);
uint64_t
dts_timing_receive
(
uint64_t
timing
,
uint64_t
index
);
#endif
plat/rockchip/rk3399/drivers/dram/dram_spec_timing.c
0 → 100644
View file @
c2229abd
/*
* 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 <string.h>
#include <stdint.h>
#include "dram_spec_timing.h"
static
const
uint8_t
ddr3_cl_cwl
[][
7
]
=
{
/*
* speed 0~330 331 ~ 400 401 ~ 533 534~666 667~800 801~933 934~1066
* tCK>3 2.5~3 1.875~2.5 1.5~1.875 1.25~1.5 1.07~1.25 0.938~1.07
* cl<<4, cwl cl<<4, cwl cl<<4, cwl
*/
/* DDR3_800D (5-5-5) */
{((
5
<<
4
)
|
5
),
((
5
<<
4
)
|
5
),
0
,
0
,
0
,
0
,
0
},
/* DDR3_800E (6-6-6) */
{((
5
<<
4
)
|
5
),
((
6
<<
4
)
|
5
),
0
,
0
,
0
,
0
,
0
},
/* DDR3_1066E (6-6-6) */
{((
5
<<
4
)
|
5
),
((
5
<<
4
)
|
5
),
((
6
<<
4
)
|
6
),
0
,
0
,
0
,
0
},
/* DDR3_1066F (7-7-7) */
{((
5
<<
4
)
|
5
),
((
6
<<
4
)
|
5
),
((
7
<<
4
)
|
6
),
0
,
0
,
0
,
0
},
/* DDR3_1066G (8-8-8) */
{((
5
<<
4
)
|
5
),
((
6
<<
4
)
|
5
),
((
8
<<
4
)
|
6
),
0
,
0
,
0
,
0
},
/* DDR3_1333F (7-7-7) */
{((
5
<<
4
)
|
5
),
((
5
<<
4
)
|
5
),
((
6
<<
4
)
|
6
),
((
7
<<
4
)
|
7
),
0
,
0
,
0
},
/* DDR3_1333G (8-8-8) */
{((
5
<<
4
)
|
5
),
((
5
<<
4
)
|
5
),
((
7
<<
4
)
|
6
),
((
8
<<
4
)
|
7
),
0
,
0
,
0
},
/* DDR3_1333H (9-9-9) */
{((
5
<<
4
)
|
5
),
((
6
<<
4
)
|
5
),
((
8
<<
4
)
|
6
),
((
9
<<
4
)
|
7
),
0
,
0
,
0
},
/* DDR3_1333J (10-10-10) */
{((
5
<<
4
)
|
5
),
((
6
<<
4
)
|
5
),
((
8
<<
4
)
|
6
),
((
10
<<
4
)
|
7
),
0
,
0
,
0
},
/* DDR3_1600G (8-8-8) */
{((
5
<<
4
)
|
5
),
((
5
<<
4
)
|
5
),
((
6
<<
4
)
|
6
),
((
7
<<
4
)
|
7
),
((
8
<<
4
)
|
8
),
0
,
0
},
/* DDR3_1600H (9-9-9) */
{((
5
<<
4
)
|
5
),
((
5
<<
4
)
|
5
),
((
6
<<
4
)
|
6
),
((
8
<<
4
)
|
7
),
((
9
<<
4
)
|
8
),
0
,
0
},
/* DDR3_1600J (10-10-10) */
{((
5
<<
4
)
|
5
),
((
5
<<
4
)
|
5
),
((
7
<<
4
)
|
6
),
((
9
<<
4
)
|
7
),
((
10
<<
4
)
|
8
),
0
,
0
},
/* DDR3_1600K (11-11-11) */
{((
5
<<
4
)
|
5
),
((
6
<<
4
)
|
5
),
((
8
<<
4
)
|
6
),
((
10
<<
4
)
|
7
),
((
11
<<
4
)
|
8
),
0
,
0
},
/* DDR3_1866J (10-10-10) */
{((
5
<<
4
)
|
5
),
((
5
<<
4
)
|
5
),
((
6
<<
4
)
|
6
),
((
8
<<
4
)
|
7
),
((
9
<<
4
)
|
8
),
((
11
<<
4
)
|
9
),
0
},
/* DDR3_1866K (11-11-11) */
{((
5
<<
4
)
|
5
),
((
5
<<
4
)
|
5
),
((
7
<<
4
)
|
6
),
((
8
<<
4
)
|
7
),
((
10
<<
4
)
|
8
),
((
11
<<
4
)
|
9
),
0
},
/* DDR3_1866L (12-12-12) */
{((
6
<<
4
)
|
5
),
((
6
<<
4
)
|
5
),
((
7
<<
4
)
|
6
),
((
9
<<
4
)
|
7
),
((
11
<<
4
)
|
8
),
((
12
<<
4
)
|
9
),
0
},
/* DDR3_1866M (13-13-13) */
{((
6
<<
4
)
|
5
),
((
6
<<
4
)
|
5
),
((
8
<<
4
)
|
6
),
((
10
<<
4
)
|
7
),
((
11
<<
4
)
|
8
),
((
13
<<
4
)
|
9
),
0
},
/* DDR3_2133K (11-11-11) */
{((
5
<<
4
)
|
5
),
((
5
<<
4
)
|
5
),
((
6
<<
4
)
|
6
),
((
7
<<
4
)
|
7
),
((
9
<<
4
)
|
8
),
((
10
<<
4
)
|
9
),
((
11
<<
4
)
|
10
)},
/* DDR3_2133L (12-12-12) */
{((
5
<<
4
)
|
5
),
((
5
<<
4
)
|
5
),
((
6
<<
4
)
|
6
),
((
8
<<
4
)
|
7
),
((
9
<<
4
)
|
8
),
((
11
<<
4
)
|
9
),
((
12
<<
4
)
|
10
)},
/* DDR3_2133M (13-13-13) */
{((
5
<<
4
)
|
5
),
((
5
<<
4
)
|
5
),
((
7
<<
4
)
|
6
),
((
9
<<
4
)
|
7
),
((
10
<<
4
)
|
8
),
((
12
<<
4
)
|
9
),
((
13
<<
4
)
|
10
)},
/* DDR3_2133N (14-14-14) */
{((
6
<<
4
)
|
5
),
((
6
<<
4
)
|
5
),
((
7
<<
4
)
|
6
),
((
9
<<
4
)
|
7
),
((
11
<<
4
)
|
8
),
((
13
<<
4
)
|
9
),
((
14
<<
4
)
|
10
)},
/* DDR3_DEFAULT */
{((
6
<<
4
)
|
5
),
((
6
<<
4
)
|
5
),
((
8
<<
4
)
|
6
),
((
10
<<
4
)
|
7
),
((
11
<<
4
)
|
8
),
((
13
<<
4
)
|
9
),
((
14
<<
4
)
|
10
)}
};
static
const
uint16_t
ddr3_trc_tfaw
[]
=
{
/* tRC tFAW */
((
50
<<
8
)
|
50
),
/* DDR3_800D (5-5-5) */
((
53
<<
8
)
|
50
),
/* DDR3_800E (6-6-6) */
((
49
<<
8
)
|
50
),
/* DDR3_1066E (6-6-6) */
((
51
<<
8
)
|
50
),
/* DDR3_1066F (7-7-7) */
((
53
<<
8
)
|
50
),
/* DDR3_1066G (8-8-8) */
((
47
<<
8
)
|
45
),
/* DDR3_1333F (7-7-7) */
((
48
<<
8
)
|
45
),
/* DDR3_1333G (8-8-8) */
((
50
<<
8
)
|
45
),
/* DDR3_1333H (9-9-9) */
((
51
<<
8
)
|
45
),
/* DDR3_1333J (10-10-10) */
((
45
<<
8
)
|
40
),
/* DDR3_1600G (8-8-8) */
((
47
<<
8
)
|
40
),
/* DDR3_1600H (9-9-9)*/
((
48
<<
8
)
|
40
),
/* DDR3_1600J (10-10-10) */
((
49
<<
8
)
|
40
),
/* DDR3_1600K (11-11-11) */
((
45
<<
8
)
|
35
),
/* DDR3_1866J (10-10-10) */
((
46
<<
8
)
|
35
),
/* DDR3_1866K (11-11-11) */
((
47
<<
8
)
|
35
),
/* DDR3_1866L (12-12-12) */
((
48
<<
8
)
|
35
),
/* DDR3_1866M (13-13-13) */
((
44
<<
8
)
|
35
),
/* DDR3_2133K (11-11-11) */
((
45
<<
8
)
|
35
),
/* DDR3_2133L (12-12-12) */
((
46
<<
8
)
|
35
),
/* DDR3_2133M (13-13-13) */
((
47
<<
8
)
|
35
),
/* DDR3_2133N (14-14-14) */
((
53
<<
8
)
|
50
)
/* DDR3_DEFAULT */
};
static
uint32_t
get_max_speed_rate
(
struct
timing_related_config
*
timing_config
)
{
if
(
timing_config
->
ch_cnt
>
1
)
return
max
(
timing_config
->
dram_info
[
0
].
speed_rate
,
timing_config
->
dram_info
[
1
].
speed_rate
);
else
return
timing_config
->
dram_info
[
0
].
speed_rate
;
}
static
uint32_t
get_max_die_capability
(
struct
timing_related_config
*
timing_config
)
{
uint32_t
die_cap
=
0
;
uint32_t
cs
,
ch
;
for
(
ch
=
0
;
ch
<
timing_config
->
ch_cnt
;
ch
++
)
{
for
(
cs
=
0
;
cs
<
timing_config
->
dram_info
[
ch
].
cs_cnt
;
cs
++
)
{
die_cap
=
max
(
die_cap
,
timing_config
->
dram_info
[
ch
].
per_die_capability
[
cs
]);
}
}
return
die_cap
;
}
/* tRSTL, 100ns */
#define DDR3_TRSTL (100)
/* trsth, 500us */
#define DDR3_TRSTH (500000)
/* trefi, 7.8us */
#define DDR3_TREFI_7_8_US (7800)
/* tWR, 15ns */
#define DDR3_TWR (15)
/* tRTP, max(4 tCK,7.5ns) */
#define DDR3_TRTP (7)
/* tRRD = max(4nCK, 10ns) */
#define DDR3_TRRD (10)
/* tCK */
#define DDR3_TCCD (4)
/*tWTR, max(4 tCK,7.5ns)*/
#define DDR3_TWTR (7)
/* tCK */
#define DDR3_TRTW (0)
/* tRAS, 37.5ns(400MHz) 37.5ns(533MHz) */
#define DDR3_TRAS (37)
/* ns */
#define DDR3_TRFC_512MBIT (90)
/* ns */
#define DDR3_TRFC_1GBIT (110)
/* ns */
#define DDR3_TRFC_2GBIT (160)
/* ns */
#define DDR3_TRFC_4GBIT (300)
/* ns */
#define DDR3_TRFC_8GBIT (350)
/*pd and sr*/
#define DDR3_TXP (7)
/* tXP, max(3 tCK, 7.5ns)( < 933MHz) */
#define DDR3_TXPDLL (24)
/* tXPDLL, max(10 tCK, 24ns) */
#define DDR3_TDLLK (512)
/* tXSR, tDLLK=512 tCK */
#define DDR3_TCKE_400MHZ (7)
/* tCKE, max(3 tCK,7.5ns)(400MHz) */
#define DDR3_TCKE_533MHZ (6)
/* tCKE, max(3 tCK,5.625ns)(533MHz) */
#define DDR3_TCKSRE (10)
/* tCKSRX, max(5 tCK, 10ns) */
/*mode register timing*/
#define DDR3_TMOD (15)
/* tMOD, max(12 tCK,15ns) */
#define DDR3_TMRD (4)
/* tMRD, 4 tCK */
/* ZQ */
#define DDR3_TZQINIT (640)
/* tZQinit, max(512 tCK, 640ns) */
#define DDR3_TZQCS (80)
/* tZQCS, max(64 tCK, 80ns) */
#define DDR3_TZQOPER (320)
/* tZQoper, max(256 tCK, 320ns) */
/* Write leveling */
#define DDR3_TWLMRD (40)
/* tCK */
#define DDR3_TWLO (9)
/* max 7.5ns */
#define DDR3_TWLDQSEN (25)
/* tCK */
/*
* Description: depend on input parameter "timing_config",
* and calculate all ddr3
* spec timing to "pdram_timing"
* parameters:
* input: timing_config
* output: pdram_timing
*/
static
void
ddr3_get_parameter
(
struct
timing_related_config
*
timing_config
,
struct
dram_timing_t
*
pdram_timing
)
{
uint32_t
nmhz
=
timing_config
->
freq
;
uint32_t
ddr_speed_bin
=
get_max_speed_rate
(
timing_config
);
uint32_t
ddr_capability_per_die
=
get_max_die_capability
(
timing_config
);
uint32_t
tmp
;
memset
((
void
*
)
pdram_timing
,
0
,
sizeof
(
struct
dram_timing_t
));
pdram_timing
->
mhz
=
nmhz
;
pdram_timing
->
al
=
0
;
pdram_timing
->
bl
=
timing_config
->
bl
;
if
(
nmhz
<=
330
)
tmp
=
0
;
else
if
(
nmhz
<=
400
)
tmp
=
1
;
else
if
(
nmhz
<=
533
)
tmp
=
2
;
else
if
(
nmhz
<=
666
)
tmp
=
3
;
else
if
(
nmhz
<=
800
)
tmp
=
4
;
else
if
(
nmhz
<=
933
)
tmp
=
5
;
else
tmp
=
6
;
/* when dll bypss cl = cwl = 6 */
if
(
nmhz
<
300
)
{
pdram_timing
->
cl
=
6
;
pdram_timing
->
cwl
=
6
;
}
else
{
pdram_timing
->
cl
=
(
ddr3_cl_cwl
[
ddr_speed_bin
][
tmp
]
>>
4
)
&
0xf
;
pdram_timing
->
cwl
=
ddr3_cl_cwl
[
ddr_speed_bin
][
tmp
]
&
0xf
;
}
switch
(
timing_config
->
dramds
)
{
case
40
:
tmp
=
DDR3_DS_40
;
break
;
case
34
:
default:
tmp
=
DDR3_DS_34
;
break
;
}
switch
(
timing_config
->
dramodt
)
{
case
60
:
pdram_timing
->
mr
[
1
]
=
tmp
|
DDR3_RTT_NOM_60
;
break
;
case
40
:
pdram_timing
->
mr
[
1
]
=
tmp
|
DDR3_RTT_NOM_40
;
break
;
case
120
:
pdram_timing
->
mr
[
1
]
=
tmp
|
DDR3_RTT_NOM_120
;
break
;
case
0
:
default:
pdram_timing
->
mr
[
1
]
=
tmp
|
DDR3_RTT_NOM_DIS
;
break
;
}
pdram_timing
->
mr
[
2
]
=
DDR3_MR2_CWL
(
pdram_timing
->
cwl
);
pdram_timing
->
mr
[
3
]
=
0
;
pdram_timing
->
trstl
=
((
DDR3_TRSTL
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
trsth
=
((
DDR3_TRSTH
*
nmhz
+
999
)
/
1000
);
/* tREFI, average periodic refresh interval, 7.8us */
pdram_timing
->
trefi
=
((
DDR3_TREFI_7_8_US
*
nmhz
+
999
)
/
1000
);
/* base timing */
pdram_timing
->
trcd
=
pdram_timing
->
cl
;
pdram_timing
->
trp
=
pdram_timing
->
cl
;
pdram_timing
->
trppb
=
pdram_timing
->
cl
;
tmp
=
((
DDR3_TWR
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
twr
=
tmp
;
pdram_timing
->
tdal
=
tmp
+
pdram_timing
->
trp
;
if
(
tmp
<
9
)
{
tmp
=
tmp
-
4
;
}
else
{
tmp
+=
(
tmp
&
0x1
)
?
1
:
0
;
tmp
=
tmp
>>
1
;
}
if
(
pdram_timing
->
bl
==
4
)
pdram_timing
->
mr
[
0
]
=
DDR3_BC4
|
DDR3_CL
(
pdram_timing
->
cl
)
|
DDR3_WR
(
tmp
);
else
pdram_timing
->
mr
[
0
]
=
DDR3_BL8
|
DDR3_CL
(
pdram_timing
->
cl
)
|
DDR3_WR
(
tmp
);
tmp
=
((
DDR3_TRTP
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
);
pdram_timing
->
trtp
=
max
(
4
,
tmp
);
pdram_timing
->
trc
=
(((
ddr3_trc_tfaw
[
ddr_speed_bin
]
>>
8
)
*
nmhz
+
999
)
/
1000
);
tmp
=
((
DDR3_TRRD
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
trrd
=
max
(
4
,
tmp
);
pdram_timing
->
tccd
=
DDR3_TCCD
;
tmp
=
((
DDR3_TWTR
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
);
pdram_timing
->
twtr
=
max
(
4
,
tmp
);
pdram_timing
->
trtw
=
DDR3_TRTW
;
pdram_timing
->
tras_max
=
9
*
pdram_timing
->
trefi
;
pdram_timing
->
tras_min
=
((
DDR3_TRAS
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
);
pdram_timing
->
tfaw
=
(((
ddr3_trc_tfaw
[
ddr_speed_bin
]
&
0x0ff
)
*
nmhz
+
999
)
/
1000
);
/* tRFC, 90ns(512Mb),110ns(1Gb),160ns(2Gb),300ns(4Gb),350ns(8Gb) */
if
(
ddr_capability_per_die
<=
0x4000000
)
tmp
=
DDR3_TRFC_512MBIT
;
else
if
(
ddr_capability_per_die
<=
0x8000000
)
tmp
=
DDR3_TRFC_1GBIT
;
else
if
(
ddr_capability_per_die
<=
0x10000000
)
tmp
=
DDR3_TRFC_2GBIT
;
else
if
(
ddr_capability_per_die
<=
0x20000000
)
tmp
=
DDR3_TRFC_4GBIT
;
else
tmp
=
DDR3_TRFC_8GBIT
;
pdram_timing
->
trfc
=
(
tmp
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
txsnr
=
max
(
5
,
(((
tmp
+
10
)
*
nmhz
+
999
)
/
1000
));
pdram_timing
->
tdqsck_max
=
0
;
/*pd and sr*/
pdram_timing
->
txsr
=
DDR3_TDLLK
;
tmp
=
((
DDR3_TXP
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
);
pdram_timing
->
txp
=
max
(
3
,
tmp
);
tmp
=
((
DDR3_TXPDLL
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
txpdll
=
max
(
10
,
tmp
);
pdram_timing
->
tdllk
=
DDR3_TDLLK
;
if
(
nmhz
>=
533
)
tmp
=
((
DDR3_TCKE_533MHZ
*
nmhz
+
999
)
/
1000
);
else
tmp
=
((
DDR3_TCKE_400MHZ
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
);
pdram_timing
->
tcke
=
max
(
3
,
tmp
);
pdram_timing
->
tckesr
=
(
pdram_timing
->
tcke
+
1
);
tmp
=
((
DDR3_TCKSRE
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
tcksre
=
max
(
5
,
tmp
);
pdram_timing
->
tcksrx
=
max
(
5
,
tmp
);
/*mode register timing*/
tmp
=
((
DDR3_TMOD
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
tmod
=
max
(
12
,
tmp
);
pdram_timing
->
tmrd
=
DDR3_TMRD
;
pdram_timing
->
tmrr
=
0
;
/*ODT*/
pdram_timing
->
todton
=
pdram_timing
->
cwl
-
2
;
/*ZQ*/
tmp
=
((
DDR3_TZQINIT
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
tzqinit
=
max
(
512
,
tmp
);
tmp
=
((
DDR3_TZQCS
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
tzqcs
=
max
(
64
,
tmp
);
tmp
=
((
DDR3_TZQOPER
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
tzqoper
=
max
(
256
,
tmp
);
/* write leveling */
pdram_timing
->
twlmrd
=
DDR3_TWLMRD
;
pdram_timing
->
twldqsen
=
DDR3_TWLDQSEN
;
pdram_timing
->
twlo
=
((
DDR3_TWLO
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
);
}
#define LPDDR2_TINIT1 (100)
/* ns */
#define LPDDR2_TINIT2 (5)
/* tCK */
#define LPDDR2_TINIT3 (200000)
/* 200us */
#define LPDDR2_TINIT4 (1000)
/* 1us */
#define LPDDR2_TINIT5 (10000)
/* 10us */
#define LPDDR2_TRSTL (0)
/* tCK */
#define LPDDR2_TRSTH (500000)
/* 500us */
#define LPDDR2_TREFI_3_9_US (3900)
/* 3.9us */
#define LPDDR2_TREFI_7_8_US (7800)
/* 7.8us */
/* base timing */
#define LPDDR2_TRCD (24)
/* tRCD,15ns(Fast)18ns(Typ)24ns(Slow) */
#define LPDDR2_TRP_PB (18)
/* tRPpb,15ns(Fast)18ns(Typ)24ns(Slow) */
#define LPDDR2_TRP_AB_8_BANK (21)
/* tRPab,18ns(Fast)21ns(Typ)27ns(Slow) */
#define LPDDR2_TWR (15)
/* tWR, max(3tCK,15ns) */
#define LPDDR2_TRTP (7)
/* tRTP, max(2tCK, 7.5ns) */
#define LPDDR2_TRRD (10)
/* tRRD, max(2tCK,10ns) */
#define LPDDR2_TCCD (2)
/* tCK */
#define LPDDR2_TWTR_GREAT_200MHZ (7)
/* ns */
#define LPDDR2_TWTR_LITTLE_200MHZ (10)
/* ns */
#define LPDDR2_TRTW (0)
/* tCK */
#define LPDDR2_TRAS_MAX (70000)
/* 70us */
#define LPDDR2_TRAS (42)
/* tRAS, max(3tCK,42ns) */
#define LPDDR2_TFAW_GREAT_200MHZ (50)
/* max(8tCK,50ns) */
#define LPDDR2_TFAW_LITTLE_200MHZ (60)
/* max(8tCK,60ns) */
#define LPDDR2_TRFC_8GBIT (210)
/* ns */
#define LPDDR2_TRFC_4GBIT (130)
/* ns */
#define LPDDR2_TDQSCK_MIN (2)
/* tDQSCKmin, 2.5ns */
#define LPDDR2_TDQSCK_MAX (5)
/* tDQSCKmax, 5.5ns */
/*pd and sr*/
#define LPDDR2_TXP (7)
/* tXP, max(2tCK,7.5ns) */
#define LPDDR2_TXPDLL (0)
#define LPDDR2_TDLLK (0)
/* tCK */
#define LPDDR2_TCKE (3)
/* tCK */
#define LPDDR2_TCKESR (15)
/* tCKESR, max(3tCK,15ns) */
#define LPDDR2_TCKSRE (1)
/* tCK */
#define LPDDR2_TCKSRX (2)
/* tCK */
/*mode register timing*/
#define LPDDR2_TMOD (0)
#define LPDDR2_TMRD (5)
/* tMRD, (=tMRW), 5 tCK */
#define LPDDR2_TMRR (2)
/* tCK */
/*ZQ*/
#define LPDDR2_TZQINIT (1000)
/* ns */
#define LPDDR2_TZQCS (90)
/* tZQCS, max(6tCK,90ns) */
#define LPDDR2_TZQCL (360)
/* tZQCL, max(6tCK,360ns) */
#define LPDDR2_TZQRESET (50)
/* ZQreset, max(3tCK,50ns) */
/*
* Description: depend on input parameter "timing_config",
* and calculate all lpddr2
* spec timing to "pdram_timing"
* parameters:
* input: timing_config
* output: pdram_timing
*/
static
void
lpddr2_get_parameter
(
struct
timing_related_config
*
timing_config
,
struct
dram_timing_t
*
pdram_timing
)
{
uint32_t
nmhz
=
timing_config
->
freq
;
uint32_t
ddr_capability_per_die
=
get_max_die_capability
(
timing_config
);
uint32_t
tmp
,
trp_tmp
,
trppb_tmp
,
tras_tmp
,
twr_tmp
,
bl_tmp
;
memset
((
void
*
)
pdram_timing
,
0
,
sizeof
(
struct
dram_timing_t
));
pdram_timing
->
mhz
=
nmhz
;
pdram_timing
->
al
=
0
;
pdram_timing
->
bl
=
timing_config
->
bl
;
/* 1066 933 800 667 533 400 333
* RL, 8 7 6 5 4 3 3
* WL, 4 4 3 2 2 1 1
*/
if
(
nmhz
<=
266
)
{
pdram_timing
->
cl
=
4
;
pdram_timing
->
cwl
=
2
;
pdram_timing
->
mr
[
2
]
=
LPDDR2_RL4_WL2
;
}
else
if
(
nmhz
<=
333
)
{
pdram_timing
->
cl
=
5
;
pdram_timing
->
cwl
=
2
;
pdram_timing
->
mr
[
2
]
=
LPDDR2_RL5_WL2
;
}
else
if
(
nmhz
<=
400
)
{
pdram_timing
->
cl
=
6
;
pdram_timing
->
cwl
=
3
;
pdram_timing
->
mr
[
2
]
=
LPDDR2_RL6_WL3
;
}
else
if
(
nmhz
<=
466
)
{
pdram_timing
->
cl
=
7
;
pdram_timing
->
cwl
=
4
;
pdram_timing
->
mr
[
2
]
=
LPDDR2_RL7_WL4
;
}
else
{
pdram_timing
->
cl
=
8
;
pdram_timing
->
cwl
=
4
;
pdram_timing
->
mr
[
2
]
=
LPDDR2_RL8_WL4
;
}
switch
(
timing_config
->
dramds
)
{
case
120
:
pdram_timing
->
mr
[
3
]
=
LPDDR2_DS_120
;
break
;
case
80
:
pdram_timing
->
mr
[
3
]
=
LPDDR2_DS_80
;
break
;
case
60
:
pdram_timing
->
mr
[
3
]
=
LPDDR2_DS_60
;
break
;
case
48
:
pdram_timing
->
mr
[
3
]
=
LPDDR2_DS_48
;
break
;
case
40
:
pdram_timing
->
mr
[
3
]
=
LPDDR2_DS_40
;
break
;
case
34
:
default:
pdram_timing
->
mr
[
3
]
=
LPDDR2_DS_34
;
break
;
}
pdram_timing
->
mr
[
0
]
=
0
;
pdram_timing
->
tinit1
=
(
LPDDR2_TINIT1
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
tinit2
=
LPDDR2_TINIT2
;
pdram_timing
->
tinit3
=
(
LPDDR2_TINIT3
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
tinit4
=
(
LPDDR2_TINIT4
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
tinit5
=
(
LPDDR2_TINIT5
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
trstl
=
LPDDR2_TRSTL
;
pdram_timing
->
trsth
=
(
LPDDR2_TRSTH
*
nmhz
+
999
)
/
1000
;
/*
* tREFI, average periodic refresh interval,
* 15.6us(<256Mb) 7.8us(256Mb-1Gb) 3.9us(2Gb-8Gb)
*/
if
(
ddr_capability_per_die
>=
0x10000000
)
pdram_timing
->
trefi
=
(
LPDDR2_TREFI_3_9_US
*
nmhz
+
999
)
/
1000
;
else
pdram_timing
->
trefi
=
(
LPDDR2_TREFI_7_8_US
*
nmhz
+
999
)
/
1000
;
/* base timing */
tmp
=
((
LPDDR2_TRCD
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
trcd
=
max
(
3
,
tmp
);
/*
* tRPpb, max(3tCK, 15ns(Fast) 18ns(Typ) 24ns(Slow),
*/
trppb_tmp
=
((
LPDDR2_TRP_PB
*
nmhz
+
999
)
/
1000
);
trppb_tmp
=
max
(
3
,
trppb_tmp
);
pdram_timing
->
trppb
=
trppb_tmp
;
/*
* tRPab, max(3tCK, 4-bank:15ns(Fast) 18ns(Typ) 24ns(Slow),
* 8-bank:18ns(Fast) 21ns(Typ) 27ns(Slow))
*/
trp_tmp
=
((
LPDDR2_TRP_AB_8_BANK
*
nmhz
+
999
)
/
1000
);
trp_tmp
=
max
(
3
,
trp_tmp
);
pdram_timing
->
trp
=
trp_tmp
;
twr_tmp
=
((
LPDDR2_TWR
*
nmhz
+
999
)
/
1000
);
twr_tmp
=
max
(
3
,
twr_tmp
);
pdram_timing
->
twr
=
twr_tmp
;
bl_tmp
=
(
pdram_timing
->
bl
==
16
)
?
LPDDR2_BL16
:
((
pdram_timing
->
bl
==
8
)
?
LPDDR2_BL8
:
LPDDR2_BL4
);
pdram_timing
->
mr
[
1
]
=
bl_tmp
|
LPDDR2_N_WR
(
twr_tmp
);
tmp
=
((
LPDDR2_TRTP
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
);
pdram_timing
->
trtp
=
max
(
2
,
tmp
);
tras_tmp
=
((
LPDDR2_TRAS
*
nmhz
+
999
)
/
1000
);
tras_tmp
=
max
(
3
,
tras_tmp
);
pdram_timing
->
tras_min
=
tras_tmp
;
pdram_timing
->
tras_max
=
((
LPDDR2_TRAS_MAX
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
trc
=
(
tras_tmp
+
trp_tmp
);
tmp
=
((
LPDDR2_TRRD
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
trrd
=
max
(
2
,
tmp
);
pdram_timing
->
tccd
=
LPDDR2_TCCD
;
/* tWTR, max(2tCK, 7.5ns(533-266MHz) 10ns(200-166MHz)) */
if
(
nmhz
>
200
)
tmp
=
((
LPDDR2_TWTR_GREAT_200MHZ
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
);
else
tmp
=
((
LPDDR2_TWTR_LITTLE_200MHZ
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
twtr
=
max
(
2
,
tmp
);
pdram_timing
->
trtw
=
LPDDR2_TRTW
;
if
(
nmhz
<=
200
)
pdram_timing
->
tfaw
=
(
LPDDR2_TFAW_LITTLE_200MHZ
*
nmhz
+
999
)
/
1000
;
else
pdram_timing
->
tfaw
=
(
LPDDR2_TFAW_GREAT_200MHZ
*
nmhz
+
999
)
/
1000
;
/* tRFC, 90ns(<=512Mb) 130ns(1Gb-4Gb) 210ns(8Gb) */
if
(
ddr_capability_per_die
>=
0x40000000
)
{
pdram_timing
->
trfc
=
(
LPDDR2_TRFC_8GBIT
*
nmhz
+
999
)
/
1000
;
tmp
=
(((
LPDDR2_TRFC_8GBIT
+
10
)
*
nmhz
+
999
)
/
1000
);
}
else
{
pdram_timing
->
trfc
=
(
LPDDR2_TRFC_4GBIT
*
nmhz
+
999
)
/
1000
;
tmp
=
(((
LPDDR2_TRFC_4GBIT
+
10
)
*
nmhz
+
999
)
/
1000
);
}
if
(
tmp
<
2
)
tmp
=
2
;
pdram_timing
->
txsr
=
tmp
;
pdram_timing
->
txsnr
=
tmp
;
/* tdqsck use rounded down */
pdram_timing
->
tdqsck
=
((
LPDDR2_TDQSCK_MIN
*
nmhz
+
(
nmhz
>>
1
))
/
1000
);
pdram_timing
->
tdqsck_max
=
((
LPDDR2_TDQSCK_MAX
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
);
/* pd and sr */
tmp
=
((
LPDDR2_TXP
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
);
pdram_timing
->
txp
=
max
(
2
,
tmp
);
pdram_timing
->
txpdll
=
LPDDR2_TXPDLL
;
pdram_timing
->
tdllk
=
LPDDR2_TDLLK
;
pdram_timing
->
tcke
=
LPDDR2_TCKE
;
tmp
=
((
LPDDR2_TCKESR
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
tckesr
=
max
(
3
,
tmp
);
pdram_timing
->
tcksre
=
LPDDR2_TCKSRE
;
pdram_timing
->
tcksrx
=
LPDDR2_TCKSRX
;
/* mode register timing */
pdram_timing
->
tmod
=
LPDDR2_TMOD
;
pdram_timing
->
tmrd
=
LPDDR2_TMRD
;
pdram_timing
->
tmrr
=
LPDDR2_TMRR
;
/* ZQ */
pdram_timing
->
tzqinit
=
(
LPDDR2_TZQINIT
*
nmhz
+
999
)
/
1000
;
tmp
=
((
LPDDR2_TZQCS
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
tzqcs
=
max
(
6
,
tmp
);
tmp
=
((
LPDDR2_TZQCL
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
tzqoper
=
max
(
6
,
tmp
);
tmp
=
((
LPDDR2_TZQRESET
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
tzqreset
=
max
(
3
,
tmp
);
}
#define LPDDR3_TINIT1 (100)
/* ns */
#define LPDDR3_TINIT2 (5)
/* tCK */
#define LPDDR3_TINIT3 (200000)
/* 200us */
#define LPDDR3_TINIT4 (1000)
/* 1us */
#define LPDDR3_TINIT5 (10000)
/* 10us */
#define LPDDR3_TRSTL (0)
#define LPDDR3_TRSTH (0)
/* 500us */
#define LPDDR3_TREFI_3_9_US (3900)
/* 3.9us */
/* base timging */
#define LPDDR3_TRCD (18)
/* tRCD,15ns(Fast)18ns(Typ)24ns(Slow) */
#define LPDDR3_TRP_PB (18)
/* tRPpb, 15ns(Fast) 18ns(Typ) 24ns(Slow) */
#define LPDDR3_TRP_AB (21)
/* tRPab, 18ns(Fast) 21ns(Typ) 27ns(Slow) */
#define LPDDR3_TWR (15)
/* tWR, max(4tCK,15ns) */
#define LPDDR3_TRTP (7)
/* tRTP, max(4tCK, 7.5ns) */
#define LPDDR3_TRRD (10)
/* tRRD, max(2tCK,10ns) */
#define LPDDR3_TCCD (4)
/* tCK */
#define LPDDR3_TWTR (7)
/* tWTR, max(4tCK, 7.5ns) */
#define LPDDR3_TRTW (0)
/* tCK register min valid value */
#define LPDDR3_TRAS_MAX (70000)
/* 70us */
#define LPDDR3_TRAS (42)
/* tRAS, max(3tCK,42ns) */
#define LPDDR3_TFAW (50)
/* tFAW,max(8tCK, 50ns) */
#define LPDDR3_TRFC_8GBIT (210)
/* tRFC, 130ns(4Gb) 210ns(>4Gb) */
#define LPDDR3_TRFC_4GBIT (130)
/* ns */
#define LPDDR3_TDQSCK_MIN (2)
/* tDQSCKmin,2.5ns */
#define LPDDR3_TDQSCK_MAX (5)
/* tDQSCKmax,5.5ns */
/* pd and sr */
#define LPDDR3_TXP (7)
/* tXP, max(3tCK,7.5ns) */
#define LPDDR3_TXPDLL (0)
#define LPDDR3_TCKE (7)
/* tCKE, (max 7.5ns,3 tCK) */
#define LPDDR3_TCKESR (15)
/* tCKESR, max(3tCK,15ns) */
#define LPDDR3_TCKSRE (2)
/* tCKSRE=tCPDED, 2 tCK */
#define LPDDR3_TCKSRX (2)
/* tCKSRX, 2 tCK */
/* mode register timing */
#define LPDDR3_TMOD (0)
#define LPDDR3_TMRD (14)
/* tMRD, (=tMRW), max(14ns, 10 tCK) */
#define LPDDR3_TMRR (4)
/* tMRR, 4 tCK */
#define LPDDR3_TMRRI LPDDR3_TRCD
/* ODT */
#define LPDDR3_TODTON (3)
/* 3.5ns */
/* ZQ */
#define LPDDR3_TZQINIT (1000)
/* 1us */
#define LPDDR3_TZQCS (90)
/* tZQCS, 90ns */
#define LPDDR3_TZQCL (360)
/* 360ns */
#define LPDDR3_TZQRESET (50)
/* ZQreset, max(3tCK,50ns) */
/* write leveling */
#define LPDDR3_TWLMRD (40)
/* ns */
#define LPDDR3_TWLO (20)
/* ns */
#define LPDDR3_TWLDQSEN (25)
/* ns */
/* CA training */
#define LPDDR3_TCACKEL (10)
/* tCK */
#define LPDDR3_TCAENT (10)
/* tCK */
#define LPDDR3_TCAMRD (20)
/* tCK */
#define LPDDR3_TCACKEH (10)
/* tCK */
#define LPDDR3_TCAEXT (10)
/* tCK */
#define LPDDR3_TADR (20)
/* ns */
#define LPDDR3_TMRZ (3)
/* ns */
/*
* Description: depend on input parameter "timing_config",
* and calculate all lpddr3
* spec timing to "pdram_timing"
* parameters:
* input: timing_config
* output: pdram_timing
*/
static
void
lpddr3_get_parameter
(
struct
timing_related_config
*
timing_config
,
struct
dram_timing_t
*
pdram_timing
)
{
uint32_t
nmhz
=
timing_config
->
freq
;
uint32_t
ddr_capability_per_die
=
get_max_die_capability
(
timing_config
);
uint32_t
tmp
,
trp_tmp
,
trppb_tmp
,
tras_tmp
,
twr_tmp
,
bl_tmp
;
memset
((
void
*
)
pdram_timing
,
0
,
sizeof
(
struct
dram_timing_t
));
pdram_timing
->
mhz
=
nmhz
;
pdram_timing
->
al
=
0
;
pdram_timing
->
bl
=
timing_config
->
bl
;
/*
* Only support Write Latency Set A here
* 1066 933 800 733 667 600 533 400 166
* RL, 16 14 12 11 10 9 8 6 3
* WL, 8 8 6 6 6 5 4 3 1
*/
if
(
nmhz
<=
400
)
{
pdram_timing
->
cl
=
6
;
pdram_timing
->
cwl
=
3
;
pdram_timing
->
mr
[
2
]
=
LPDDR3_RL6_WL3
;
}
else
if
(
nmhz
<=
533
)
{
pdram_timing
->
cl
=
8
;
pdram_timing
->
cwl
=
4
;
pdram_timing
->
mr
[
2
]
=
LPDDR3_RL8_WL4
;
}
else
if
(
nmhz
<=
600
)
{
pdram_timing
->
cl
=
9
;
pdram_timing
->
cwl
=
5
;
pdram_timing
->
mr
[
2
]
=
LPDDR3_RL9_WL5
;
}
else
if
(
nmhz
<=
667
)
{
pdram_timing
->
cl
=
10
;
pdram_timing
->
cwl
=
6
;
pdram_timing
->
mr
[
2
]
=
LPDDR3_RL10_WL6
;
}
else
if
(
nmhz
<=
733
)
{
pdram_timing
->
cl
=
11
;
pdram_timing
->
cwl
=
6
;
pdram_timing
->
mr
[
2
]
=
LPDDR3_RL11_WL6
;
}
else
if
(
nmhz
<=
800
)
{
pdram_timing
->
cl
=
12
;
pdram_timing
->
cwl
=
6
;
pdram_timing
->
mr
[
2
]
=
LPDDR3_RL12_WL6
;
}
else
if
(
nmhz
<=
933
)
{
pdram_timing
->
cl
=
14
;
pdram_timing
->
cwl
=
8
;
pdram_timing
->
mr
[
2
]
=
LPDDR3_RL14_WL8
;
}
else
{
pdram_timing
->
cl
=
16
;
pdram_timing
->
cwl
=
8
;
pdram_timing
->
mr
[
2
]
=
LPDDR3_RL16_WL8
;
}
switch
(
timing_config
->
dramds
)
{
case
80
:
pdram_timing
->
mr
[
3
]
=
LPDDR3_DS_80
;
break
;
case
60
:
pdram_timing
->
mr
[
3
]
=
LPDDR3_DS_60
;
break
;
case
48
:
pdram_timing
->
mr
[
3
]
=
LPDDR3_DS_48
;
break
;
case
40
:
pdram_timing
->
mr
[
3
]
=
LPDDR3_DS_40
;
break
;
case
3440
:
pdram_timing
->
mr
[
3
]
=
LPDDR3_DS_34D_40U
;
break
;
case
4048
:
pdram_timing
->
mr
[
3
]
=
LPDDR3_DS_40D_48U
;
break
;
case
3448
:
pdram_timing
->
mr
[
3
]
=
LPDDR3_DS_34D_48U
;
break
;
case
34
:
default:
pdram_timing
->
mr
[
3
]
=
LPDDR3_DS_34
;
break
;
}
pdram_timing
->
mr
[
0
]
=
0
;
switch
(
timing_config
->
dramodt
)
{
case
60
:
pdram_timing
->
mr11
=
LPDDR3_ODT_60
;
break
;
case
120
:
pdram_timing
->
mr11
=
LPDDR3_ODT_120
;
break
;
case
240
:
default:
pdram_timing
->
mr11
=
LPDDR3_ODT_240
;
break
;
}
pdram_timing
->
tinit1
=
(
LPDDR3_TINIT1
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
tinit2
=
LPDDR3_TINIT2
;
pdram_timing
->
tinit3
=
(
LPDDR3_TINIT3
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
tinit4
=
(
LPDDR3_TINIT4
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
tinit5
=
(
LPDDR3_TINIT5
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
trstl
=
LPDDR3_TRSTL
;
pdram_timing
->
trsth
=
(
LPDDR3_TRSTH
*
nmhz
+
999
)
/
1000
;
/* tREFI, average periodic refresh interval, 3.9us(4Gb-16Gb) */
pdram_timing
->
trefi
=
(
LPDDR3_TREFI_3_9_US
*
nmhz
+
999
)
/
1000
;
/* base timing */
tmp
=
((
LPDDR3_TRCD
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
trcd
=
max
(
3
,
tmp
);
trppb_tmp
=
((
LPDDR3_TRP_PB
*
nmhz
+
999
)
/
1000
);
trppb_tmp
=
max
(
3
,
trppb_tmp
);
pdram_timing
->
trppb
=
trppb_tmp
;
trp_tmp
=
((
LPDDR3_TRP_AB
*
nmhz
+
999
)
/
1000
);
trp_tmp
=
max
(
3
,
trp_tmp
);
pdram_timing
->
trp
=
trp_tmp
;
twr_tmp
=
((
LPDDR3_TWR
*
nmhz
+
999
)
/
1000
);
twr_tmp
=
max
(
4
,
twr_tmp
);
pdram_timing
->
twr
=
twr_tmp
;
if
(
twr_tmp
<=
6
)
twr_tmp
=
6
;
else
if
(
twr_tmp
<=
8
)
twr_tmp
=
8
;
else
if
(
twr_tmp
<=
12
)
twr_tmp
=
twr_tmp
;
else
if
(
twr_tmp
<=
14
)
twr_tmp
=
14
;
else
twr_tmp
=
16
;
if
(
twr_tmp
>
9
)
pdram_timing
->
mr
[
2
]
|=
(
1
<<
4
);
/*enable nWR > 9*/
twr_tmp
=
(
twr_tmp
>
9
)
?
(
twr_tmp
-
10
)
:
(
twr_tmp
-
2
);
bl_tmp
=
LPDDR3_BL8
;
pdram_timing
->
mr
[
1
]
=
bl_tmp
|
LPDDR3_N_WR
(
twr_tmp
);
tmp
=
((
LPDDR3_TRTP
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
);
pdram_timing
->
trtp
=
max
(
4
,
tmp
);
tras_tmp
=
((
LPDDR3_TRAS
*
nmhz
+
999
)
/
1000
);
tras_tmp
=
max
(
3
,
tras_tmp
);
pdram_timing
->
tras_min
=
tras_tmp
;
pdram_timing
->
trc
=
(
tras_tmp
+
trp_tmp
);
tmp
=
((
LPDDR3_TRRD
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
trrd
=
max
(
2
,
tmp
);
pdram_timing
->
tccd
=
LPDDR3_TCCD
;
tmp
=
((
LPDDR3_TWTR
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
);
pdram_timing
->
twtr
=
max
(
4
,
tmp
);
pdram_timing
->
trtw
=
((
LPDDR3_TRTW
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
tras_max
=
((
LPDDR3_TRAS_MAX
*
nmhz
+
999
)
/
1000
);
tmp
=
(
LPDDR3_TFAW
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
tfaw
=
max
(
8
,
tmp
);
if
(
ddr_capability_per_die
>
0x20000000
)
{
pdram_timing
->
trfc
=
(
LPDDR3_TRFC_8GBIT
*
nmhz
+
999
)
/
1000
;
tmp
=
(((
LPDDR3_TRFC_8GBIT
+
10
)
*
nmhz
+
999
)
/
1000
);
}
else
{
pdram_timing
->
trfc
=
(
LPDDR3_TRFC_4GBIT
*
nmhz
+
999
)
/
1000
;
tmp
=
(((
LPDDR3_TRFC_4GBIT
+
10
)
*
nmhz
+
999
)
/
1000
);
}
pdram_timing
->
txsr
=
max
(
2
,
tmp
);
pdram_timing
->
txsnr
=
max
(
2
,
tmp
);
/* tdqsck use rounded down */
pdram_timing
->
tdqsck
=
((
LPDDR3_TDQSCK_MIN
*
nmhz
+
(
nmhz
>>
1
))
/
1000
);
pdram_timing
->
tdqsck_max
=
((
LPDDR3_TDQSCK_MAX
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
);
/*pd and sr*/
tmp
=
((
LPDDR3_TXP
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
);
pdram_timing
->
txp
=
max
(
3
,
tmp
);
pdram_timing
->
txpdll
=
LPDDR3_TXPDLL
;
tmp
=
((
LPDDR3_TCKE
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
);
pdram_timing
->
tcke
=
max
(
3
,
tmp
);
tmp
=
((
LPDDR3_TCKESR
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
tckesr
=
max
(
3
,
tmp
);
pdram_timing
->
tcksre
=
LPDDR3_TCKSRE
;
pdram_timing
->
tcksrx
=
LPDDR3_TCKSRX
;
/*mode register timing*/
pdram_timing
->
tmod
=
LPDDR3_TMOD
;
tmp
=
((
LPDDR3_TMRD
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
tmrd
=
max
(
10
,
tmp
);
pdram_timing
->
tmrr
=
LPDDR3_TMRR
;
tmp
=
((
LPDDR3_TRCD
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
tmrri
=
max
(
3
,
tmp
);
/* ODT */
pdram_timing
->
todton
=
(
LPDDR3_TODTON
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
;
/* ZQ */
pdram_timing
->
tzqinit
=
(
LPDDR3_TZQINIT
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
tzqcs
=
((
LPDDR3_TZQCS
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
tzqoper
=
((
LPDDR3_TZQCL
*
nmhz
+
999
)
/
1000
);
tmp
=
((
LPDDR3_TZQRESET
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
tzqreset
=
max
(
3
,
tmp
);
/* write leveling */
pdram_timing
->
twlmrd
=
(
LPDDR3_TWLMRD
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
twlo
=
(
LPDDR3_TWLO
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
twldqsen
=
(
LPDDR3_TWLDQSEN
*
nmhz
+
999
)
/
1000
;
/* CA training */
pdram_timing
->
tcackel
=
LPDDR3_TCACKEL
;
pdram_timing
->
tcaent
=
LPDDR3_TCAENT
;
pdram_timing
->
tcamrd
=
LPDDR3_TCAMRD
;
pdram_timing
->
tcackeh
=
LPDDR3_TCACKEH
;
pdram_timing
->
tcaext
=
LPDDR3_TCAEXT
;
pdram_timing
->
tadr
=
(
LPDDR3_TADR
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
tmrz
=
(
LPDDR3_TMRZ
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
tcacd
=
pdram_timing
->
tadr
+
2
;
}
#define LPDDR4_TINIT1 (200000)
/* 200us */
#define LPDDR4_TINIT2 (10)
/* 10ns */
#define LPDDR4_TINIT3 (2000000)
/* 2ms */
#define LPDDR4_TINIT4 (5)
/* tCK */
#define LPDDR4_TINIT5 (2000)
/* 2us */
#define LPDDR4_TRSTL LPDDR4_TINIT1
#define LPDDR4_TRSTH LPDDR4_TINIT3
#define LPDDR4_TREFI_3_9_US (3900)
/* 3.9us */
/* base timging */
#define LPDDR4_TRCD (18)
/* tRCD, max(18ns,4tCK) */
#define LPDDR4_TRP_PB (18)
/* tRPpb, max(18ns, 4tCK) */
#define LPDDR4_TRP_AB (21)
/* tRPab, max(21ns, 4tCK) */
#define LPDDR4_TRRD (10)
/* tRRD, max(4tCK,10ns) */
#define LPDDR4_TCCD_BL16 (8)
/* tCK */
#define LPDDR4_TCCD_BL32 (16)
/* tCK */
#define LPDDR4_TWTR (10)
/* tWTR, max(8tCK, 10ns) */
#define LPDDR4_TRTW (0)
/* tCK register min valid value */
#define LPDDR4_TRAS_MAX (70000)
/* 70us */
#define LPDDR4_TRAS (42)
/* tRAS, max(3tCK,42ns) */
#define LPDDR4_TFAW (40)
/* tFAW,min 40ns) */
#define LPDDR4_TRFC_12GBIT (280)
/* tRFC, 280ns(>=12Gb) */
#define LPDDR4_TRFC_6GBIT (180)
/* 6Gb/8Gb 180ns */
#define LPDDR4_TRFC_4GBIT (130)
/* 4Gb 130ns */
#define LPDDR4_TDQSCK_MIN (1)
/* tDQSCKmin,1.5ns */
#define LPDDR4_TDQSCK_MAX (3)
/* tDQSCKmax,3.5ns */
#define LPDDR4_TPPD (4)
/* tCK */
/* pd and sr */
#define LPDDR4_TXP (7)
/* tXP, max(5tCK,7.5ns) */
#define LPDDR4_TCKE (7)
/* tCKE, max(7.5ns,4 tCK) */
#define LPDDR4_TESCKE (1)
/* tESCKE, max(1.75ns, 3tCK) */
#define LPDDR4_TSR (15)
/* tSR, max(15ns, 3tCK) */
#define LPDDR4_TCMDCKE (1)
/* max(1.75ns, 3tCK) */
#define LPDDR4_TCSCKE (1)
/* 1.75ns */
#define LPDDR4_TCKELCS (5)
/* max(5ns, 5tCK) */
#define LPDDR4_TCSCKEH (1)
/* 1.75ns */
#define LPDDR4_TCKEHCS (7)
/* max(7.5ns, 5tCK) */
#define LPDDR4_TMRWCKEL (14)
/* max(14ns, 10tCK) */
#define LPDDR4_TCKELCMD (7)
/* max(7.5ns, 3tCK) */
#define LPDDR4_TCKEHCMD (7)
/* max(7.5ns, 3tCK) */
#define LPDDR4_TCKELPD (7)
/* max(7.5ns, 3tCK) */
#define LPDDR4_TCKCKEL (7)
/* max(7.5ns, 3tCK) */
/* mode register timing */
#define LPDDR4_TMRD (14)
/* tMRD, (=tMRW), max(14ns, 10 tCK) */
#define LPDDR4_TMRR (8)
/* tMRR, 8 tCK */
/* ODT */
#define LPDDR4_TODTON (3)
/* 3.5ns */
/* ZQ */
#define LPDDR4_TZQCAL (1000)
/* 1us */
#define LPDDR4_TZQLAT (30)
/* tZQLAT, max(30ns,8tCK) */
#define LPDDR4_TZQRESET (50)
/* ZQreset, max(3tCK,50ns) */
#define LPDDR4_TZQCKE (1)
/* tZQCKE, max(1.75ns, 3tCK) */
/* write leveling */
#define LPDDR4_TWLMRD (40)
/* tCK */
#define LPDDR4_TWLO (20)
/* ns */
#define LPDDR4_TWLDQSEN (20)
/* tCK */
/* CA training */
#define LPDDR4_TCAENT (250)
/* ns */
#define LPDDR4_TADR (20)
/* ns */
#define LPDDR4_TMRZ (1)
/* 1.5ns */
#define LPDDR4_TVREF_LONG (250)
/* ns */
#define LPDDR4_TVREF_SHORT (100)
/* ns */
/* VRCG */
#define LPDDR4_TVRCG_ENABLE (200)
/* ns */
#define LPDDR4_TVRCG_DISABLE (100)
/* ns */
/* FSP */
#define LPDDR4_TFC_LONG (250)
/* ns */
#define LPDDR4_TCKFSPE (7)
/* max(7.5ns, 4tCK) */
#define LPDDR4_TCKFSPX (7)
/* max(7.5ns, 4tCK) */
/*
* Description: depend on input parameter "timing_config",
* and calculate all lpddr4
* spec timing to "pdram_timing"
* parameters:
* input: timing_config
* output: pdram_timing
*/
static
void
lpddr4_get_parameter
(
struct
timing_related_config
*
timing_config
,
struct
dram_timing_t
*
pdram_timing
)
{
uint32_t
nmhz
=
timing_config
->
freq
;
uint32_t
ddr_capability_per_die
=
get_max_die_capability
(
timing_config
);
uint32_t
tmp
,
trp_tmp
,
trppb_tmp
,
tras_tmp
;
memset
((
void
*
)
pdram_timing
,
0
,
sizeof
(
struct
dram_timing_t
));
pdram_timing
->
mhz
=
nmhz
;
pdram_timing
->
al
=
0
;
pdram_timing
->
bl
=
timing_config
->
bl
;
/*
* Only support Write Latency Set A here
* 2133 1866 1600 1333 1066 800 533 266
* RL, 36 32 28 24 20 14 10 6
* WL, 18 16 14 12 10 8 6 4
* nWR, 40 34 30 24 20 16 10 6
* nRTP,16 14 12 10 8 8 8 8
*/
tmp
=
(
timing_config
->
bl
==
32
)
?
1
:
0
;
/*
* we always use WR preamble = 2tCK
* RD preamble = Static
*/
tmp
|=
(
1
<<
2
);
if
(
nmhz
<=
266
)
{
pdram_timing
->
cl
=
6
;
pdram_timing
->
cwl
=
4
;
pdram_timing
->
twr
=
6
;
pdram_timing
->
trtp
=
8
;
pdram_timing
->
mr
[
2
]
=
LPDDR4_RL6_NRTP8
|
LPDDR4_A_WL4
;
}
else
if
(
nmhz
<=
533
)
{
if
(
timing_config
->
rdbi
)
{
pdram_timing
->
cl
=
12
;
pdram_timing
->
mr
[
2
]
=
LPDDR4_RL12_NRTP8
|
LPDDR4_A_WL6
;
}
else
{
pdram_timing
->
cl
=
10
;
pdram_timing
->
mr
[
2
]
=
LPDDR4_RL10_NRTP8
|
LPDDR4_A_WL6
;
}
pdram_timing
->
cwl
=
6
;
pdram_timing
->
twr
=
10
;
pdram_timing
->
trtp
=
8
;
tmp
|=
(
1
<<
4
);
}
else
if
(
nmhz
<=
800
)
{
if
(
timing_config
->
rdbi
)
{
pdram_timing
->
cl
=
16
;
pdram_timing
->
mr
[
2
]
=
LPDDR4_RL16_NRTP8
|
LPDDR4_A_WL8
;
}
else
{
pdram_timing
->
cl
=
14
;
pdram_timing
->
mr
[
2
]
=
LPDDR4_RL14_NRTP8
|
LPDDR4_A_WL8
;
}
pdram_timing
->
cwl
=
8
;
pdram_timing
->
twr
=
16
;
pdram_timing
->
trtp
=
8
;
tmp
|=
(
2
<<
4
);
}
else
if
(
nmhz
<=
1066
)
{
if
(
timing_config
->
rdbi
)
{
pdram_timing
->
cl
=
22
;
pdram_timing
->
mr
[
2
]
=
LPDDR4_RL22_NRTP8
|
LPDDR4_A_WL10
;
}
else
{
pdram_timing
->
cl
=
20
;
pdram_timing
->
mr
[
2
]
=
LPDDR4_RL20_NRTP8
|
LPDDR4_A_WL10
;
}
pdram_timing
->
cwl
=
10
;
pdram_timing
->
twr
=
20
;
pdram_timing
->
trtp
=
8
;
tmp
|=
(
3
<<
4
);
}
else
if
(
nmhz
<=
1333
)
{
if
(
timing_config
->
rdbi
)
{
pdram_timing
->
cl
=
28
;
pdram_timing
->
mr
[
2
]
=
LPDDR4_RL28_NRTP10
|
LPDDR4_A_WL12
;
}
else
{
pdram_timing
->
cl
=
24
;
pdram_timing
->
mr
[
2
]
=
LPDDR4_RL24_NRTP10
|
LPDDR4_A_WL12
;
}
pdram_timing
->
cwl
=
12
;
pdram_timing
->
twr
=
24
;
pdram_timing
->
trtp
=
10
;
tmp
|=
(
4
<<
4
);
}
else
if
(
nmhz
<=
1600
)
{
if
(
timing_config
->
rdbi
)
{
pdram_timing
->
cl
=
32
;
pdram_timing
->
mr
[
2
]
=
LPDDR4_RL32_NRTP12
|
LPDDR4_A_WL14
;
}
else
{
pdram_timing
->
cl
=
28
;
pdram_timing
->
mr
[
2
]
=
LPDDR4_RL28_NRTP12
|
LPDDR4_A_WL14
;
}
pdram_timing
->
cwl
=
14
;
pdram_timing
->
twr
=
30
;
pdram_timing
->
trtp
=
12
;
tmp
|=
(
5
<<
4
);
}
else
if
(
nmhz
<=
1866
)
{
if
(
timing_config
->
rdbi
)
{
pdram_timing
->
cl
=
36
;
pdram_timing
->
mr
[
2
]
=
LPDDR4_RL36_NRTP14
|
LPDDR4_A_WL16
;
}
else
{
pdram_timing
->
cl
=
32
;
pdram_timing
->
mr
[
2
]
=
LPDDR4_RL32_NRTP14
|
LPDDR4_A_WL16
;
}
pdram_timing
->
cwl
=
16
;
pdram_timing
->
twr
=
34
;
pdram_timing
->
trtp
=
14
;
tmp
|=
(
6
<<
4
);
}
else
{
if
(
timing_config
->
rdbi
)
{
pdram_timing
->
cl
=
40
;
pdram_timing
->
mr
[
2
]
=
LPDDR4_RL40_NRTP16
|
LPDDR4_A_WL18
;
}
else
{
pdram_timing
->
cl
=
36
;
pdram_timing
->
mr
[
2
]
=
LPDDR4_RL36_NRTP16
|
LPDDR4_A_WL18
;
}
pdram_timing
->
cwl
=
18
;
pdram_timing
->
twr
=
40
;
pdram_timing
->
trtp
=
16
;
tmp
|=
(
7
<<
4
);
}
pdram_timing
->
mr
[
1
]
=
tmp
;
tmp
=
(
timing_config
->
rdbi
?
LPDDR4_DBI_RD_EN
:
0
)
|
(
timing_config
->
wdbi
?
LPDDR4_DBI_WR_EN
:
0
);
switch
(
timing_config
->
dramds
)
{
case
240
:
pdram_timing
->
mr
[
3
]
=
LPDDR4_PDDS_240
|
tmp
;
break
;
case
120
:
pdram_timing
->
mr
[
3
]
=
LPDDR4_PDDS_120
|
tmp
;
break
;
case
80
:
pdram_timing
->
mr
[
3
]
=
LPDDR4_PDDS_80
|
tmp
;
break
;
case
60
:
pdram_timing
->
mr
[
3
]
=
LPDDR4_PDDS_60
|
tmp
;
break
;
case
48
:
pdram_timing
->
mr
[
3
]
=
LPDDR4_PDDS_48
|
tmp
;
break
;
case
40
:
default:
pdram_timing
->
mr
[
3
]
=
LPDDR4_PDDS_40
|
tmp
;
break
;
}
pdram_timing
->
mr
[
0
]
=
0
;
switch
(
timing_config
->
dramodt
)
{
case
240
:
tmp
=
LPDDR4_DQODT_240
;
break
;
case
120
:
tmp
=
LPDDR4_DQODT_120
;
break
;
case
80
:
tmp
=
LPDDR4_DQODT_80
;
break
;
case
60
:
tmp
=
LPDDR4_DQODT_60
;
break
;
case
48
:
tmp
=
LPDDR4_DQODT_48
;
break
;
case
40
:
default:
tmp
=
LPDDR4_DQODT_40
;
break
;
}
switch
(
timing_config
->
caodt
)
{
case
240
:
pdram_timing
->
mr11
=
LPDDR4_CAODT_240
|
tmp
;
break
;
case
120
:
pdram_timing
->
mr11
=
LPDDR4_CAODT_120
|
tmp
;
break
;
case
80
:
pdram_timing
->
mr11
=
LPDDR4_CAODT_80
|
tmp
;
break
;
case
60
:
pdram_timing
->
mr11
=
LPDDR4_CAODT_60
|
tmp
;
break
;
case
48
:
pdram_timing
->
mr11
=
LPDDR4_CAODT_48
|
tmp
;
break
;
case
40
:
default:
pdram_timing
->
mr11
=
LPDDR4_CAODT_40
|
tmp
;
break
;
}
pdram_timing
->
tinit1
=
(
LPDDR4_TINIT1
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
tinit2
=
(
LPDDR4_TINIT2
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
tinit3
=
(
LPDDR4_TINIT3
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
tinit4
=
(
LPDDR4_TINIT4
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
tinit5
=
(
LPDDR4_TINIT5
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
trstl
=
(
LPDDR4_TRSTL
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
trsth
=
(
LPDDR4_TRSTH
*
nmhz
+
999
)
/
1000
;
/* tREFI, average periodic refresh interval, 3.9us(4Gb-16Gb) */
pdram_timing
->
trefi
=
(
LPDDR4_TREFI_3_9_US
*
nmhz
+
999
)
/
1000
;
/* base timing */
tmp
=
((
LPDDR4_TRCD
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
trcd
=
max
(
4
,
tmp
);
trppb_tmp
=
((
LPDDR4_TRP_PB
*
nmhz
+
999
)
/
1000
);
trppb_tmp
=
max
(
4
,
trppb_tmp
);
pdram_timing
->
trppb
=
trppb_tmp
;
trp_tmp
=
((
LPDDR4_TRP_AB
*
nmhz
+
999
)
/
1000
);
trp_tmp
=
max
(
4
,
trp_tmp
);
pdram_timing
->
trp
=
trp_tmp
;
tras_tmp
=
((
LPDDR4_TRAS
*
nmhz
+
999
)
/
1000
);
tras_tmp
=
max
(
3
,
tras_tmp
);
pdram_timing
->
tras_min
=
tras_tmp
;
pdram_timing
->
trc
=
(
tras_tmp
+
trp_tmp
);
tmp
=
((
LPDDR4_TRRD
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
trrd
=
max
(
4
,
tmp
);
if
(
timing_config
->
bl
==
32
)
pdram_timing
->
tccd
=
LPDDR4_TCCD_BL16
;
else
pdram_timing
->
tccd
=
LPDDR4_TCCD_BL32
;
pdram_timing
->
tccdmw
=
4
*
pdram_timing
->
tccd
;
tmp
=
((
LPDDR4_TWTR
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
twtr
=
max
(
8
,
tmp
);
pdram_timing
->
trtw
=
((
LPDDR4_TRTW
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
tras_max
=
((
LPDDR4_TRAS_MAX
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
tfaw
=
(
LPDDR4_TFAW
*
nmhz
+
999
)
/
1000
;
if
(
ddr_capability_per_die
>
0x60000000
)
{
/* >= 12Gb */
pdram_timing
->
trfc
=
(
LPDDR4_TRFC_12GBIT
*
nmhz
+
999
)
/
1000
;
tmp
=
(((
LPDDR4_TRFC_12GBIT
+
7
)
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
);
}
else
if
(
ddr_capability_per_die
>
0x30000000
)
{
pdram_timing
->
trfc
=
(
LPDDR4_TRFC_6GBIT
*
nmhz
+
999
)
/
1000
;
tmp
=
(((
LPDDR4_TRFC_6GBIT
+
7
)
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
);
}
else
{
pdram_timing
->
trfc
=
(
LPDDR4_TRFC_4GBIT
*
nmhz
+
999
)
/
1000
;
tmp
=
(((
LPDDR4_TRFC_4GBIT
+
7
)
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
);
}
pdram_timing
->
txsr
=
max
(
2
,
tmp
);
pdram_timing
->
txsnr
=
max
(
2
,
tmp
);
/* tdqsck use rounded down */
pdram_timing
->
tdqsck
=
((
LPDDR4_TDQSCK_MIN
*
nmhz
+
(
nmhz
>>
1
))
/
1000
);
pdram_timing
->
tdqsck_max
=
((
LPDDR4_TDQSCK_MAX
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
);
pdram_timing
->
tppd
=
LPDDR4_TPPD
;
/* pd and sr */
tmp
=
((
LPDDR4_TXP
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
);
pdram_timing
->
txp
=
max
(
5
,
tmp
);
tmp
=
((
LPDDR4_TCKE
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
);
pdram_timing
->
tcke
=
max
(
4
,
tmp
);
tmp
=
((
LPDDR4_TESCKE
*
nmhz
+
((
nmhz
*
3
)
/
4
)
+
999
)
/
1000
);
pdram_timing
->
tescke
=
max
(
3
,
tmp
);
tmp
=
((
LPDDR4_TSR
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
tsr
=
max
(
3
,
tmp
);
tmp
=
((
LPDDR4_TCMDCKE
*
nmhz
+
((
nmhz
*
3
)
/
4
)
+
999
)
/
1000
);
pdram_timing
->
tcmdcke
=
max
(
3
,
tmp
);
pdram_timing
->
tcscke
=
((
LPDDR4_TCSCKE
*
nmhz
+
((
nmhz
*
3
)
/
4
)
+
999
)
/
1000
);
tmp
=
((
LPDDR4_TCKELCS
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
tckelcs
=
max
(
5
,
tmp
);
pdram_timing
->
tcsckeh
=
((
LPDDR4_TCSCKEH
*
nmhz
+
((
nmhz
*
3
)
/
4
)
+
999
)
/
1000
);
tmp
=
((
LPDDR4_TCKEHCS
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
);
pdram_timing
->
tckehcs
=
max
(
5
,
tmp
);
tmp
=
((
LPDDR4_TMRWCKEL
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
tmrwckel
=
max
(
10
,
tmp
);
tmp
=
((
LPDDR4_TCKELCMD
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
);
pdram_timing
->
tckelcmd
=
max
(
3
,
tmp
);
tmp
=
((
LPDDR4_TCKEHCMD
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
);
pdram_timing
->
tckehcmd
=
max
(
3
,
tmp
);
tmp
=
((
LPDDR4_TCKELPD
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
);
pdram_timing
->
tckelpd
=
max
(
3
,
tmp
);
tmp
=
((
LPDDR4_TCKCKEL
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
);
pdram_timing
->
tckckel
=
max
(
3
,
tmp
);
/* mode register timing */
tmp
=
((
LPDDR4_TMRD
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
tmrd
=
max
(
10
,
tmp
);
pdram_timing
->
tmrr
=
LPDDR4_TMRR
;
pdram_timing
->
tmrri
=
pdram_timing
->
trcd
+
3
;
/* ODT */
pdram_timing
->
todton
=
(
LPDDR4_TODTON
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
;
/* ZQ */
pdram_timing
->
tzqcal
=
(
LPDDR4_TZQCAL
*
nmhz
+
999
)
/
1000
;
tmp
=
((
LPDDR4_TZQLAT
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
tzqlat
=
max
(
8
,
tmp
);
tmp
=
((
LPDDR4_TZQRESET
*
nmhz
+
999
)
/
1000
);
pdram_timing
->
tzqreset
=
max
(
3
,
tmp
);
tmp
=
((
LPDDR4_TZQCKE
*
nmhz
+
((
nmhz
*
3
)
/
4
)
+
999
)
/
1000
);
pdram_timing
->
tzqcke
=
max
(
3
,
tmp
);
/* write leveling */
pdram_timing
->
twlmrd
=
LPDDR4_TWLMRD
;
pdram_timing
->
twlo
=
(
LPDDR4_TWLO
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
twldqsen
=
LPDDR4_TWLDQSEN
;
/* CA training */
pdram_timing
->
tcaent
=
(
LPDDR4_TCAENT
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
tadr
=
(
LPDDR4_TADR
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
tmrz
=
(
LPDDR4_TMRZ
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
;
pdram_timing
->
tvref_long
=
(
LPDDR4_TVREF_LONG
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
tvref_short
=
(
LPDDR4_TVREF_SHORT
*
nmhz
+
999
)
/
1000
;
/* VRCG */
pdram_timing
->
tvrcg_enable
=
(
LPDDR4_TVRCG_ENABLE
*
nmhz
+
999
)
/
1000
;
pdram_timing
->
tvrcg_disable
=
(
LPDDR4_TVRCG_DISABLE
*
nmhz
+
999
)
/
1000
;
/* FSP */
pdram_timing
->
tfc_long
=
(
LPDDR4_TFC_LONG
*
nmhz
+
999
)
/
1000
;
tmp
=
(
LPDDR4_TCKFSPE
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
;
pdram_timing
->
tckfspe
=
max
(
4
,
tmp
);
tmp
=
(
LPDDR4_TCKFSPX
*
nmhz
+
(
nmhz
>>
1
)
+
999
)
/
1000
;
pdram_timing
->
tckfspx
=
max
(
4
,
tmp
);
}
/*
* Description: depend on input parameter "timing_config",
* and calculate correspond "dram_type"
* spec timing to "pdram_timing"
* parameters:
* input: timing_config
* output: pdram_timing
* NOTE: MR ODT is set, need to disable by controller
*/
void
dram_get_parameter
(
struct
timing_related_config
*
timing_config
,
struct
dram_timing_t
*
pdram_timing
)
{
switch
(
timing_config
->
dram_type
)
{
case
DDR3
:
ddr3_get_parameter
(
timing_config
,
pdram_timing
);
break
;
case
LPDDR2
:
lpddr2_get_parameter
(
timing_config
,
pdram_timing
);
break
;
case
LPDDR3
:
lpddr3_get_parameter
(
timing_config
,
pdram_timing
);
break
;
case
LPDDR4
:
lpddr4_get_parameter
(
timing_config
,
pdram_timing
);
break
;
}
}
plat/rockchip/rk3399/drivers/dram/dram_spec_timing.h
0 → 100644
View file @
c2229abd
/*
* 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 _DRAM_SPEC_TIMING_HEAD_
#define _DRAM_SPEC_TIMING_HEAD_
#include <stdint.h>
enum
{
DDR3
=
3
,
LPDDR2
=
5
,
LPDDR3
=
6
,
LPDDR4
=
7
,
UNUSED
=
0xFF
};
enum
ddr3_speed_rate
{
/* 5-5-5 */
DDR3_800D
=
0
,
/* 6-6-6 */
DDR3_800E
=
1
,
/* 6-6-6 */
DDR3_1066E
=
2
,
/* 7-7-7 */
DDR3_1066F
=
3
,
/* 8-8-8 */
DDR3_1066G
=
4
,
/* 7-7-7 */
DDR3_1333F
=
5
,
/* 8-8-8 */
DDR3_1333G
=
6
,
/* 9-9-9 */
DDR3_1333H
=
7
,
/* 10-10-10 */
DDR3_1333J
=
8
,
/* 8-8-8 */
DDR3_1600G
=
9
,
/* 9-9-9 */
DDR3_1600H
=
10
,
/* 10-10-10 */
DDR3_1600J
=
11
,
/* 11-11-11 */
DDR3_1600K
=
12
,
/* 10-10-10 */
DDR3_1866J
=
13
,
/* 11-11-11 */
DDR3_1866K
=
14
,
/* 12-12-12 */
DDR3_1866L
=
15
,
/* 13-13-13 */
DDR3_1866M
=
16
,
/* 11-11-11 */
DDR3_2133K
=
17
,
/* 12-12-12 */
DDR3_2133L
=
18
,
/* 13-13-13 */
DDR3_2133M
=
19
,
/* 14-14-14 */
DDR3_2133N
=
20
,
DDR3_DEFAULT
=
21
,
};
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define range(mi, val, ma) (((ma) > (val)) ? (max(mi, val)) : (ma))
struct
dram_timing_t
{
/* unit MHz */
uint32_t
mhz
;
/* some timing unit is us */
uint32_t
tinit1
;
uint32_t
tinit2
;
uint32_t
tinit3
;
uint32_t
tinit4
;
uint32_t
tinit5
;
/* reset low, DDR3:200us */
uint32_t
trstl
;
/* reset high to CKE high, DDR3:500us */
uint32_t
trsth
;
uint32_t
trefi
;
/* base */
uint32_t
trcd
;
/* trp per bank */
uint32_t
trppb
;
/* trp all bank */
uint32_t
trp
;
uint32_t
twr
;
uint32_t
tdal
;
uint32_t
trtp
;
uint32_t
trc
;
uint32_t
trrd
;
uint32_t
tccd
;
uint32_t
twtr
;
uint32_t
trtw
;
uint32_t
tras_max
;
uint32_t
tras_min
;
uint32_t
tfaw
;
uint32_t
trfc
;
uint32_t
tdqsck
;
uint32_t
tdqsck_max
;
/* pd or sr */
uint32_t
txsr
;
uint32_t
txsnr
;
uint32_t
txp
;
uint32_t
txpdll
;
uint32_t
tdllk
;
uint32_t
tcke
;
uint32_t
tckesr
;
uint32_t
tcksre
;
uint32_t
tcksrx
;
uint32_t
tdpd
;
/* mode regiter timing */
uint32_t
tmod
;
uint32_t
tmrd
;
uint32_t
tmrr
;
uint32_t
tmrri
;
/* ODT */
uint32_t
todton
;
/* ZQ */
uint32_t
tzqinit
;
uint32_t
tzqcs
;
uint32_t
tzqoper
;
uint32_t
tzqreset
;
/* Write Leveling */
uint32_t
twlmrd
;
uint32_t
twlo
;
uint32_t
twldqsen
;
/* CA Training */
uint32_t
tcackel
;
uint32_t
tcaent
;
uint32_t
tcamrd
;
uint32_t
tcackeh
;
uint32_t
tcaext
;
uint32_t
tadr
;
uint32_t
tmrz
;
uint32_t
tcacd
;
/* mode register */
uint32_t
mr
[
4
];
uint32_t
mr11
;
/* lpddr4 spec */
uint32_t
mr12
;
uint32_t
mr13
;
uint32_t
mr14
;
uint32_t
mr16
;
uint32_t
mr17
;
uint32_t
mr20
;
uint32_t
mr22
;
uint32_t
tccdmw
;
uint32_t
tppd
;
uint32_t
tescke
;
uint32_t
tsr
;
uint32_t
tcmdcke
;
uint32_t
tcscke
;
uint32_t
tckelcs
;
uint32_t
tcsckeh
;
uint32_t
tckehcs
;
uint32_t
tmrwckel
;
uint32_t
tzqcal
;
uint32_t
tzqlat
;
uint32_t
tzqcke
;
uint32_t
tvref_long
;
uint32_t
tvref_short
;
uint32_t
tvrcg_enable
;
uint32_t
tvrcg_disable
;
uint32_t
tfc_long
;
uint32_t
tckfspe
;
uint32_t
tckfspx
;
uint32_t
tckehcmd
;
uint32_t
tckelcmd
;
uint32_t
tckelpd
;
uint32_t
tckckel
;
/* other */
uint32_t
al
;
uint32_t
cl
;
uint32_t
cwl
;
uint32_t
bl
;
};
struct
dram_info_t
{
/* speed_rate only used when DDR3 */
enum
ddr3_speed_rate
speed_rate
;
/* 1: use CS0, 2: use CS0 and CS1 */
uint32_t
cs_cnt
;
/* give the max per-die capability on each rank/cs */
uint32_t
per_die_capability
[
2
];
};
struct
timing_related_config
{
struct
dram_info_t
dram_info
[
2
];
uint32_t
dram_type
;
/* MHz */
uint32_t
freq
;
uint32_t
ch_cnt
;
uint32_t
bl
;
/* 1:auto precharge, 0:never auto precharge */
uint32_t
ap
;
/*
* 1:dll bypass, 0:dll normal
* dram and controller dll bypass at the same time
*/
uint32_t
dllbp
;
/* 1:odt enable, 0:odt disable */
uint32_t
odt
;
/* 1:enable, 0:disabe */
uint32_t
rdbi
;
uint32_t
wdbi
;
/* dram driver strength */
uint32_t
dramds
;
/* dram ODT, if odt=0, this parameter invalid */
uint32_t
dramodt
;
/*
* ca ODT, if odt=0, this parameter invalid
* it only used by LPDDR4
*/
uint32_t
caodt
;
};
/* mr0 for ddr3 */
#define DDR3_BL8 (0)
#define DDR3_BC4_8 (1)
#define DDR3_BC4 (2)
#define DDR3_CL(n) (((((n) - 4) & 0x7) << 4)\
| ((((n) - 4) & 0x8) >> 1))
#define DDR3_WR(n) (((n) & 0x7) << 9)
#define DDR3_DLL_RESET (1 << 8)
#define DDR3_DLL_DERESET (0 << 8)
/* mr1 for ddr3 */
#define DDR3_DLL_ENABLE (0)
#define DDR3_DLL_DISABLE (1)
#define DDR3_MR1_AL(n) (((n) & 0x3) << 3)
#define DDR3_DS_40 (0)
#define DDR3_DS_34 (1 << 1)
#define DDR3_RTT_NOM_DIS (0)
#define DDR3_RTT_NOM_60 (1 << 2)
#define DDR3_RTT_NOM_120 (1 << 6)
#define DDR3_RTT_NOM_40 ((1 << 2) | (1 << 6))
#define DDR3_TDQS (1 << 11)
/* mr2 for ddr3 */
#define DDR3_MR2_CWL(n) ((((n) - 5) & 0x7) << 3)
#define DDR3_RTT_WR_DIS (0)
#define DDR3_RTT_WR_60 (1 << 9)
#define DDR3_RTT_WR_120 (2 << 9)
/*
* MR0 (Device Information)
* 0:DAI complete, 1:DAI still in progress
*/
#define LPDDR2_DAI (0x1)
/* 0:S2 or S4 SDRAM, 1:NVM */
#define LPDDR2_DI (0x1 << 1)
/* 0:DNV not supported, 1:DNV supported */
#define LPDDR2_DNVI (0x1 << 2)
#define LPDDR2_RZQI (0x3 << 3)
/*
* 00:RZQ self test not supported,
* 01:ZQ-pin may connect to VDDCA or float
* 10:ZQ-pin may short to GND.
* 11:ZQ-pin self test completed, no error condition detected.
*/
/* MR1 (Device Feature) */
#define LPDDR2_BL4 (0x2)
#define LPDDR2_BL8 (0x3)
#define LPDDR2_BL16 (0x4)
#define LPDDR2_N_WR(n) (((n) - 2) << 5)
/* MR2 (Device Feature 2) */
#define LPDDR2_RL3_WL1 (0x1)
#define LPDDR2_RL4_WL2 (0x2)
#define LPDDR2_RL5_WL2 (0x3)
#define LPDDR2_RL6_WL3 (0x4)
#define LPDDR2_RL7_WL4 (0x5)
#define LPDDR2_RL8_WL4 (0x6)
/* MR3 (IO Configuration 1) */
#define LPDDR2_DS_34 (0x1)
#define LPDDR2_DS_40 (0x2)
#define LPDDR2_DS_48 (0x3)
#define LPDDR2_DS_60 (0x4)
#define LPDDR2_DS_80 (0x6)
/* optional */
#define LPDDR2_DS_120 (0x7)
/* MR4 (Device Temperature) */
#define LPDDR2_TREF_MASK (0x7)
#define LPDDR2_4_TREF (0x1)
#define LPDDR2_2_TREF (0x2)
#define LPDDR2_1_TREF (0x3)
#define LPDDR2_025_TREF (0x5)
#define LPDDR2_025_TREF_DERATE (0x6)
#define LPDDR2_TUF (0x1 << 7)
/* MR8 (Basic configuration 4) */
#define LPDDR2_S4 (0x0)
#define LPDDR2_S2 (0x1)
#define LPDDR2_N (0x2)
/* Unit:MB */
#define LPDDR2_DENSITY(mr8) (8 << (((mr8) >> 2) & 0xf))
#define LPDDR2_IO_WIDTH(mr8) (32 >> (((mr8) >> 6) & 0x3))
/* MR10 (Calibration) */
#define LPDDR2_ZQINIT (0xff)
#define LPDDR2_ZQCL (0xab)
#define LPDDR2_ZQCS (0x56)
#define LPDDR2_ZQRESET (0xc3)
/* MR16 (PASR Bank Mask), S2 SDRAM Only */
#define LPDDR2_PASR_FULL (0x0)
#define LPDDR2_PASR_1_2 (0x1)
#define LPDDR2_PASR_1_4 (0x2)
#define LPDDR2_PASR_1_8 (0x3)
/*
* MR0 (Device Information)
* 0:DAI complete,
* 1:DAI still in progress
*/
#define LPDDR3_DAI (0x1)
/*
* 00:RZQ self test not supported,
* 01:ZQ-pin may connect to VDDCA or float
* 10:ZQ-pin may short to GND.
* 11:ZQ-pin self test completed, no error condition detected.
*/
#define LPDDR3_RZQI (0x3 << 3)
/*
* 0:DRAM does not support WL(Set B),
* 1:DRAM support WL(Set B)
*/
#define LPDDR3_WL_SUPOT (1 << 6)
/*
* 0:DRAM does not support RL=3,nWR=3,WL=1;
* 1:DRAM supports RL=3,nWR=3,WL=1 for frequencies <=166
*/
#define LPDDR3_RL3_SUPOT (1 << 7)
/* MR1 (Device Feature) */
#define LPDDR3_BL8 (0x3)
#define LPDDR3_N_WR(n) ((n) << 5)
/* MR2 (Device Feature 2), WL Set A,default */
/* <=166MHz,optional*/
#define LPDDR3_RL3_WL1 (0x1)
/* <=400MHz*/
#define LPDDR3_RL6_WL3 (0x4)
/* <=533MHz*/
#define LPDDR3_RL8_WL4 (0x6)
/* <=600MHz*/
#define LPDDR3_RL9_WL5 (0x7)
/* <=667MHz,default*/
#define LPDDR3_RL10_WL6 (0x8)
/* <=733MHz*/
#define LPDDR3_RL11_WL6 (0x9)
/* <=800MHz*/
#define LPDDR3_RL12_WL6 (0xa)
/* <=933MHz*/
#define LPDDR3_RL14_WL8 (0xc)
/* <=1066MHz*/
#define LPDDR3_RL16_WL8 (0xe)
/* WL Set B, optional */
/* <=667MHz,default*/
#define LPDDR3_RL10_WL8 (0x8)
/* <=733MHz*/
#define LPDDR3_RL11_WL9 (0x9)
/* <=800MHz*/
#define LPDDR3_RL12_WL9 (0xa)
/* <=933MHz*/
#define LPDDR3_RL14_WL11 (0xc)
/* <=1066MHz*/
#define LPDDR3_RL16_WL13 (0xe)
/* 1:enable nWR programming > 9(default)*/
#define LPDDR3_N_WRE (1 << 4)
/* 1:Select WL Set B*/
#define LPDDR3_WL_S (1 << 6)
/* 1:enable*/
#define LPDDR3_WR_LEVEL (1 << 7)
/* MR3 (IO Configuration 1) */
#define LPDDR3_DS_34 (0x1)
#define LPDDR3_DS_40 (0x2)
#define LPDDR3_DS_48 (0x3)
#define LPDDR3_DS_60 (0x4)
#define LPDDR3_DS_80 (0x6)
#define LPDDR3_DS_34D_40U (0x9)
#define LPDDR3_DS_40D_48U (0xa)
#define LPDDR3_DS_34D_48U (0xb)
/* MR4 (Device Temperature) */
#define LPDDR3_TREF_MASK (0x7)
/* SDRAM Low temperature operating limit exceeded */
#define LPDDR3_LT_EXED (0x0)
#define LPDDR3_4_TREF (0x1)
#define LPDDR3_2_TREF (0x2)
#define LPDDR3_1_TREF (0x3)
#define LPDDR3_05_TREF (0x4)
#define LPDDR3_025_TREF (0x5)
#define LPDDR3_025_TREF_DERATE (0x6)
/* SDRAM High temperature operating limit exceeded */
#define LPDDR3_HT_EXED (0x7)
/* 1:value has changed since last read of MR4 */
#define LPDDR3_TUF (0x1 << 7)
/* MR8 (Basic configuration 4) */
#define LPDDR3_S8 (0x3)
#define LPDDR3_DENSITY(mr8) (8 << (((mr8) >> 2) & 0xf))
#define LPDDR3_IO_WIDTH(mr8) (32 >> (((mr8) >> 6) & 0x3))
/* MR10 (Calibration) */
#define LPDDR3_ZQINIT (0xff)
#define LPDDR3_ZQCL (0xab)
#define LPDDR3_ZQCS (0x56)
#define LPDDR3_ZQRESET (0xc3)
/* MR11 (ODT Control) */
#define LPDDR3_ODT_60 (1)
#define LPDDR3_ODT_120 (2)
#define LPDDR3_ODT_240 (3)
#define LPDDR3_ODT_DIS (0)
/* MR2 (Device Feature 2) */
/* RL & nRTP for DBI-RD Disabled */
#define LPDDR4_RL6_NRTP8 (0x0)
#define LPDDR4_RL10_NRTP8 (0x1)
#define LPDDR4_RL14_NRTP8 (0x2)
#define LPDDR4_RL20_NRTP8 (0x3)
#define LPDDR4_RL24_NRTP10 (0x4)
#define LPDDR4_RL28_NRTP12 (0x5)
#define LPDDR4_RL32_NRTP14 (0x6)
#define LPDDR4_RL36_NRTP16 (0x7)
/* RL & nRTP for DBI-RD Disabled */
#define LPDDR4_RL12_NRTP8 (0x1)
#define LPDDR4_RL16_NRTP8 (0x2)
#define LPDDR4_RL22_NRTP8 (0x3)
#define LPDDR4_RL28_NRTP10 (0x4)
#define LPDDR4_RL32_NRTP12 (0x5)
#define LPDDR4_RL36_NRTP14 (0x6)
#define LPDDR4_RL40_NRTP16 (0x7)
/* WL Set A,default */
#define LPDDR4_A_WL4 (0x0)
#define LPDDR4_A_WL6 (0x1)
#define LPDDR4_A_WL8 (0x2)
#define LPDDR4_A_WL10 (0x3)
#define LPDDR4_A_WL12 (0x4)
#define LPDDR4_A_WL14 (0x5)
#define LPDDR4_A_WL16 (0x6)
#define LPDDR4_A_WL18 (0x7)
/* WL Set B, optional */
#define LPDDR4_B_WL4 (0x0 << 3)
#define LPDDR4_B_WL8 (0x1 << 3)
#define LPDDR4_B_WL12 (0x2 << 3)
#define LPDDR4_B_WL18 (0x3 << 3)
#define LPDDR4_B_WL22 (0x4 << 3)
#define LPDDR4_B_WL26 (0x5 << 3)
#define LPDDR4_B_WL30 (0x6 << 3)
#define LPDDR4_B_WL34 (0x7 << 3)
/* 1:Select WL Set B*/
#define LPDDR4_WL_B (1 << 6)
/* 1:enable*/
#define LPDDR4_WR_LEVEL (1 << 7)
/* MR3 */
#define LPDDR4_VDDQ_2_5 (0)
#define LPDDR4_VDDQ_3 (1)
#define LPDDR4_WRPST_0_5_TCK (0 << 1)
#define LPDDR4_WRPST_1_5_TCK (1 << 1)
#define LPDDR4_PPR_EN (1 << 2)
/* PDDS */
#define LPDDR4_PDDS_240 (0x1 << 3)
#define LPDDR4_PDDS_120 (0x2 << 3)
#define LPDDR4_PDDS_80 (0x3 << 3)
#define LPDDR4_PDDS_60 (0x4 << 3)
#define LPDDR4_PDDS_48 (0x5 << 3)
#define LPDDR4_PDDS_40 (0x6 << 3)
#define LPDDR4_DBI_RD_EN (1 << 6)
#define LPDDR4_DBI_WR_EN (1 << 7)
/* MR11 (ODT Control) */
#define LPDDR4_DQODT_240 (1)
#define LPDDR4_DQODT_120 (2)
#define LPDDR4_DQODT_80 (3)
#define LPDDR4_DQODT_60 (4)
#define LPDDR4_DQODT_48 (5)
#define LPDDR4_DQODT_40 (6)
#define LPDDR4_DQODT_DIS (0)
#define LPDDR4_CAODT_240 (1 << 4)
#define LPDDR4_CAODT_120 (2 << 4)
#define LPDDR4_CAODT_80 (3 << 4)
#define LPDDR4_CAODT_60 (4 << 4)
#define LPDDR4_CAODT_48 (5 << 4)
#define LPDDR4_CAODT_40 (6 << 4)
#define LPDDR4_CAODT_DIS (0 << 4)
/*
* Description: depend on input parameter "timing_config",
* and calculate correspond "dram_type"
* spec timing to "pdram_timing"
* parameters:
* input: timing_config
* output: pdram_timing
* NOTE: MR ODT is set, need to disable by controller
*/
void
dram_get_parameter
(
struct
timing_related_config
*
timing_config
,
struct
dram_timing_t
*
pdram_timing
);
#endif
/* _DRAM_SPEC_TIMING_HEAD_ */
plat/rockchip/rk3399/drivers/soc/soc.h
View file @
c2229abd
...
@@ -48,6 +48,12 @@
...
@@ -48,6 +48,12 @@
#define NO_PLL_BYPASS (0x00)
#define NO_PLL_BYPASS (0x00)
#define NO_PLL_PWRDN (0x00)
#define NO_PLL_PWRDN (0x00)
#define FBDIV(n) ((0xfff << 16) | n)
#define POSTDIV2(n) ((0x7 << (12 + 16)) | (n << 12))
#define POSTDIV1(n) ((0x7 << (8 + 16)) | (n << 8))
#define REFDIV(n) ((0x3F << 16) | n)
#define PLL_LOCK(n) ((n >> 31) & 0x1)
#define PLL_SLOW_MODE BITS_WITH_WMASK(SLOW_MODE,\
#define PLL_SLOW_MODE BITS_WITH_WMASK(SLOW_MODE,\
PLL_MODE_MSK, PLL_MODE_SHIFT)
PLL_MODE_MSK, PLL_MODE_SHIFT)
...
@@ -107,6 +113,31 @@ struct deepsleep_data_s {
...
@@ -107,6 +113,31 @@ struct deepsleep_data_s {
uint32_t
pmucru_gate_con
[
PMUCRU_GATE_COUNT
];
uint32_t
pmucru_gate_con
[
PMUCRU_GATE_COUNT
];
};
};
/**************************************************
* pmugrf reg, offset
**************************************************/
#define PMUGRF_OSREG(n) (0x300 + (n) * 4)
/**************************************************
* DCF reg, offset
**************************************************/
#define DCF_DCF_CTRL 0x0
#define DCF_DCF_ADDR 0x8
#define DCF_DCF_ISR 0xc
#define DCF_DCF_TOSET 0x14
#define DCF_DCF_TOCMD 0x18
#define DCF_DCF_CMD_CFG 0x1c
/* DCF_DCF_ISR */
#define DCF_TIMEOUT (1 << 2)
#define DCF_ERR (1 << 1)
#define DCF_DONE (1 << 0)
/* DCF_DCF_CTRL */
#define DCF_VOP_HW_EN (1 << 2)
#define DCF_STOP (1 << 1)
#define DCF_START (1 << 0)
#define CYCL_24M_CNT_US(us) (24 * us)
#define CYCL_24M_CNT_US(us) (24 * us)
#define CYCL_24M_CNT_MS(ms) (ms * CYCL_24M_CNT_US(1000))
#define CYCL_24M_CNT_MS(ms) (ms * CYCL_24M_CNT_US(1000))
#define CYCL_32K_CNT_MS(ms) (ms * 32)
#define CYCL_32K_CNT_MS(ms) (ms * 32)
...
@@ -256,6 +287,12 @@ struct deepsleep_data_s {
...
@@ -256,6 +287,12 @@ struct deepsleep_data_s {
#define PWM_DISABLE (0 << 0)
#define PWM_DISABLE (0 << 0)
#define PWM_ENABLE (1 << 0)
#define PWM_ENABLE (1 << 0)
/* grf reg offset */
#define GRF_DDRC0_CON0 0xe380
#define GRF_DDRC0_CON1 0xe384
#define GRF_DDRC1_CON0 0xe388
#define GRF_DDRC1_CON1 0xe38c
/*
/*
* When system reset in running state, we want the cpus to be reboot
* When system reset in running state, we want the cpus to be reboot
* from maskrom (system reboot),
* from maskrom (system reboot),
...
...
plat/rockchip/rk3399/plat_sip_calls.c
View file @
c2229abd
...
@@ -29,6 +29,42 @@
...
@@ -29,6 +29,42 @@
#include <plat_sip_calls.h>
#include <plat_sip_calls.h>
#include <rockchip_sip_svc.h>
#include <rockchip_sip_svc.h>
#include <runtime_svc.h>
#include <runtime_svc.h>
#include <dram.h>
#define RK_SIP_DDR_CFG64 0x82000008
#define CONFIG_DRAM_INIT 0x00
#define CONFIG_DRAM_SET_RATE 0x01
#define CONFIG_DRAM_ROUND_RATE 0x02
#define CONFIG_DRAM_SET_AT_SR 0x03
#define CONFIG_DRAM_GET_BW 0x04
#define CONFIG_DRAM_GET_RATE 0x05
#define CONFIG_DRAM_CLR_IRQ 0x06
#define CONFIG_DRAM_SET_PARAM 0x07
uint64_t
ddr_smc_handler
(
uint64_t
arg0
,
uint64_t
arg1
,
uint64_t
id
)
{
switch
(
id
)
{
case
CONFIG_DRAM_INIT
:
ddr_init
();
break
;
case
CONFIG_DRAM_SET_RATE
:
return
ddr_set_rate
(
arg0
);
case
CONFIG_DRAM_ROUND_RATE
:
return
ddr_round_rate
(
arg0
);
case
CONFIG_DRAM_GET_RATE
:
return
ddr_get_rate
();
case
CONFIG_DRAM_CLR_IRQ
:
clr_dcf_irq
();
break
;
case
CONFIG_DRAM_SET_PARAM
:
dts_timing_receive
(
arg0
,
arg1
);
break
;
default:
break
;
}
return
0
;
}
uint64_t
rockchip_plat_sip_handler
(
uint32_t
smc_fid
,
uint64_t
rockchip_plat_sip_handler
(
uint32_t
smc_fid
,
uint64_t
x1
,
uint64_t
x1
,
...
@@ -40,6 +76,8 @@ uint64_t rockchip_plat_sip_handler(uint32_t smc_fid,
...
@@ -40,6 +76,8 @@ uint64_t rockchip_plat_sip_handler(uint32_t smc_fid,
uint64_t
flags
)
uint64_t
flags
)
{
{
switch
(
smc_fid
)
{
switch
(
smc_fid
)
{
case
RK_SIP_DDR_CFG64
:
SMC_RET1
(
handle
,
ddr_smc_handler
(
x1
,
x2
,
x3
));
default:
default:
ERROR
(
"%s: unhandled SMC (0x%x)
\n
"
,
__func__
,
smc_fid
);
ERROR
(
"%s: unhandled SMC (0x%x)
\n
"
,
__func__
,
smc_fid
);
SMC_RET1
(
handle
,
SMC_UNK
);
SMC_RET1
(
handle
,
SMC_UNK
);
...
...
plat/rockchip/rk3399/platform.mk
View file @
c2229abd
...
@@ -40,6 +40,7 @@ PLAT_INCLUDES := -I${RK_PLAT_COMMON}/ \
...
@@ -40,6 +40,7 @@ PLAT_INCLUDES := -I${RK_PLAT_COMMON}/ \
-I
${RK_PLAT_SOC}
/drivers/pmu/
\
-I
${RK_PLAT_SOC}
/drivers/pmu/
\
-I
${RK_PLAT_SOC}
/drivers/pwm/
\
-I
${RK_PLAT_SOC}
/drivers/pwm/
\
-I
${RK_PLAT_SOC}
/drivers/soc/
\
-I
${RK_PLAT_SOC}
/drivers/soc/
\
-I
${RK_PLAT_SOC}
/drivers/dram/
\
-I
${RK_PLAT_SOC}
/include/
\
-I
${RK_PLAT_SOC}
/include/
\
RK_GIC_SOURCES
:=
drivers/arm/gic/common/gic_common.c
\
RK_GIC_SOURCES
:=
drivers/arm/gic/common/gic_common.c
\
...
@@ -76,6 +77,8 @@ BL31_SOURCES += ${RK_GIC_SOURCES}
...
@@ -76,6 +77,8 @@ BL31_SOURCES += ${RK_GIC_SOURCES}
${RK_PLAT_SOC}
/drivers/gpio/rk3399_gpio.c
\
${RK_PLAT_SOC}
/drivers/gpio/rk3399_gpio.c
\
${RK_PLAT_SOC}
/drivers/pmu/pmu.c
\
${RK_PLAT_SOC}
/drivers/pmu/pmu.c
\
${RK_PLAT_SOC}
/drivers/pwm/pwm.c
\
${RK_PLAT_SOC}
/drivers/pwm/pwm.c
\
${RK_PLAT_SOC}
/drivers/soc/soc.c
${RK_PLAT_SOC}
/drivers/soc/soc.c
\
${RK_PLAT_SOC}
/drivers/dram/dram.c
\
${RK_PLAT_SOC}
/drivers/dram/dram_spec_timing.c
ENABLE_PLAT_COMPAT
:=
0
ENABLE_PLAT_COMPAT
:=
0
plat/rockchip/rk3399/rk3399_def.h
View file @
c2229abd
...
@@ -61,6 +61,12 @@
...
@@ -61,6 +61,12 @@
#define PWM_BASE (MMIO_BASE + 0x1420000)
#define PWM_BASE (MMIO_BASE + 0x1420000)
#define PWM_SIZE SIZE_K(64)
#define PWM_SIZE SIZE_K(64)
#define CIC_BASE (MMIO_BASE + 0x1620000)
#define CIC_SIZE SIZE_K(4)
#define DCF_BASE (MMIO_BASE + 0x16a0000)
#define DCF_SIZE SIZE_K(4)
#define GPIO0_BASE (MMIO_BASE + 0x1720000)
#define GPIO0_BASE (MMIO_BASE + 0x1720000)
#define GPIO0_SIZE SIZE_K(64)
#define GPIO0_SIZE SIZE_K(64)
...
@@ -85,12 +91,21 @@
...
@@ -85,12 +91,21 @@
#define STIME_BASE (MMIO_BASE + 0x1860000)
#define STIME_BASE (MMIO_BASE + 0x1860000)
#define STIME_SIZE SIZE_K(64)
#define STIME_SIZE SIZE_K(64)
#define SRAM_BASE (MMIO_BASE + 0x18c0000)
#define SRAM_SIZE SIZE_K(192)
#define SERVICE_NOC_0_BASE (MMIO_BASE + 0x1a50000)
#define SERVICE_NOC_0_BASE (MMIO_BASE + 0x1a50000)
#define NOC_0_SIZE SIZE_K(192)
#define NOC_0_SIZE SIZE_K(192)
#define DDRC0_BASE (MMIO_BASE + 0x1a80000)
#define DDRC0_SIZE SIZE_K(32)
#define SERVICE_NOC_1_BASE (MMIO_BASE + 0x1a84000)
#define SERVICE_NOC_1_BASE (MMIO_BASE + 0x1a84000)
#define NOC_1_SIZE SIZE_K(16)
#define NOC_1_SIZE SIZE_K(16)
#define DDRC1_BASE (MMIO_BASE + 0x1a88000)
#define DDRC1_SIZE SIZE_K(32)
#define SERVICE_NOC_2_BASE (MMIO_BASE + 0x1a8c000)
#define SERVICE_NOC_2_BASE (MMIO_BASE + 0x1a8c000)
#define NOC_2_SIZE SIZE_K(16)
#define NOC_2_SIZE SIZE_K(16)
...
@@ -100,6 +115,14 @@
...
@@ -100,6 +115,14 @@
#define CCI500_BASE (MMIO_BASE + 0x1b00000)
#define CCI500_BASE (MMIO_BASE + 0x1b00000)
#define CCI500_SIZE SIZE_M(1)
#define CCI500_SIZE SIZE_M(1)
#define DDR_PI_OFFSET 0x800
#define DDR_PHY_OFFSET 0x2000
#define DDRC0_PI_BASE (DDRC0_BASE + DDR_PI_OFFSET)
#define DDRC0_PHY_BASE (DDRC0_BASE + DDR_PHY_OFFSET)
#define DDRC1_PI_BASE (DDRC1_BASE + DDR_PI_OFFSET)
#define DDRC1_PHY_BASE (DDRC1_BASE + DDR_PHY_OFFSET)
/* Aggregate of all devices in the first GB */
/* Aggregate of all devices in the first GB */
#define RK3399_DEV_RNG0_BASE MMIO_BASE
#define RK3399_DEV_RNG0_BASE MMIO_BASE
#define RK3399_DEV_RNG0_SIZE 0x1d00000
#define RK3399_DEV_RNG0_SIZE 0x1d00000
...
...
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