116a92a42STang Yun ping // SPDX-License-Identifier: GPL-2.0
216a92a42STang Yun ping /*
316a92a42STang Yun ping * (C) Copyright 2018 Rockchip Electronics Co., Ltd
416a92a42STang Yun ping */
516a92a42STang Yun ping #include <asm/arch/rockchip_smccc.h>
616a92a42STang Yun ping #include <asm/arch/rockchip_dmc.h>
716a92a42STang Yun ping #include <asm/io.h>
816a92a42STang Yun ping #include <asm/psci.h>
916a92a42STang Yun ping #include <common.h>
1016a92a42STang Yun ping #include <clk.h>
1116a92a42STang Yun ping #include <dm.h>
1216a92a42STang Yun ping #include <dm/of_access.h>
1316a92a42STang Yun ping #include <dt-structs.h>
1416a92a42STang Yun ping #include <linux/arm-smccc.h>
1516a92a42STang Yun ping #include <linux/err.h>
1616a92a42STang Yun ping #include <linux/errno.h>
1716a92a42STang Yun ping #include <ram.h>
1816a92a42STang Yun ping #include <regmap.h>
1916a92a42STang Yun ping
2016a92a42STang Yun ping #define DTS_PAR_OFFSET (4096)
2116a92a42STang Yun ping
2216a92a42STang Yun ping struct share_params {
2316a92a42STang Yun ping u32 hz;
2416a92a42STang Yun ping u32 lcdc_type;
2516a92a42STang Yun ping u32 vop;
2616a92a42STang Yun ping u32 vop_dclk_mode;
2716a92a42STang Yun ping u32 sr_idle_en;
2816a92a42STang Yun ping u32 addr_mcu_el3;
2916a92a42STang Yun ping /*
3016a92a42STang Yun ping * 1: need to wait flag1
3116a92a42STang Yun ping * 0: never wait flag1
3216a92a42STang Yun ping */
3316a92a42STang Yun ping u32 wait_flag1;
3416a92a42STang Yun ping /*
3516a92a42STang Yun ping * 1: need to wait flag1
3616a92a42STang Yun ping * 0: never wait flag1
3716a92a42STang Yun ping */
3816a92a42STang Yun ping u32 wait_flag0;
3916a92a42STang Yun ping u32 complt_hwirq;
4016a92a42STang Yun ping /* if need, add parameter after */
4116a92a42STang Yun ping };
4216a92a42STang Yun ping
4316a92a42STang Yun ping static struct share_params *ddr_psci_param;
4416a92a42STang Yun ping
4516a92a42STang Yun ping /* hope this define can adapt all future platfor */
4616a92a42STang Yun ping static const char * const rk3328_dts_timing[] = {
4716a92a42STang Yun ping "ddr3_speed_bin",
4816a92a42STang Yun ping "ddr4_speed_bin",
4916a92a42STang Yun ping "pd_idle",
5016a92a42STang Yun ping "sr_idle",
5116a92a42STang Yun ping "sr_mc_gate_idle",
5216a92a42STang Yun ping "srpd_lite_idle",
5316a92a42STang Yun ping "standby_idle",
5416a92a42STang Yun ping
5516a92a42STang Yun ping "auto_pd_dis_freq",
5616a92a42STang Yun ping "auto_sr_dis_freq",
5716a92a42STang Yun ping "ddr3_dll_dis_freq",
5816a92a42STang Yun ping "ddr4_dll_dis_freq",
5916a92a42STang Yun ping "phy_dll_dis_freq",
6016a92a42STang Yun ping
6116a92a42STang Yun ping "ddr3_odt_dis_freq",
6216a92a42STang Yun ping "phy_ddr3_odt_dis_freq",
6316a92a42STang Yun ping "ddr3_drv",
6416a92a42STang Yun ping "ddr3_odt",
6516a92a42STang Yun ping "phy_ddr3_ca_drv",
6616a92a42STang Yun ping "phy_ddr3_ck_drv",
6716a92a42STang Yun ping "phy_ddr3_dq_drv",
6816a92a42STang Yun ping "phy_ddr3_odt",
6916a92a42STang Yun ping
7016a92a42STang Yun ping "lpddr3_odt_dis_freq",
7116a92a42STang Yun ping "phy_lpddr3_odt_dis_freq",
7216a92a42STang Yun ping "lpddr3_drv",
7316a92a42STang Yun ping "lpddr3_odt",
7416a92a42STang Yun ping "phy_lpddr3_ca_drv",
7516a92a42STang Yun ping "phy_lpddr3_ck_drv",
7616a92a42STang Yun ping "phy_lpddr3_dq_drv",
7716a92a42STang Yun ping "phy_lpddr3_odt",
7816a92a42STang Yun ping
7916a92a42STang Yun ping "lpddr4_odt_dis_freq",
8016a92a42STang Yun ping "phy_lpddr4_odt_dis_freq",
8116a92a42STang Yun ping "lpddr4_drv",
8216a92a42STang Yun ping "lpddr4_dq_odt",
8316a92a42STang Yun ping "lpddr4_ca_odt",
8416a92a42STang Yun ping "phy_lpddr4_ca_drv",
8516a92a42STang Yun ping "phy_lpddr4_ck_cs_drv",
8616a92a42STang Yun ping "phy_lpddr4_dq_drv",
8716a92a42STang Yun ping "phy_lpddr4_odt",
8816a92a42STang Yun ping
8916a92a42STang Yun ping "ddr4_odt_dis_freq",
9016a92a42STang Yun ping "phy_ddr4_odt_dis_freq",
9116a92a42STang Yun ping "ddr4_drv",
9216a92a42STang Yun ping "ddr4_odt",
9316a92a42STang Yun ping "phy_ddr4_ca_drv",
9416a92a42STang Yun ping "phy_ddr4_ck_drv",
9516a92a42STang Yun ping "phy_ddr4_dq_drv",
9616a92a42STang Yun ping "phy_ddr4_odt",
9716a92a42STang Yun ping };
9816a92a42STang Yun ping
9916a92a42STang Yun ping static const char * const px30_dts_timing[] = {
10016a92a42STang Yun ping "ddr2_speed_bin",
10116a92a42STang Yun ping "ddr3_speed_bin",
10216a92a42STang Yun ping "ddr4_speed_bin",
10316a92a42STang Yun ping "pd_idle",
10416a92a42STang Yun ping "sr_idle",
10516a92a42STang Yun ping "sr_mc_gate_idle",
10616a92a42STang Yun ping "srpd_lite_idle",
10716a92a42STang Yun ping "standby_idle",
10816a92a42STang Yun ping
10916a92a42STang Yun ping "auto_pd_dis_freq",
11016a92a42STang Yun ping "auto_sr_dis_freq",
11116a92a42STang Yun ping "ddr2_dll_dis_freq",
11216a92a42STang Yun ping "ddr3_dll_dis_freq",
11316a92a42STang Yun ping "ddr4_dll_dis_freq",
11416a92a42STang Yun ping "phy_dll_dis_freq",
11516a92a42STang Yun ping
11616a92a42STang Yun ping "ddr2_odt_dis_freq",
11716a92a42STang Yun ping "phy_ddr2_odt_dis_freq",
11816a92a42STang Yun ping "ddr2_drv",
11916a92a42STang Yun ping "ddr2_odt",
12016a92a42STang Yun ping "phy_ddr2_ca_drv",
12116a92a42STang Yun ping "phy_ddr2_ck_drv",
12216a92a42STang Yun ping "phy_ddr2_dq_drv",
12316a92a42STang Yun ping "phy_ddr2_odt",
12416a92a42STang Yun ping
12516a92a42STang Yun ping "ddr3_odt_dis_freq",
12616a92a42STang Yun ping "phy_ddr3_odt_dis_freq",
12716a92a42STang Yun ping "ddr3_drv",
12816a92a42STang Yun ping "ddr3_odt",
12916a92a42STang Yun ping "phy_ddr3_ca_drv",
13016a92a42STang Yun ping "phy_ddr3_ck_drv",
13116a92a42STang Yun ping "phy_ddr3_dq_drv",
13216a92a42STang Yun ping "phy_ddr3_odt",
13316a92a42STang Yun ping
13416a92a42STang Yun ping "phy_lpddr2_odt_dis_freq",
13516a92a42STang Yun ping "lpddr2_drv",
13616a92a42STang Yun ping "phy_lpddr2_ca_drv",
13716a92a42STang Yun ping "phy_lpddr2_ck_drv",
13816a92a42STang Yun ping "phy_lpddr2_dq_drv",
13916a92a42STang Yun ping "phy_lpddr2_odt",
14016a92a42STang Yun ping
14116a92a42STang Yun ping "lpddr3_odt_dis_freq",
14216a92a42STang Yun ping "phy_lpddr3_odt_dis_freq",
14316a92a42STang Yun ping "lpddr3_drv",
14416a92a42STang Yun ping "lpddr3_odt",
14516a92a42STang Yun ping "phy_lpddr3_ca_drv",
14616a92a42STang Yun ping "phy_lpddr3_ck_drv",
14716a92a42STang Yun ping "phy_lpddr3_dq_drv",
14816a92a42STang Yun ping "phy_lpddr3_odt",
14916a92a42STang Yun ping
15016a92a42STang Yun ping "lpddr4_odt_dis_freq",
15116a92a42STang Yun ping "phy_lpddr4_odt_dis_freq",
15216a92a42STang Yun ping "lpddr4_drv",
15316a92a42STang Yun ping "lpddr4_dq_odt",
15416a92a42STang Yun ping "lpddr4_ca_odt",
15516a92a42STang Yun ping "phy_lpddr4_ca_drv",
15616a92a42STang Yun ping "phy_lpddr4_ck_cs_drv",
15716a92a42STang Yun ping "phy_lpddr4_dq_drv",
15816a92a42STang Yun ping "phy_lpddr4_odt",
15916a92a42STang Yun ping
16016a92a42STang Yun ping "ddr4_odt_dis_freq",
16116a92a42STang Yun ping "phy_ddr4_odt_dis_freq",
16216a92a42STang Yun ping "ddr4_drv",
16316a92a42STang Yun ping "ddr4_odt",
16416a92a42STang Yun ping "phy_ddr4_ca_drv",
16516a92a42STang Yun ping "phy_ddr4_ck_drv",
16616a92a42STang Yun ping "phy_ddr4_dq_drv",
16716a92a42STang Yun ping "phy_ddr4_odt",
16816a92a42STang Yun ping };
16916a92a42STang Yun ping
17016a92a42STang Yun ping static const char * const rk3328_dts_ca_timing[] = {
17116a92a42STang Yun ping "ddr3a1_ddr4a9_de-skew",
17216a92a42STang Yun ping "ddr3a0_ddr4a10_de-skew",
17316a92a42STang Yun ping "ddr3a3_ddr4a6_de-skew",
17416a92a42STang Yun ping "ddr3a2_ddr4a4_de-skew",
17516a92a42STang Yun ping "ddr3a5_ddr4a8_de-skew",
17616a92a42STang Yun ping "ddr3a4_ddr4a5_de-skew",
17716a92a42STang Yun ping "ddr3a7_ddr4a11_de-skew",
17816a92a42STang Yun ping "ddr3a6_ddr4a7_de-skew",
17916a92a42STang Yun ping "ddr3a9_ddr4a0_de-skew",
18016a92a42STang Yun ping "ddr3a8_ddr4a13_de-skew",
18116a92a42STang Yun ping "ddr3a11_ddr4a3_de-skew",
18216a92a42STang Yun ping "ddr3a10_ddr4cs0_de-skew",
18316a92a42STang Yun ping "ddr3a13_ddr4a2_de-skew",
18416a92a42STang Yun ping "ddr3a12_ddr4ba1_de-skew",
18516a92a42STang Yun ping "ddr3a15_ddr4odt0_de-skew",
18616a92a42STang Yun ping "ddr3a14_ddr4a1_de-skew",
18716a92a42STang Yun ping "ddr3ba1_ddr4a15_de-skew",
18816a92a42STang Yun ping "ddr3ba0_ddr4bg0_de-skew",
18916a92a42STang Yun ping "ddr3ras_ddr4cke_de-skew",
19016a92a42STang Yun ping "ddr3ba2_ddr4ba0_de-skew",
19116a92a42STang Yun ping "ddr3we_ddr4bg1_de-skew",
19216a92a42STang Yun ping "ddr3cas_ddr4a12_de-skew",
19316a92a42STang Yun ping "ddr3ckn_ddr4ckn_de-skew",
19416a92a42STang Yun ping "ddr3ckp_ddr4ckp_de-skew",
19516a92a42STang Yun ping "ddr3cke_ddr4a16_de-skew",
19616a92a42STang Yun ping "ddr3odt0_ddr4a14_de-skew",
19716a92a42STang Yun ping "ddr3cs0_ddr4act_de-skew",
19816a92a42STang Yun ping "ddr3reset_ddr4reset_de-skew",
19916a92a42STang Yun ping "ddr3cs1_ddr4cs1_de-skew",
20016a92a42STang Yun ping "ddr3odt1_ddr4odt1_de-skew",
20116a92a42STang Yun ping };
20216a92a42STang Yun ping
20316a92a42STang Yun ping static const char * const rk3328_dts_cs0_timing[] = {
20416a92a42STang Yun ping "cs0_dm0_rx_de-skew",
20516a92a42STang Yun ping "cs0_dm0_tx_de-skew",
20616a92a42STang Yun ping "cs0_dq0_rx_de-skew",
20716a92a42STang Yun ping "cs0_dq0_tx_de-skew",
20816a92a42STang Yun ping "cs0_dq1_rx_de-skew",
20916a92a42STang Yun ping "cs0_dq1_tx_de-skew",
21016a92a42STang Yun ping "cs0_dq2_rx_de-skew",
21116a92a42STang Yun ping "cs0_dq2_tx_de-skew",
21216a92a42STang Yun ping "cs0_dq3_rx_de-skew",
21316a92a42STang Yun ping "cs0_dq3_tx_de-skew",
21416a92a42STang Yun ping "cs0_dq4_rx_de-skew",
21516a92a42STang Yun ping "cs0_dq4_tx_de-skew",
21616a92a42STang Yun ping "cs0_dq5_rx_de-skew",
21716a92a42STang Yun ping "cs0_dq5_tx_de-skew",
21816a92a42STang Yun ping "cs0_dq6_rx_de-skew",
21916a92a42STang Yun ping "cs0_dq6_tx_de-skew",
22016a92a42STang Yun ping "cs0_dq7_rx_de-skew",
22116a92a42STang Yun ping "cs0_dq7_tx_de-skew",
22216a92a42STang Yun ping "cs0_dqs0_rx_de-skew",
22316a92a42STang Yun ping "cs0_dqs0p_tx_de-skew",
22416a92a42STang Yun ping "cs0_dqs0n_tx_de-skew",
22516a92a42STang Yun ping
22616a92a42STang Yun ping "cs0_dm1_rx_de-skew",
22716a92a42STang Yun ping "cs0_dm1_tx_de-skew",
22816a92a42STang Yun ping "cs0_dq8_rx_de-skew",
22916a92a42STang Yun ping "cs0_dq8_tx_de-skew",
23016a92a42STang Yun ping "cs0_dq9_rx_de-skew",
23116a92a42STang Yun ping "cs0_dq9_tx_de-skew",
23216a92a42STang Yun ping "cs0_dq10_rx_de-skew",
23316a92a42STang Yun ping "cs0_dq10_tx_de-skew",
23416a92a42STang Yun ping "cs0_dq11_rx_de-skew",
23516a92a42STang Yun ping "cs0_dq11_tx_de-skew",
23616a92a42STang Yun ping "cs0_dq12_rx_de-skew",
23716a92a42STang Yun ping "cs0_dq12_tx_de-skew",
23816a92a42STang Yun ping "cs0_dq13_rx_de-skew",
23916a92a42STang Yun ping "cs0_dq13_tx_de-skew",
24016a92a42STang Yun ping "cs0_dq14_rx_de-skew",
24116a92a42STang Yun ping "cs0_dq14_tx_de-skew",
24216a92a42STang Yun ping "cs0_dq15_rx_de-skew",
24316a92a42STang Yun ping "cs0_dq15_tx_de-skew",
24416a92a42STang Yun ping "cs0_dqs1_rx_de-skew",
24516a92a42STang Yun ping "cs0_dqs1p_tx_de-skew",
24616a92a42STang Yun ping "cs0_dqs1n_tx_de-skew",
24716a92a42STang Yun ping
24816a92a42STang Yun ping "cs0_dm2_rx_de-skew",
24916a92a42STang Yun ping "cs0_dm2_tx_de-skew",
25016a92a42STang Yun ping "cs0_dq16_rx_de-skew",
25116a92a42STang Yun ping "cs0_dq16_tx_de-skew",
25216a92a42STang Yun ping "cs0_dq17_rx_de-skew",
25316a92a42STang Yun ping "cs0_dq17_tx_de-skew",
25416a92a42STang Yun ping "cs0_dq18_rx_de-skew",
25516a92a42STang Yun ping "cs0_dq18_tx_de-skew",
25616a92a42STang Yun ping "cs0_dq19_rx_de-skew",
25716a92a42STang Yun ping "cs0_dq19_tx_de-skew",
25816a92a42STang Yun ping "cs0_dq20_rx_de-skew",
25916a92a42STang Yun ping "cs0_dq20_tx_de-skew",
26016a92a42STang Yun ping "cs0_dq21_rx_de-skew",
26116a92a42STang Yun ping "cs0_dq21_tx_de-skew",
26216a92a42STang Yun ping "cs0_dq22_rx_de-skew",
26316a92a42STang Yun ping "cs0_dq22_tx_de-skew",
26416a92a42STang Yun ping "cs0_dq23_rx_de-skew",
26516a92a42STang Yun ping "cs0_dq23_tx_de-skew",
26616a92a42STang Yun ping "cs0_dqs2_rx_de-skew",
26716a92a42STang Yun ping "cs0_dqs2p_tx_de-skew",
26816a92a42STang Yun ping "cs0_dqs2n_tx_de-skew",
26916a92a42STang Yun ping
27016a92a42STang Yun ping "cs0_dm3_rx_de-skew",
27116a92a42STang Yun ping "cs0_dm3_tx_de-skew",
27216a92a42STang Yun ping "cs0_dq24_rx_de-skew",
27316a92a42STang Yun ping "cs0_dq24_tx_de-skew",
27416a92a42STang Yun ping "cs0_dq25_rx_de-skew",
27516a92a42STang Yun ping "cs0_dq25_tx_de-skew",
27616a92a42STang Yun ping "cs0_dq26_rx_de-skew",
27716a92a42STang Yun ping "cs0_dq26_tx_de-skew",
27816a92a42STang Yun ping "cs0_dq27_rx_de-skew",
27916a92a42STang Yun ping "cs0_dq27_tx_de-skew",
28016a92a42STang Yun ping "cs0_dq28_rx_de-skew",
28116a92a42STang Yun ping "cs0_dq28_tx_de-skew",
28216a92a42STang Yun ping "cs0_dq29_rx_de-skew",
28316a92a42STang Yun ping "cs0_dq29_tx_de-skew",
28416a92a42STang Yun ping "cs0_dq30_rx_de-skew",
28516a92a42STang Yun ping "cs0_dq30_tx_de-skew",
28616a92a42STang Yun ping "cs0_dq31_rx_de-skew",
28716a92a42STang Yun ping "cs0_dq31_tx_de-skew",
28816a92a42STang Yun ping "cs0_dqs3_rx_de-skew",
28916a92a42STang Yun ping "cs0_dqs3p_tx_de-skew",
29016a92a42STang Yun ping "cs0_dqs3n_tx_de-skew",
29116a92a42STang Yun ping };
29216a92a42STang Yun ping
29316a92a42STang Yun ping static const char * const rk3328_dts_cs1_timing[] = {
29416a92a42STang Yun ping "cs1_dm0_rx_de-skew",
29516a92a42STang Yun ping "cs1_dm0_tx_de-skew",
29616a92a42STang Yun ping "cs1_dq0_rx_de-skew",
29716a92a42STang Yun ping "cs1_dq0_tx_de-skew",
29816a92a42STang Yun ping "cs1_dq1_rx_de-skew",
29916a92a42STang Yun ping "cs1_dq1_tx_de-skew",
30016a92a42STang Yun ping "cs1_dq2_rx_de-skew",
30116a92a42STang Yun ping "cs1_dq2_tx_de-skew",
30216a92a42STang Yun ping "cs1_dq3_rx_de-skew",
30316a92a42STang Yun ping "cs1_dq3_tx_de-skew",
30416a92a42STang Yun ping "cs1_dq4_rx_de-skew",
30516a92a42STang Yun ping "cs1_dq4_tx_de-skew",
30616a92a42STang Yun ping "cs1_dq5_rx_de-skew",
30716a92a42STang Yun ping "cs1_dq5_tx_de-skew",
30816a92a42STang Yun ping "cs1_dq6_rx_de-skew",
30916a92a42STang Yun ping "cs1_dq6_tx_de-skew",
31016a92a42STang Yun ping "cs1_dq7_rx_de-skew",
31116a92a42STang Yun ping "cs1_dq7_tx_de-skew",
31216a92a42STang Yun ping "cs1_dqs0_rx_de-skew",
31316a92a42STang Yun ping "cs1_dqs0p_tx_de-skew",
31416a92a42STang Yun ping "cs1_dqs0n_tx_de-skew",
31516a92a42STang Yun ping
31616a92a42STang Yun ping "cs1_dm1_rx_de-skew",
31716a92a42STang Yun ping "cs1_dm1_tx_de-skew",
31816a92a42STang Yun ping "cs1_dq8_rx_de-skew",
31916a92a42STang Yun ping "cs1_dq8_tx_de-skew",
32016a92a42STang Yun ping "cs1_dq9_rx_de-skew",
32116a92a42STang Yun ping "cs1_dq9_tx_de-skew",
32216a92a42STang Yun ping "cs1_dq10_rx_de-skew",
32316a92a42STang Yun ping "cs1_dq10_tx_de-skew",
32416a92a42STang Yun ping "cs1_dq11_rx_de-skew",
32516a92a42STang Yun ping "cs1_dq11_tx_de-skew",
32616a92a42STang Yun ping "cs1_dq12_rx_de-skew",
32716a92a42STang Yun ping "cs1_dq12_tx_de-skew",
32816a92a42STang Yun ping "cs1_dq13_rx_de-skew",
32916a92a42STang Yun ping "cs1_dq13_tx_de-skew",
33016a92a42STang Yun ping "cs1_dq14_rx_de-skew",
33116a92a42STang Yun ping "cs1_dq14_tx_de-skew",
33216a92a42STang Yun ping "cs1_dq15_rx_de-skew",
33316a92a42STang Yun ping "cs1_dq15_tx_de-skew",
33416a92a42STang Yun ping "cs1_dqs1_rx_de-skew",
33516a92a42STang Yun ping "cs1_dqs1p_tx_de-skew",
33616a92a42STang Yun ping "cs1_dqs1n_tx_de-skew",
33716a92a42STang Yun ping
33816a92a42STang Yun ping "cs1_dm2_rx_de-skew",
33916a92a42STang Yun ping "cs1_dm2_tx_de-skew",
34016a92a42STang Yun ping "cs1_dq16_rx_de-skew",
34116a92a42STang Yun ping "cs1_dq16_tx_de-skew",
34216a92a42STang Yun ping "cs1_dq17_rx_de-skew",
34316a92a42STang Yun ping "cs1_dq17_tx_de-skew",
34416a92a42STang Yun ping "cs1_dq18_rx_de-skew",
34516a92a42STang Yun ping "cs1_dq18_tx_de-skew",
34616a92a42STang Yun ping "cs1_dq19_rx_de-skew",
34716a92a42STang Yun ping "cs1_dq19_tx_de-skew",
34816a92a42STang Yun ping "cs1_dq20_rx_de-skew",
34916a92a42STang Yun ping "cs1_dq20_tx_de-skew",
35016a92a42STang Yun ping "cs1_dq21_rx_de-skew",
35116a92a42STang Yun ping "cs1_dq21_tx_de-skew",
35216a92a42STang Yun ping "cs1_dq22_rx_de-skew",
35316a92a42STang Yun ping "cs1_dq22_tx_de-skew",
35416a92a42STang Yun ping "cs1_dq23_rx_de-skew",
35516a92a42STang Yun ping "cs1_dq23_tx_de-skew",
35616a92a42STang Yun ping "cs1_dqs2_rx_de-skew",
35716a92a42STang Yun ping "cs1_dqs2p_tx_de-skew",
35816a92a42STang Yun ping "cs1_dqs2n_tx_de-skew",
35916a92a42STang Yun ping
36016a92a42STang Yun ping "cs1_dm3_rx_de-skew",
36116a92a42STang Yun ping "cs1_dm3_tx_de-skew",
36216a92a42STang Yun ping "cs1_dq24_rx_de-skew",
36316a92a42STang Yun ping "cs1_dq24_tx_de-skew",
36416a92a42STang Yun ping "cs1_dq25_rx_de-skew",
36516a92a42STang Yun ping "cs1_dq25_tx_de-skew",
36616a92a42STang Yun ping "cs1_dq26_rx_de-skew",
36716a92a42STang Yun ping "cs1_dq26_tx_de-skew",
36816a92a42STang Yun ping "cs1_dq27_rx_de-skew",
36916a92a42STang Yun ping "cs1_dq27_tx_de-skew",
37016a92a42STang Yun ping "cs1_dq28_rx_de-skew",
37116a92a42STang Yun ping "cs1_dq28_tx_de-skew",
37216a92a42STang Yun ping "cs1_dq29_rx_de-skew",
37316a92a42STang Yun ping "cs1_dq29_tx_de-skew",
37416a92a42STang Yun ping "cs1_dq30_rx_de-skew",
37516a92a42STang Yun ping "cs1_dq30_tx_de-skew",
37616a92a42STang Yun ping "cs1_dq31_rx_de-skew",
37716a92a42STang Yun ping "cs1_dq31_tx_de-skew",
37816a92a42STang Yun ping "cs1_dqs3_rx_de-skew",
37916a92a42STang Yun ping "cs1_dqs3p_tx_de-skew",
38016a92a42STang Yun ping "cs1_dqs3n_tx_de-skew",
38116a92a42STang Yun ping };
38216a92a42STang Yun ping
38316a92a42STang Yun ping struct rk3328_ddr_dts_config_timing {
38416a92a42STang Yun ping unsigned int ddr3_speed_bin;
38516a92a42STang Yun ping unsigned int ddr4_speed_bin;
38616a92a42STang Yun ping unsigned int pd_idle;
38716a92a42STang Yun ping unsigned int sr_idle;
38816a92a42STang Yun ping unsigned int sr_mc_gate_idle;
38916a92a42STang Yun ping unsigned int srpd_lite_idle;
39016a92a42STang Yun ping unsigned int standby_idle;
39116a92a42STang Yun ping
39216a92a42STang Yun ping unsigned int auto_pd_dis_freq;
39316a92a42STang Yun ping unsigned int auto_sr_dis_freq;
39416a92a42STang Yun ping /* for ddr3 only */
39516a92a42STang Yun ping unsigned int ddr3_dll_dis_freq;
39616a92a42STang Yun ping /* for ddr4 only */
39716a92a42STang Yun ping unsigned int ddr4_dll_dis_freq;
39816a92a42STang Yun ping unsigned int phy_dll_dis_freq;
39916a92a42STang Yun ping
40016a92a42STang Yun ping unsigned int ddr3_odt_dis_freq;
40116a92a42STang Yun ping unsigned int phy_ddr3_odt_dis_freq;
40216a92a42STang Yun ping unsigned int ddr3_drv;
40316a92a42STang Yun ping unsigned int ddr3_odt;
40416a92a42STang Yun ping unsigned int phy_ddr3_ca_drv;
40516a92a42STang Yun ping unsigned int phy_ddr3_ck_drv;
40616a92a42STang Yun ping unsigned int phy_ddr3_dq_drv;
40716a92a42STang Yun ping unsigned int phy_ddr3_odt;
40816a92a42STang Yun ping
40916a92a42STang Yun ping unsigned int lpddr3_odt_dis_freq;
41016a92a42STang Yun ping unsigned int phy_lpddr3_odt_dis_freq;
41116a92a42STang Yun ping unsigned int lpddr3_drv;
41216a92a42STang Yun ping unsigned int lpddr3_odt;
41316a92a42STang Yun ping unsigned int phy_lpddr3_ca_drv;
41416a92a42STang Yun ping unsigned int phy_lpddr3_ck_drv;
41516a92a42STang Yun ping unsigned int phy_lpddr3_dq_drv;
41616a92a42STang Yun ping unsigned int phy_lpddr3_odt;
41716a92a42STang Yun ping
41816a92a42STang Yun ping unsigned int lpddr4_odt_dis_freq;
41916a92a42STang Yun ping unsigned int phy_lpddr4_odt_dis_freq;
42016a92a42STang Yun ping unsigned int lpddr4_drv;
42116a92a42STang Yun ping unsigned int lpddr4_dq_odt;
42216a92a42STang Yun ping unsigned int lpddr4_ca_odt;
42316a92a42STang Yun ping unsigned int phy_lpddr4_ca_drv;
42416a92a42STang Yun ping unsigned int phy_lpddr4_ck_cs_drv;
42516a92a42STang Yun ping unsigned int phy_lpddr4_dq_drv;
42616a92a42STang Yun ping unsigned int phy_lpddr4_odt;
42716a92a42STang Yun ping
42816a92a42STang Yun ping unsigned int ddr4_odt_dis_freq;
42916a92a42STang Yun ping unsigned int phy_ddr4_odt_dis_freq;
43016a92a42STang Yun ping unsigned int ddr4_drv;
43116a92a42STang Yun ping unsigned int ddr4_odt;
43216a92a42STang Yun ping unsigned int phy_ddr4_ca_drv;
43316a92a42STang Yun ping unsigned int phy_ddr4_ck_drv;
43416a92a42STang Yun ping unsigned int phy_ddr4_dq_drv;
43516a92a42STang Yun ping unsigned int phy_ddr4_odt;
43616a92a42STang Yun ping
43716a92a42STang Yun ping unsigned int ca_skew[15];
43816a92a42STang Yun ping unsigned int cs0_skew[44];
43916a92a42STang Yun ping unsigned int cs1_skew[44];
44016a92a42STang Yun ping
44116a92a42STang Yun ping unsigned int available;
44216a92a42STang Yun ping };
44316a92a42STang Yun ping
44416a92a42STang Yun ping struct px30_ddr_dts_config_timing {
44516a92a42STang Yun ping unsigned int ddr2_speed_bin;
44616a92a42STang Yun ping unsigned int ddr3_speed_bin;
44716a92a42STang Yun ping unsigned int ddr4_speed_bin;
44816a92a42STang Yun ping unsigned int pd_idle;
44916a92a42STang Yun ping unsigned int sr_idle;
45016a92a42STang Yun ping unsigned int sr_mc_gate_idle;
45116a92a42STang Yun ping unsigned int srpd_lite_idle;
45216a92a42STang Yun ping unsigned int standby_idle;
45316a92a42STang Yun ping
45416a92a42STang Yun ping unsigned int auto_pd_dis_freq;
45516a92a42STang Yun ping unsigned int auto_sr_dis_freq;
45616a92a42STang Yun ping /* for ddr2 only */
45716a92a42STang Yun ping unsigned int ddr2_dll_dis_freq;
45816a92a42STang Yun ping /* for ddr3 only */
45916a92a42STang Yun ping unsigned int ddr3_dll_dis_freq;
46016a92a42STang Yun ping /* for ddr4 only */
46116a92a42STang Yun ping unsigned int ddr4_dll_dis_freq;
46216a92a42STang Yun ping unsigned int phy_dll_dis_freq;
46316a92a42STang Yun ping
46416a92a42STang Yun ping unsigned int ddr2_odt_dis_freq;
46516a92a42STang Yun ping unsigned int phy_ddr2_odt_dis_freq;
46616a92a42STang Yun ping unsigned int ddr2_drv;
46716a92a42STang Yun ping unsigned int ddr2_odt;
46816a92a42STang Yun ping unsigned int phy_ddr2_ca_drv;
46916a92a42STang Yun ping unsigned int phy_ddr2_ck_drv;
47016a92a42STang Yun ping unsigned int phy_ddr2_dq_drv;
47116a92a42STang Yun ping unsigned int phy_ddr2_odt;
47216a92a42STang Yun ping
47316a92a42STang Yun ping unsigned int ddr3_odt_dis_freq;
47416a92a42STang Yun ping unsigned int phy_ddr3_odt_dis_freq;
47516a92a42STang Yun ping unsigned int ddr3_drv;
47616a92a42STang Yun ping unsigned int ddr3_odt;
47716a92a42STang Yun ping unsigned int phy_ddr3_ca_drv;
47816a92a42STang Yun ping unsigned int phy_ddr3_ck_drv;
47916a92a42STang Yun ping unsigned int phy_ddr3_dq_drv;
48016a92a42STang Yun ping unsigned int phy_ddr3_odt;
48116a92a42STang Yun ping
48216a92a42STang Yun ping unsigned int phy_lpddr2_odt_dis_freq;
48316a92a42STang Yun ping unsigned int lpddr2_drv;
48416a92a42STang Yun ping unsigned int phy_lpddr2_ca_drv;
48516a92a42STang Yun ping unsigned int phy_lpddr2_ck_drv;
48616a92a42STang Yun ping unsigned int phy_lpddr2_dq_drv;
48716a92a42STang Yun ping unsigned int phy_lpddr2_odt;
48816a92a42STang Yun ping
48916a92a42STang Yun ping unsigned int lpddr3_odt_dis_freq;
49016a92a42STang Yun ping unsigned int phy_lpddr3_odt_dis_freq;
49116a92a42STang Yun ping unsigned int lpddr3_drv;
49216a92a42STang Yun ping unsigned int lpddr3_odt;
49316a92a42STang Yun ping unsigned int phy_lpddr3_ca_drv;
49416a92a42STang Yun ping unsigned int phy_lpddr3_ck_drv;
49516a92a42STang Yun ping unsigned int phy_lpddr3_dq_drv;
49616a92a42STang Yun ping unsigned int phy_lpddr3_odt;
49716a92a42STang Yun ping
49816a92a42STang Yun ping unsigned int lpddr4_odt_dis_freq;
49916a92a42STang Yun ping unsigned int phy_lpddr4_odt_dis_freq;
50016a92a42STang Yun ping unsigned int lpddr4_drv;
50116a92a42STang Yun ping unsigned int lpddr4_dq_odt;
50216a92a42STang Yun ping unsigned int lpddr4_ca_odt;
50316a92a42STang Yun ping unsigned int phy_lpddr4_ca_drv;
50416a92a42STang Yun ping unsigned int phy_lpddr4_ck_cs_drv;
50516a92a42STang Yun ping unsigned int phy_lpddr4_dq_drv;
50616a92a42STang Yun ping unsigned int phy_lpddr4_odt;
50716a92a42STang Yun ping
50816a92a42STang Yun ping unsigned int ddr4_odt_dis_freq;
50916a92a42STang Yun ping unsigned int phy_ddr4_odt_dis_freq;
51016a92a42STang Yun ping unsigned int ddr4_drv;
51116a92a42STang Yun ping unsigned int ddr4_odt;
51216a92a42STang Yun ping unsigned int phy_ddr4_ca_drv;
51316a92a42STang Yun ping unsigned int phy_ddr4_ck_drv;
51416a92a42STang Yun ping unsigned int phy_ddr4_dq_drv;
51516a92a42STang Yun ping unsigned int phy_ddr4_odt;
51616a92a42STang Yun ping
51716a92a42STang Yun ping unsigned int ca_skew[15];
51816a92a42STang Yun ping unsigned int cs0_skew[44];
51916a92a42STang Yun ping unsigned int cs1_skew[44];
52016a92a42STang Yun ping
52116a92a42STang Yun ping unsigned int available;
52216a92a42STang Yun ping };
52316a92a42STang Yun ping
52416a92a42STang Yun ping struct rk3328_ddr_de_skew_setting {
52516a92a42STang Yun ping unsigned int ca_de_skew[30];
52616a92a42STang Yun ping unsigned int cs0_de_skew[84];
52716a92a42STang Yun ping unsigned int cs1_de_skew[84];
52816a92a42STang Yun ping };
52916a92a42STang Yun ping
53016a92a42STang Yun ping static void
rk3328_de_skew_setting_2_register(struct rk3328_ddr_de_skew_setting * de_skew,struct rk3328_ddr_dts_config_timing * tim)53116a92a42STang Yun ping rk3328_de_skew_setting_2_register(struct rk3328_ddr_de_skew_setting *de_skew,
53216a92a42STang Yun ping struct rk3328_ddr_dts_config_timing *tim)
53316a92a42STang Yun ping {
53416a92a42STang Yun ping u32 n;
53516a92a42STang Yun ping u32 offset;
53616a92a42STang Yun ping u32 shift;
53716a92a42STang Yun ping
53816a92a42STang Yun ping memset_io(tim->ca_skew, 0, sizeof(tim->ca_skew));
53916a92a42STang Yun ping memset_io(tim->cs0_skew, 0, sizeof(tim->cs0_skew));
54016a92a42STang Yun ping memset_io(tim->cs1_skew, 0, sizeof(tim->cs1_skew));
54116a92a42STang Yun ping
54216a92a42STang Yun ping /* CA de-skew */
54316a92a42STang Yun ping for (n = 0; n < ARRAY_SIZE(de_skew->ca_de_skew); n++) {
54416a92a42STang Yun ping offset = n / 2;
54516a92a42STang Yun ping shift = n % 2;
54616a92a42STang Yun ping /* 0 => 4; 1 => 0 */
54716a92a42STang Yun ping shift = (shift == 0) ? 4 : 0;
54816a92a42STang Yun ping tim->ca_skew[offset] &= ~(0xf << shift);
54916a92a42STang Yun ping tim->ca_skew[offset] |= (de_skew->ca_de_skew[n] << shift);
55016a92a42STang Yun ping }
55116a92a42STang Yun ping
55216a92a42STang Yun ping /* CS0 data de-skew */
55316a92a42STang Yun ping for (n = 0; n < ARRAY_SIZE(de_skew->cs0_de_skew); n++) {
55416a92a42STang Yun ping offset = ((n / 21) * 11) + ((n % 21) / 2);
55516a92a42STang Yun ping shift = ((n % 21) % 2);
55616a92a42STang Yun ping if ((n % 21) == 20)
55716a92a42STang Yun ping shift = 0;
55816a92a42STang Yun ping else
55916a92a42STang Yun ping /* 0 => 4; 1 => 0 */
56016a92a42STang Yun ping shift = (shift == 0) ? 4 : 0;
56116a92a42STang Yun ping tim->cs0_skew[offset] &= ~(0xf << shift);
56216a92a42STang Yun ping tim->cs0_skew[offset] |= (de_skew->cs0_de_skew[n] << shift);
56316a92a42STang Yun ping }
56416a92a42STang Yun ping
56516a92a42STang Yun ping /* CS1 data de-skew */
56616a92a42STang Yun ping for (n = 0; n < ARRAY_SIZE(de_skew->cs1_de_skew); n++) {
56716a92a42STang Yun ping offset = ((n / 21) * 11) + ((n % 21) / 2);
56816a92a42STang Yun ping shift = ((n % 21) % 2);
56916a92a42STang Yun ping if ((n % 21) == 20)
57016a92a42STang Yun ping shift = 0;
57116a92a42STang Yun ping else
57216a92a42STang Yun ping /* 0 => 4; 1 => 0 */
57316a92a42STang Yun ping shift = (shift == 0) ? 4 : 0;
57416a92a42STang Yun ping tim->cs1_skew[offset] &= ~(0xf << shift);
57516a92a42STang Yun ping tim->cs1_skew[offset] |= (de_skew->cs1_de_skew[n] << shift);
57616a92a42STang Yun ping }
57716a92a42STang Yun ping }
57816a92a42STang Yun ping
px30_de_skew_set_2_reg(struct rk3328_ddr_de_skew_setting * de_skew,struct px30_ddr_dts_config_timing * tim)57916a92a42STang Yun ping static void px30_de_skew_set_2_reg(struct rk3328_ddr_de_skew_setting *de_skew,
58016a92a42STang Yun ping struct px30_ddr_dts_config_timing *tim)
58116a92a42STang Yun ping {
58216a92a42STang Yun ping u32 n;
58316a92a42STang Yun ping u32 offset;
58416a92a42STang Yun ping u32 shift;
58516a92a42STang Yun ping
58616a92a42STang Yun ping memset_io(tim->ca_skew, 0, sizeof(tim->ca_skew));
58716a92a42STang Yun ping memset_io(tim->cs0_skew, 0, sizeof(tim->cs0_skew));
58816a92a42STang Yun ping memset_io(tim->cs1_skew, 0, sizeof(tim->cs1_skew));
58916a92a42STang Yun ping
59016a92a42STang Yun ping /* CA de-skew */
59116a92a42STang Yun ping for (n = 0; n < ARRAY_SIZE(de_skew->ca_de_skew); n++) {
59216a92a42STang Yun ping offset = n / 2;
59316a92a42STang Yun ping shift = n % 2;
59416a92a42STang Yun ping /* 0 => 4; 1 => 0 */
59516a92a42STang Yun ping shift = (shift == 0) ? 4 : 0;
59616a92a42STang Yun ping tim->ca_skew[offset] &= ~(0xf << shift);
59716a92a42STang Yun ping tim->ca_skew[offset] |= (de_skew->ca_de_skew[n] << shift);
59816a92a42STang Yun ping }
59916a92a42STang Yun ping
60016a92a42STang Yun ping /* CS0 data de-skew */
60116a92a42STang Yun ping for (n = 0; n < ARRAY_SIZE(de_skew->cs0_de_skew); n++) {
60216a92a42STang Yun ping offset = ((n / 21) * 11) + ((n % 21) / 2);
60316a92a42STang Yun ping shift = ((n % 21) % 2);
60416a92a42STang Yun ping if ((n % 21) == 20)
60516a92a42STang Yun ping shift = 0;
60616a92a42STang Yun ping else
60716a92a42STang Yun ping /* 0 => 4; 1 => 0 */
60816a92a42STang Yun ping shift = (shift == 0) ? 4 : 0;
60916a92a42STang Yun ping tim->cs0_skew[offset] &= ~(0xf << shift);
61016a92a42STang Yun ping tim->cs0_skew[offset] |= (de_skew->cs0_de_skew[n] << shift);
61116a92a42STang Yun ping }
61216a92a42STang Yun ping
61316a92a42STang Yun ping /* CS1 data de-skew */
61416a92a42STang Yun ping for (n = 0; n < ARRAY_SIZE(de_skew->cs1_de_skew); n++) {
61516a92a42STang Yun ping offset = ((n / 21) * 11) + ((n % 21) / 2);
61616a92a42STang Yun ping shift = ((n % 21) % 2);
61716a92a42STang Yun ping if ((n % 21) == 20)
61816a92a42STang Yun ping shift = 0;
61916a92a42STang Yun ping else
62016a92a42STang Yun ping /* 0 => 4; 1 => 0 */
62116a92a42STang Yun ping shift = (shift == 0) ? 4 : 0;
62216a92a42STang Yun ping tim->cs1_skew[offset] &= ~(0xf << shift);
62316a92a42STang Yun ping tim->cs1_skew[offset] |= (de_skew->cs1_de_skew[n] << shift);
62416a92a42STang Yun ping }
62516a92a42STang Yun ping }
62616a92a42STang Yun ping
of_get_rk3328_timings(struct udevice * dev,uint32_t * timing)62716a92a42STang Yun ping static void of_get_rk3328_timings(struct udevice *dev, uint32_t *timing)
62816a92a42STang Yun ping {
62916a92a42STang Yun ping struct device_node *np_tim;
63016a92a42STang Yun ping u32 *p;
63116a92a42STang Yun ping struct rk3328_ddr_dts_config_timing *dts_timing;
63216a92a42STang Yun ping struct rk3328_ddr_de_skew_setting *de_skew;
63316a92a42STang Yun ping int ret = 0;
63416a92a42STang Yun ping u32 i;
63516a92a42STang Yun ping
63616a92a42STang Yun ping dts_timing =
63716a92a42STang Yun ping (struct rk3328_ddr_dts_config_timing *)(timing +
63816a92a42STang Yun ping DTS_PAR_OFFSET / 4);
63916a92a42STang Yun ping
64016a92a42STang Yun ping np_tim = of_parse_phandle(ofnode_to_np(dev_ofnode(dev)),
64116a92a42STang Yun ping "ddr_timing", 0);
64216a92a42STang Yun ping if (!np_tim) {
64316a92a42STang Yun ping ret = -EINVAL;
64416a92a42STang Yun ping goto end;
64516a92a42STang Yun ping }
64616a92a42STang Yun ping de_skew = malloc(sizeof(*de_skew));
64716a92a42STang Yun ping if (!de_skew) {
64816a92a42STang Yun ping ret = -ENOMEM;
64916a92a42STang Yun ping goto end;
65016a92a42STang Yun ping }
65116a92a42STang Yun ping p = (u32 *)dts_timing;
65216a92a42STang Yun ping for (i = 0; i < ARRAY_SIZE(rk3328_dts_timing); i++)
65316a92a42STang Yun ping ret |= ofnode_read_u32(np_to_ofnode(np_tim),
65416a92a42STang Yun ping rk3328_dts_timing[i], p + i);
65516a92a42STang Yun ping
65616a92a42STang Yun ping p = (u32 *)de_skew->ca_de_skew;
65716a92a42STang Yun ping for (i = 0; i < ARRAY_SIZE(rk3328_dts_ca_timing); i++)
65816a92a42STang Yun ping ret |= ofnode_read_u32(np_to_ofnode(np_tim),
65916a92a42STang Yun ping rk3328_dts_ca_timing[i], p + i);
66016a92a42STang Yun ping p = (u32 *)de_skew->cs0_de_skew;
66116a92a42STang Yun ping for (i = 0; i < ARRAY_SIZE(rk3328_dts_cs0_timing); i++)
66216a92a42STang Yun ping ret |= ofnode_read_u32(np_to_ofnode(np_tim),
66316a92a42STang Yun ping rk3328_dts_cs0_timing[i], p + i);
66416a92a42STang Yun ping p = (u32 *)de_skew->cs1_de_skew;
66516a92a42STang Yun ping for (i = 0; i < ARRAY_SIZE(rk3328_dts_cs1_timing); i++)
66616a92a42STang Yun ping ret |= ofnode_read_u32(np_to_ofnode(np_tim),
66716a92a42STang Yun ping rk3328_dts_cs1_timing[i], p + i);
66816a92a42STang Yun ping
66916a92a42STang Yun ping if (!ret)
67016a92a42STang Yun ping rk3328_de_skew_setting_2_register(de_skew, dts_timing);
67116a92a42STang Yun ping free(de_skew);
67216a92a42STang Yun ping end:
67316a92a42STang Yun ping if (!ret) {
67416a92a42STang Yun ping dts_timing->available = 1;
67516a92a42STang Yun ping } else {
67616a92a42STang Yun ping dts_timing->available = 0;
67716a92a42STang Yun ping printf("of_get_ddr_timings: fail\n");
67816a92a42STang Yun ping }
67916a92a42STang Yun ping }
68016a92a42STang Yun ping
of_get_px30_timings(struct udevice * dev,uint32_t * timing)68116a92a42STang Yun ping static void of_get_px30_timings(struct udevice *dev, uint32_t *timing)
68216a92a42STang Yun ping {
68316a92a42STang Yun ping struct device_node *np_tim;
68416a92a42STang Yun ping u32 *p;
68516a92a42STang Yun ping struct px30_ddr_dts_config_timing *dts_timing;
68616a92a42STang Yun ping struct rk3328_ddr_de_skew_setting *de_skew;
68716a92a42STang Yun ping int ret = 0;
68816a92a42STang Yun ping u32 i;
68916a92a42STang Yun ping
69016a92a42STang Yun ping dts_timing =
69116a92a42STang Yun ping (struct px30_ddr_dts_config_timing *)(timing +
69216a92a42STang Yun ping DTS_PAR_OFFSET / 4);
69316a92a42STang Yun ping
69416a92a42STang Yun ping np_tim = of_parse_phandle(ofnode_to_np(dev_ofnode(dev)),
69516a92a42STang Yun ping "ddr_timing", 0);
69616a92a42STang Yun ping if (!np_tim) {
69716a92a42STang Yun ping ret = -EINVAL;
69816a92a42STang Yun ping goto end;
69916a92a42STang Yun ping }
70016a92a42STang Yun ping de_skew = malloc(sizeof(*de_skew));
70116a92a42STang Yun ping if (!de_skew) {
70216a92a42STang Yun ping ret = -ENOMEM;
70316a92a42STang Yun ping goto end;
70416a92a42STang Yun ping }
70516a92a42STang Yun ping p = (u32 *)dts_timing;
70616a92a42STang Yun ping for (i = 0; i < ARRAY_SIZE(px30_dts_timing); i++)
70716a92a42STang Yun ping ret |= ofnode_read_u32(np_to_ofnode(np_tim), px30_dts_timing[i],
70816a92a42STang Yun ping p + i);
70916a92a42STang Yun ping p = (u32 *)de_skew->ca_de_skew;
71016a92a42STang Yun ping for (i = 0; i < ARRAY_SIZE(rk3328_dts_ca_timing); i++)
71116a92a42STang Yun ping ret |= ofnode_read_u32(np_to_ofnode(np_tim),
71216a92a42STang Yun ping rk3328_dts_ca_timing[i], p + i);
71316a92a42STang Yun ping p = (u32 *)de_skew->cs0_de_skew;
71416a92a42STang Yun ping for (i = 0; i < ARRAY_SIZE(rk3328_dts_cs0_timing); i++)
71516a92a42STang Yun ping ret |= ofnode_read_u32(np_to_ofnode(np_tim),
71616a92a42STang Yun ping rk3328_dts_cs0_timing[i], p + i);
71716a92a42STang Yun ping p = (u32 *)de_skew->cs1_de_skew;
71816a92a42STang Yun ping for (i = 0; i < ARRAY_SIZE(rk3328_dts_cs1_timing); i++)
71916a92a42STang Yun ping ret |= ofnode_read_u32(np_to_ofnode(np_tim),
72016a92a42STang Yun ping rk3328_dts_cs1_timing[i], p + i);
72116a92a42STang Yun ping if (!ret)
72216a92a42STang Yun ping px30_de_skew_set_2_reg(de_skew, dts_timing);
72316a92a42STang Yun ping free(de_skew);
72416a92a42STang Yun ping end:
72516a92a42STang Yun ping if (!ret) {
72616a92a42STang Yun ping dts_timing->available = 1;
72716a92a42STang Yun ping } else {
72816a92a42STang Yun ping dts_timing->available = 0;
72916a92a42STang Yun ping printf("of_get_ddr_timings: fail\n");
73016a92a42STang Yun ping }
73116a92a42STang Yun ping }
73216a92a42STang Yun ping
rk3328_devfreq_init(struct udevice * dev)73316a92a42STang Yun ping static __maybe_unused int rk3328_devfreq_init(struct udevice *dev)
73416a92a42STang Yun ping {
73516a92a42STang Yun ping struct arm_smccc_res res;
73616a92a42STang Yun ping u32 size;
73716a92a42STang Yun ping
73816a92a42STang Yun ping res = sip_smc_dram(0, 0,
73916a92a42STang Yun ping ROCKCHIP_SIP_CONFIG_DRAM_GET_VERSION);
74016a92a42STang Yun ping printf("current ATF version 0x%lx!\n", res.a1);
74116a92a42STang Yun ping if (res.a0 || res.a1 < 0x101) {
74216a92a42STang Yun ping printf("trusted firmware need to update or is invalid!\n");
74316a92a42STang Yun ping return -ENXIO;
74416a92a42STang Yun ping }
74516a92a42STang Yun ping
74616a92a42STang Yun ping printf("read tf version 0x%lx!\n", res.a1);
74716a92a42STang Yun ping
74816a92a42STang Yun ping /*
74916a92a42STang Yun ping * first 4KB is used for interface parameters
75016a92a42STang Yun ping * after 4KB * N is dts parameters
75116a92a42STang Yun ping */
75216a92a42STang Yun ping size = sizeof(struct rk3328_ddr_dts_config_timing);
75316a92a42STang Yun ping res = sip_smc_request_share_mem(DIV_ROUND_UP(size, 4096) + 1,
75416a92a42STang Yun ping SHARE_PAGE_TYPE_DDR);
75516a92a42STang Yun ping if (res.a0 != 0) {
75616a92a42STang Yun ping printf("no ATF memory for init\n");
75716a92a42STang Yun ping return -ENOMEM;
75816a92a42STang Yun ping }
75916a92a42STang Yun ping ddr_psci_param = (struct share_params *)res.a1;
76016a92a42STang Yun ping of_get_rk3328_timings(dev, (uint32_t *)ddr_psci_param);
76116a92a42STang Yun ping
76216a92a42STang Yun ping flush_cache((unsigned long)ddr_psci_param,
76316a92a42STang Yun ping (DIV_ROUND_UP(size, 4096) + 1) * 0x1000);
76416a92a42STang Yun ping
76516a92a42STang Yun ping res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0,
76616a92a42STang Yun ping ROCKCHIP_SIP_CONFIG_DRAM_INIT);
76716a92a42STang Yun ping if (res.a0) {
76816a92a42STang Yun ping printf("rockchip_sip_config_dram_init error:%lx\n",
76916a92a42STang Yun ping res.a0);
77016a92a42STang Yun ping return -ENOMEM;
77116a92a42STang Yun ping }
77216a92a42STang Yun ping
77316a92a42STang Yun ping return 0;
77416a92a42STang Yun ping }
77516a92a42STang Yun ping
px30_devfreq_init(struct udevice * dev)77616a92a42STang Yun ping static __maybe_unused int px30_devfreq_init(struct udevice *dev)
77716a92a42STang Yun ping {
77816a92a42STang Yun ping struct arm_smccc_res res;
77916a92a42STang Yun ping u32 size;
78016a92a42STang Yun ping
78116a92a42STang Yun ping res = sip_smc_dram(0, 0,
78216a92a42STang Yun ping ROCKCHIP_SIP_CONFIG_DRAM_GET_VERSION);
78316a92a42STang Yun ping printf("current ATF version 0x%lx!\n", res.a1);
78416a92a42STang Yun ping if (res.a0 || res.a1 < 0x103) {
78516a92a42STang Yun ping printf("trusted firmware need to update or is invalid!\n");
78616a92a42STang Yun ping return -ENXIO;
78716a92a42STang Yun ping }
78816a92a42STang Yun ping
78916a92a42STang Yun ping printf("read tf version 0x%lx!\n", res.a1);
79016a92a42STang Yun ping
79116a92a42STang Yun ping /*
79216a92a42STang Yun ping * first 4KB is used for interface parameters
79316a92a42STang Yun ping * after 4KB * N is dts parameters
79416a92a42STang Yun ping */
79516a92a42STang Yun ping size = sizeof(struct px30_ddr_dts_config_timing);
79616a92a42STang Yun ping res = sip_smc_request_share_mem(DIV_ROUND_UP(size, 4096) + 1,
79716a92a42STang Yun ping SHARE_PAGE_TYPE_DDR);
79816a92a42STang Yun ping if (res.a0 != 0) {
79916a92a42STang Yun ping printf("no ATF memory for init\n");
80016a92a42STang Yun ping return -ENOMEM;
80116a92a42STang Yun ping }
80216a92a42STang Yun ping
80316a92a42STang Yun ping ddr_psci_param = (struct share_params *)res.a1;
80416a92a42STang Yun ping of_get_px30_timings(dev, (uint32_t *)ddr_psci_param);
80516a92a42STang Yun ping
80616a92a42STang Yun ping flush_cache((unsigned long)ddr_psci_param,
80716a92a42STang Yun ping (DIV_ROUND_UP(size, 4096) + 1) * 0x1000);
80816a92a42STang Yun ping res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0,
80916a92a42STang Yun ping ROCKCHIP_SIP_CONFIG_DRAM_INIT);
81016a92a42STang Yun ping if (res.a0) {
81116a92a42STang Yun ping printf("rockchip_sip_config_dram_init error:%lx\n",
81216a92a42STang Yun ping res.a0);
81316a92a42STang Yun ping return -ENOMEM;
81416a92a42STang Yun ping }
81516a92a42STang Yun ping
81616a92a42STang Yun ping return 0;
81716a92a42STang Yun ping }
81816a92a42STang Yun ping
rockchip_ddrclk_sip_set_rate_v2(unsigned long drate)81916a92a42STang Yun ping int rockchip_ddrclk_sip_set_rate_v2(unsigned long drate)
82016a92a42STang Yun ping {
82116a92a42STang Yun ping struct share_params *p;
82216a92a42STang Yun ping struct arm_smccc_res res;
82316a92a42STang Yun ping
82416a92a42STang Yun ping p = ddr_psci_param;
82516a92a42STang Yun ping
82616a92a42STang Yun ping p->hz = drate;
82716a92a42STang Yun ping p->lcdc_type = 0;
82816a92a42STang Yun ping p->wait_flag1 = 0;
82916a92a42STang Yun ping p->wait_flag0 = 0;
83016a92a42STang Yun ping p->complt_hwirq = 105;
83116a92a42STang Yun ping
83216a92a42STang Yun ping flush_cache((unsigned long)ddr_psci_param, sizeof(struct share_params));
83316a92a42STang Yun ping res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0,
83416a92a42STang Yun ping ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE);
83516a92a42STang Yun ping
83616a92a42STang Yun ping return res.a0;
83716a92a42STang Yun ping }
83816a92a42STang Yun ping
rockchip_ddrclk_sip_recalc_rate_v2(void)83916a92a42STang Yun ping unsigned long rockchip_ddrclk_sip_recalc_rate_v2(void)
84016a92a42STang Yun ping {
84116a92a42STang Yun ping struct arm_smccc_res res;
84216a92a42STang Yun ping
84316a92a42STang Yun ping res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0,
84416a92a42STang Yun ping ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE);
84516a92a42STang Yun ping if (!res.a0)
84616a92a42STang Yun ping return res.a1;
84716a92a42STang Yun ping else
84816a92a42STang Yun ping return 0;
84916a92a42STang Yun ping }
85016a92a42STang Yun ping
rockchip_ddrclk_sip_round_rate_v2(unsigned long rate)85116a92a42STang Yun ping unsigned long rockchip_ddrclk_sip_round_rate_v2(unsigned long rate)
85216a92a42STang Yun ping {
85316a92a42STang Yun ping struct share_params *p;
85416a92a42STang Yun ping struct arm_smccc_res res;
85516a92a42STang Yun ping
85616a92a42STang Yun ping p = ddr_psci_param;
85716a92a42STang Yun ping
85816a92a42STang Yun ping p->hz = rate;
85916a92a42STang Yun ping
86016a92a42STang Yun ping flush_cache((unsigned long)ddr_psci_param, sizeof(struct share_params));
86116a92a42STang Yun ping
86216a92a42STang Yun ping res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0,
86316a92a42STang Yun ping ROCKCHIP_SIP_CONFIG_DRAM_ROUND_RATE);
86416a92a42STang Yun ping if (!res.a0)
86516a92a42STang Yun ping return res.a1;
86616a92a42STang Yun ping else
86716a92a42STang Yun ping return 0;
86816a92a42STang Yun ping }
86916a92a42STang Yun ping
set_ddr_freq(unsigned long freq)870*6bce753fSTang Yun ping int set_ddr_freq(unsigned long freq)
871*6bce753fSTang Yun ping {
872*6bce753fSTang Yun ping if (freq < MHZ)
873*6bce753fSTang Yun ping freq *= MHZ;
874*6bce753fSTang Yun ping if (freq) {
875*6bce753fSTang Yun ping freq = rockchip_ddrclk_sip_round_rate_v2(freq);
876*6bce753fSTang Yun ping rockchip_ddrclk_sip_set_rate_v2(freq);
877*6bce753fSTang Yun ping }
878*6bce753fSTang Yun ping freq = rockchip_ddrclk_sip_recalc_rate_v2();
879*6bce753fSTang Yun ping printf("current ddr freq:%lu Hz\n", freq);
880*6bce753fSTang Yun ping
881*6bce753fSTang Yun ping return freq;
882*6bce753fSTang Yun ping }
883*6bce753fSTang Yun ping
rockchip_dmcfreq_probe(struct udevice * dev)88416a92a42STang Yun ping int rockchip_dmcfreq_probe(struct udevice *dev)
88516a92a42STang Yun ping {
88616a92a42STang Yun ping int ret;
88716a92a42STang Yun ping
88816a92a42STang Yun ping #if defined(CONFIG_ROCKCHIP_PX30)
88916a92a42STang Yun ping ret = px30_devfreq_init(dev);
89016a92a42STang Yun ping #elif defined(CONFIG_ROCKCHIP_RK3328)
89116a92a42STang Yun ping ret = rk3328_devfreq_init(dev);
89216a92a42STang Yun ping #else
89316a92a42STang Yun ping ret = -1;
89416a92a42STang Yun ping printf("Unsupported chip type\n");
89516a92a42STang Yun ping #endif
89616a92a42STang Yun ping if (ret)
89716a92a42STang Yun ping return ret;
89816a92a42STang Yun ping
89916a92a42STang Yun ping printf("dram freq:%ld Hz\n", rockchip_ddrclk_sip_recalc_rate_v2());
90016a92a42STang Yun ping
90116a92a42STang Yun ping return 0;
90216a92a42STang Yun ping }
903