1d8e26cc8SYouMin Chen // SPDX-License-Identifier: GPL-2.0+
2d8e26cc8SYouMin Chen /*
3d8e26cc8SYouMin Chen * (C) Copyright 2021 Rockchip Electronics Co., Ltd.
4d8e26cc8SYouMin Chen */
5d8e26cc8SYouMin Chen
6d8e26cc8SYouMin Chen #include <common.h>
7d8e26cc8SYouMin Chen #include <dm.h>
8d8e26cc8SYouMin Chen #include <syscon.h>
9d8e26cc8SYouMin Chen #include <asm/io.h>
10d8e26cc8SYouMin Chen #include <dm/of_access.h>
11d8e26cc8SYouMin Chen #include <asm/arch/clock.h>
12d8e26cc8SYouMin Chen #include <asm/arch/rockchip_smccc.h>
13d8e26cc8SYouMin Chen #include <asm/arch/sdram.h>
14d8e26cc8SYouMin Chen #include <asm/arch/sdram_common.h>
15d8e26cc8SYouMin Chen
16d8e26cc8SYouMin Chen #define DDR2_PARAMS_PHANDLE_NAME "ddr2_params"
17d8e26cc8SYouMin Chen #define DDR3_PARAMS_PHANDLE_NAME "ddr3_params"
18d8e26cc8SYouMin Chen #define DDR4_PARAMS_PHANDLE_NAME "ddr4_params"
19d8e26cc8SYouMin Chen #define LPDDR2_PARAMS_PHANDLE_NAME "lpddr2_params"
20d8e26cc8SYouMin Chen #define LPDDR3_PARAMS_PHANDLE_NAME "lpddr3_params"
21d8e26cc8SYouMin Chen #define LPDDR4_PARAMS_PHANDLE_NAME "lpddr4_params"
22d8e26cc8SYouMin Chen #define LPDDR4X_PARAMS_PHANDLE_NAME "lpddr4x_params"
23d8e26cc8SYouMin Chen #define LPDDR5_PARAMS_PHANDLE_NAME "lpddr5_params"
24d8e26cc8SYouMin Chen
25d8e26cc8SYouMin Chen #define DTS_PAR_OFFSET (4096)
26d8e26cc8SYouMin Chen #define PARAMS_INVALID_VAL (0xff00aa99)
27*e97e46abSZhihuan He #define PARAMS_IGNORE_THIS (0)
28d8e26cc8SYouMin Chen
29d8e26cc8SYouMin Chen #define PMUGRF_OS_REG(n) (0x200 + (n) * 4)
30d8e26cc8SYouMin Chen
319aff8079SZhihuan He struct rk3326_ddr_de_skew_setting {
329aff8079SZhihuan He unsigned int ca_de_skew[30];
339aff8079SZhihuan He unsigned int cs0_de_skew[84];
349aff8079SZhihuan He unsigned int cs1_de_skew[84];
359aff8079SZhihuan He };
369aff8079SZhihuan He
37d8e26cc8SYouMin Chen /* there is a matching relationship, modify it with caution */
38d8e26cc8SYouMin Chen static char *dmc_fsp_params[] = {
39d8e26cc8SYouMin Chen "debug_print_level",
409aff8079SZhihuan He "phy_de_skew_en",
41d8e26cc8SYouMin Chen /* if need, add parameter after */
42d8e26cc8SYouMin Chen };
43d8e26cc8SYouMin Chen
44d8e26cc8SYouMin Chen /* there is a matching relationship, modify it with caution */
45d8e26cc8SYouMin Chen static char *ddr_params_v1[] = {
46d8e26cc8SYouMin Chen /* version information V1.00 */
47d8e26cc8SYouMin Chen "version",
48d8e26cc8SYouMin Chen "expanded_version",
49d8e26cc8SYouMin Chen "reserved",
50d8e26cc8SYouMin Chen /* freq info, freq_0 is final frequency, unit: MHz */
51d8e26cc8SYouMin Chen "freq_0",
52d8e26cc8SYouMin Chen "freq_1",
53d8e26cc8SYouMin Chen "freq_2",
54d8e26cc8SYouMin Chen "freq_3",
55d8e26cc8SYouMin Chen "freq_4",
56d8e26cc8SYouMin Chen "freq_5",
57d8e26cc8SYouMin Chen /* power save setting */
58d8e26cc8SYouMin Chen "pd_idle",
59d8e26cc8SYouMin Chen "sr_idle",
60d8e26cc8SYouMin Chen "sr_mc_gate_idle",
61d8e26cc8SYouMin Chen "srpd_lite_idle",
62d8e26cc8SYouMin Chen "standby_idle",
63d8e26cc8SYouMin Chen "pd_dis_freq",
64d8e26cc8SYouMin Chen "sr_dis_freq",
65d8e26cc8SYouMin Chen "dram_dll_dis_freq",
66d8e26cc8SYouMin Chen "phy_dll_dis_freq",
67d8e26cc8SYouMin Chen /* drv when odt on */
68d8e26cc8SYouMin Chen "phy_dq_drv_odten",
69d8e26cc8SYouMin Chen "phy_ca_drv_odten",
70d8e26cc8SYouMin Chen "phy_clk_drv_odten",
71d8e26cc8SYouMin Chen "dram_dq_drv_odten",
72d8e26cc8SYouMin Chen /* drv when odt off */
73d8e26cc8SYouMin Chen "phy_dq_drv_odtoff",
74d8e26cc8SYouMin Chen "phy_ca_drv_odtoff",
75d8e26cc8SYouMin Chen "phy_clk_drv_odtoff",
76d8e26cc8SYouMin Chen "dram_dq_drv_odtoff",
77d8e26cc8SYouMin Chen /* odt info */
78d8e26cc8SYouMin Chen "dram_odt",
79d8e26cc8SYouMin Chen "phy_odt",
80d8e26cc8SYouMin Chen "phy_odt_puup_en",
81d8e26cc8SYouMin Chen "phy_odt_pudn_en",
82d8e26cc8SYouMin Chen /* odt enable freq */
83d8e26cc8SYouMin Chen "dram_dq_odt_en_freq",
84d8e26cc8SYouMin Chen "phy_odt_en_freq",
85d8e26cc8SYouMin Chen /* slew rate when odt enable */
86d8e26cc8SYouMin Chen "phy_dq_sr_odten",
87d8e26cc8SYouMin Chen "phy_ca_sr_odten",
88d8e26cc8SYouMin Chen "phy_clk_sr_odten",
89d8e26cc8SYouMin Chen /* slew rate when odt disable */
90d8e26cc8SYouMin Chen "phy_dq_sr_odtoff",
91d8e26cc8SYouMin Chen "phy_ca_sr_odtoff",
92d8e26cc8SYouMin Chen "phy_clk_sr_odtoff",
93d8e26cc8SYouMin Chen /* ssmod setting*/
94d8e26cc8SYouMin Chen "ssmod_downspread",
95d8e26cc8SYouMin Chen "ssmod_div",
96d8e26cc8SYouMin Chen "ssmod_spread",
97d8e26cc8SYouMin Chen /* 2T mode */
98d8e26cc8SYouMin Chen "mode_2t",
99d8e26cc8SYouMin Chen /* speed bin */
100d8e26cc8SYouMin Chen "speed_bin",
101d8e26cc8SYouMin Chen /* dram extended temperature support */
102d8e26cc8SYouMin Chen "dram_ext_temp",
103d8e26cc8SYouMin Chen /* byte map */
104d8e26cc8SYouMin Chen "byte_map",
105d8e26cc8SYouMin Chen /* dq map */
106d8e26cc8SYouMin Chen "dq_map_cs0_dq_l",
107d8e26cc8SYouMin Chen "dq_map_cs0_dq_h",
108d8e26cc8SYouMin Chen "dq_map_cs1_dq_l",
109d8e26cc8SYouMin Chen "dq_map_cs1_dq_h",
110d8e26cc8SYouMin Chen /* for LPDDR4 and LPDDR4X */
111d8e26cc8SYouMin Chen /* odt info */
112d8e26cc8SYouMin Chen "lp4_ca_odt",
113d8e26cc8SYouMin Chen "lp4_drv_pu_cal_odten",
114d8e26cc8SYouMin Chen "lp4_drv_pu_cal_odtoff",
115d8e26cc8SYouMin Chen "phy_lp4_drv_pulldown_en_odten",
116d8e26cc8SYouMin Chen "phy_lp4_drv_pulldown_en_odtoff",
117d8e26cc8SYouMin Chen /* odt enable freq */
118d8e26cc8SYouMin Chen "lp4_ca_odt_en_freq",
119d8e26cc8SYouMin Chen /* lp4 cs drv info and ca odt info */
120d8e26cc8SYouMin Chen "phy_lp4_cs_drv_odten",
121d8e26cc8SYouMin Chen "phy_lp4_cs_drv_odtoff",
122d8e26cc8SYouMin Chen "lp4_odte_ck_en",
123d8e26cc8SYouMin Chen "lp4_odte_cs_en",
124d8e26cc8SYouMin Chen "lp4_odtd_ca_en",
125d8e26cc8SYouMin Chen /* lp4 vref info when odt enable */
126d8e26cc8SYouMin Chen "phy_lp4_dq_vref_odten",
127d8e26cc8SYouMin Chen "lp4_dq_vref_odten",
128d8e26cc8SYouMin Chen "lp4_ca_vref_odten",
129d8e26cc8SYouMin Chen /* lp4 vref info when odt disable */
130d8e26cc8SYouMin Chen "phy_lp4_dq_vref_odtoff",
131d8e26cc8SYouMin Chen "lp4_dq_vref_odtoff",
132d8e26cc8SYouMin Chen "lp4_ca_vref_odtoff",
133d8e26cc8SYouMin Chen /* if need, add parameter after and change the minor version. */
134d8e26cc8SYouMin Chen };
135d8e26cc8SYouMin Chen
136*e97e46abSZhihuan He /* the expanded version V1.00 add skew info */
137*e97e46abSZhihuan He static char *ddr_params_exp_v1[] = {
1389aff8079SZhihuan He "ddr3a1_ddr4a9_de-skew",
1399aff8079SZhihuan He "ddr3a0_ddr4a10_de-skew",
1409aff8079SZhihuan He "ddr3a3_ddr4a6_de-skew",
1419aff8079SZhihuan He "ddr3a2_ddr4a4_de-skew",
1429aff8079SZhihuan He "ddr3a5_ddr4a8_de-skew",
1439aff8079SZhihuan He "ddr3a4_ddr4a5_de-skew",
1449aff8079SZhihuan He "ddr3a7_ddr4a11_de-skew",
1459aff8079SZhihuan He "ddr3a6_ddr4a7_de-skew",
1469aff8079SZhihuan He "ddr3a9_ddr4a0_de-skew",
1479aff8079SZhihuan He "ddr3a8_ddr4a13_de-skew",
1489aff8079SZhihuan He "ddr3a11_ddr4a3_de-skew",
1499aff8079SZhihuan He "ddr3a10_ddr4cs0_de-skew",
1509aff8079SZhihuan He "ddr3a13_ddr4a2_de-skew",
1519aff8079SZhihuan He "ddr3a12_ddr4ba1_de-skew",
1529aff8079SZhihuan He "ddr3a15_ddr4odt0_de-skew",
1539aff8079SZhihuan He "ddr3a14_ddr4a1_de-skew",
1549aff8079SZhihuan He "ddr3ba1_ddr4a15_de-skew",
1559aff8079SZhihuan He "ddr3ba0_ddr4bg0_de-skew",
1569aff8079SZhihuan He "ddr3ras_ddr4cke_de-skew",
1579aff8079SZhihuan He "ddr3ba2_ddr4ba0_de-skew",
1589aff8079SZhihuan He "ddr3we_ddr4bg1_de-skew",
1599aff8079SZhihuan He "ddr3cas_ddr4a12_de-skew",
1609aff8079SZhihuan He "ddr3ckn_ddr4ckn_de-skew",
1619aff8079SZhihuan He "ddr3ckp_ddr4ckp_de-skew",
1629aff8079SZhihuan He "ddr3cke_ddr4a16_de-skew",
1639aff8079SZhihuan He "ddr3odt0_ddr4a14_de-skew",
1649aff8079SZhihuan He "ddr3cs0_ddr4act_de-skew",
1659aff8079SZhihuan He "ddr3reset_ddr4reset_de-skew",
1669aff8079SZhihuan He "ddr3cs1_ddr4cs1_de-skew",
1679aff8079SZhihuan He "ddr3odt1_ddr4odt1_de-skew",
1689aff8079SZhihuan He
1699aff8079SZhihuan He "cs0_dm0_rx_de-skew",
1709aff8079SZhihuan He "cs0_dm0_tx_de-skew",
1719aff8079SZhihuan He "cs0_dq0_rx_de-skew",
1729aff8079SZhihuan He "cs0_dq0_tx_de-skew",
1739aff8079SZhihuan He "cs0_dq1_rx_de-skew",
1749aff8079SZhihuan He "cs0_dq1_tx_de-skew",
1759aff8079SZhihuan He "cs0_dq2_rx_de-skew",
1769aff8079SZhihuan He "cs0_dq2_tx_de-skew",
1779aff8079SZhihuan He "cs0_dq3_rx_de-skew",
1789aff8079SZhihuan He "cs0_dq3_tx_de-skew",
1799aff8079SZhihuan He "cs0_dq4_rx_de-skew",
1809aff8079SZhihuan He "cs0_dq4_tx_de-skew",
1819aff8079SZhihuan He "cs0_dq5_rx_de-skew",
1829aff8079SZhihuan He "cs0_dq5_tx_de-skew",
1839aff8079SZhihuan He "cs0_dq6_rx_de-skew",
1849aff8079SZhihuan He "cs0_dq6_tx_de-skew",
1859aff8079SZhihuan He "cs0_dq7_rx_de-skew",
1869aff8079SZhihuan He "cs0_dq7_tx_de-skew",
1879aff8079SZhihuan He "cs0_dqs0_rx_de-skew",
1889aff8079SZhihuan He "cs0_dqs0p_tx_de-skew",
1899aff8079SZhihuan He "cs0_dqs0n_tx_de-skew",
1909aff8079SZhihuan He
1919aff8079SZhihuan He "cs0_dm1_rx_de-skew",
1929aff8079SZhihuan He "cs0_dm1_tx_de-skew",
1939aff8079SZhihuan He "cs0_dq8_rx_de-skew",
1949aff8079SZhihuan He "cs0_dq8_tx_de-skew",
1959aff8079SZhihuan He "cs0_dq9_rx_de-skew",
1969aff8079SZhihuan He "cs0_dq9_tx_de-skew",
1979aff8079SZhihuan He "cs0_dq10_rx_de-skew",
1989aff8079SZhihuan He "cs0_dq10_tx_de-skew",
1999aff8079SZhihuan He "cs0_dq11_rx_de-skew",
2009aff8079SZhihuan He "cs0_dq11_tx_de-skew",
2019aff8079SZhihuan He "cs0_dq12_rx_de-skew",
2029aff8079SZhihuan He "cs0_dq12_tx_de-skew",
2039aff8079SZhihuan He "cs0_dq13_rx_de-skew",
2049aff8079SZhihuan He "cs0_dq13_tx_de-skew",
2059aff8079SZhihuan He "cs0_dq14_rx_de-skew",
2069aff8079SZhihuan He "cs0_dq14_tx_de-skew",
2079aff8079SZhihuan He "cs0_dq15_rx_de-skew",
2089aff8079SZhihuan He "cs0_dq15_tx_de-skew",
2099aff8079SZhihuan He "cs0_dqs1_rx_de-skew",
2109aff8079SZhihuan He "cs0_dqs1p_tx_de-skew",
2119aff8079SZhihuan He "cs0_dqs1n_tx_de-skew",
2129aff8079SZhihuan He
2139aff8079SZhihuan He "cs0_dm2_rx_de-skew",
2149aff8079SZhihuan He "cs0_dm2_tx_de-skew",
2159aff8079SZhihuan He "cs0_dq16_rx_de-skew",
2169aff8079SZhihuan He "cs0_dq16_tx_de-skew",
2179aff8079SZhihuan He "cs0_dq17_rx_de-skew",
2189aff8079SZhihuan He "cs0_dq17_tx_de-skew",
2199aff8079SZhihuan He "cs0_dq18_rx_de-skew",
2209aff8079SZhihuan He "cs0_dq18_tx_de-skew",
2219aff8079SZhihuan He "cs0_dq19_rx_de-skew",
2229aff8079SZhihuan He "cs0_dq19_tx_de-skew",
2239aff8079SZhihuan He "cs0_dq20_rx_de-skew",
2249aff8079SZhihuan He "cs0_dq20_tx_de-skew",
2259aff8079SZhihuan He "cs0_dq21_rx_de-skew",
2269aff8079SZhihuan He "cs0_dq21_tx_de-skew",
2279aff8079SZhihuan He "cs0_dq22_rx_de-skew",
2289aff8079SZhihuan He "cs0_dq22_tx_de-skew",
2299aff8079SZhihuan He "cs0_dq23_rx_de-skew",
2309aff8079SZhihuan He "cs0_dq23_tx_de-skew",
2319aff8079SZhihuan He "cs0_dqs2_rx_de-skew",
2329aff8079SZhihuan He "cs0_dqs2p_tx_de-skew",
2339aff8079SZhihuan He "cs0_dqs2n_tx_de-skew",
2349aff8079SZhihuan He
2359aff8079SZhihuan He "cs0_dm3_rx_de-skew",
2369aff8079SZhihuan He "cs0_dm3_tx_de-skew",
2379aff8079SZhihuan He "cs0_dq24_rx_de-skew",
2389aff8079SZhihuan He "cs0_dq24_tx_de-skew",
2399aff8079SZhihuan He "cs0_dq25_rx_de-skew",
2409aff8079SZhihuan He "cs0_dq25_tx_de-skew",
2419aff8079SZhihuan He "cs0_dq26_rx_de-skew",
2429aff8079SZhihuan He "cs0_dq26_tx_de-skew",
2439aff8079SZhihuan He "cs0_dq27_rx_de-skew",
2449aff8079SZhihuan He "cs0_dq27_tx_de-skew",
2459aff8079SZhihuan He "cs0_dq28_rx_de-skew",
2469aff8079SZhihuan He "cs0_dq28_tx_de-skew",
2479aff8079SZhihuan He "cs0_dq29_rx_de-skew",
2489aff8079SZhihuan He "cs0_dq29_tx_de-skew",
2499aff8079SZhihuan He "cs0_dq30_rx_de-skew",
2509aff8079SZhihuan He "cs0_dq30_tx_de-skew",
2519aff8079SZhihuan He "cs0_dq31_rx_de-skew",
2529aff8079SZhihuan He "cs0_dq31_tx_de-skew",
2539aff8079SZhihuan He "cs0_dqs3_rx_de-skew",
2549aff8079SZhihuan He "cs0_dqs3p_tx_de-skew",
2559aff8079SZhihuan He "cs0_dqs3n_tx_de-skew",
2569aff8079SZhihuan He
2579aff8079SZhihuan He "cs1_dm0_rx_de-skew",
2589aff8079SZhihuan He "cs1_dm0_tx_de-skew",
2599aff8079SZhihuan He "cs1_dq0_rx_de-skew",
2609aff8079SZhihuan He "cs1_dq0_tx_de-skew",
2619aff8079SZhihuan He "cs1_dq1_rx_de-skew",
2629aff8079SZhihuan He "cs1_dq1_tx_de-skew",
2639aff8079SZhihuan He "cs1_dq2_rx_de-skew",
2649aff8079SZhihuan He "cs1_dq2_tx_de-skew",
2659aff8079SZhihuan He "cs1_dq3_rx_de-skew",
2669aff8079SZhihuan He "cs1_dq3_tx_de-skew",
2679aff8079SZhihuan He "cs1_dq4_rx_de-skew",
2689aff8079SZhihuan He "cs1_dq4_tx_de-skew",
2699aff8079SZhihuan He "cs1_dq5_rx_de-skew",
2709aff8079SZhihuan He "cs1_dq5_tx_de-skew",
2719aff8079SZhihuan He "cs1_dq6_rx_de-skew",
2729aff8079SZhihuan He "cs1_dq6_tx_de-skew",
2739aff8079SZhihuan He "cs1_dq7_rx_de-skew",
2749aff8079SZhihuan He "cs1_dq7_tx_de-skew",
2759aff8079SZhihuan He "cs1_dqs0_rx_de-skew",
2769aff8079SZhihuan He "cs1_dqs0p_tx_de-skew",
2779aff8079SZhihuan He "cs1_dqs0n_tx_de-skew",
2789aff8079SZhihuan He
2799aff8079SZhihuan He "cs1_dm1_rx_de-skew",
2809aff8079SZhihuan He "cs1_dm1_tx_de-skew",
2819aff8079SZhihuan He "cs1_dq8_rx_de-skew",
2829aff8079SZhihuan He "cs1_dq8_tx_de-skew",
2839aff8079SZhihuan He "cs1_dq9_rx_de-skew",
2849aff8079SZhihuan He "cs1_dq9_tx_de-skew",
2859aff8079SZhihuan He "cs1_dq10_rx_de-skew",
2869aff8079SZhihuan He "cs1_dq10_tx_de-skew",
2879aff8079SZhihuan He "cs1_dq11_rx_de-skew",
2889aff8079SZhihuan He "cs1_dq11_tx_de-skew",
2899aff8079SZhihuan He "cs1_dq12_rx_de-skew",
2909aff8079SZhihuan He "cs1_dq12_tx_de-skew",
2919aff8079SZhihuan He "cs1_dq13_rx_de-skew",
2929aff8079SZhihuan He "cs1_dq13_tx_de-skew",
2939aff8079SZhihuan He "cs1_dq14_rx_de-skew",
2949aff8079SZhihuan He "cs1_dq14_tx_de-skew",
2959aff8079SZhihuan He "cs1_dq15_rx_de-skew",
2969aff8079SZhihuan He "cs1_dq15_tx_de-skew",
2979aff8079SZhihuan He "cs1_dqs1_rx_de-skew",
2989aff8079SZhihuan He "cs1_dqs1p_tx_de-skew",
2999aff8079SZhihuan He "cs1_dqs1n_tx_de-skew",
3009aff8079SZhihuan He
3019aff8079SZhihuan He "cs1_dm2_rx_de-skew",
3029aff8079SZhihuan He "cs1_dm2_tx_de-skew",
3039aff8079SZhihuan He "cs1_dq16_rx_de-skew",
3049aff8079SZhihuan He "cs1_dq16_tx_de-skew",
3059aff8079SZhihuan He "cs1_dq17_rx_de-skew",
3069aff8079SZhihuan He "cs1_dq17_tx_de-skew",
3079aff8079SZhihuan He "cs1_dq18_rx_de-skew",
3089aff8079SZhihuan He "cs1_dq18_tx_de-skew",
3099aff8079SZhihuan He "cs1_dq19_rx_de-skew",
3109aff8079SZhihuan He "cs1_dq19_tx_de-skew",
3119aff8079SZhihuan He "cs1_dq20_rx_de-skew",
3129aff8079SZhihuan He "cs1_dq20_tx_de-skew",
3139aff8079SZhihuan He "cs1_dq21_rx_de-skew",
3149aff8079SZhihuan He "cs1_dq21_tx_de-skew",
3159aff8079SZhihuan He "cs1_dq22_rx_de-skew",
3169aff8079SZhihuan He "cs1_dq22_tx_de-skew",
3179aff8079SZhihuan He "cs1_dq23_rx_de-skew",
3189aff8079SZhihuan He "cs1_dq23_tx_de-skew",
3199aff8079SZhihuan He "cs1_dqs2_rx_de-skew",
3209aff8079SZhihuan He "cs1_dqs2p_tx_de-skew",
3219aff8079SZhihuan He "cs1_dqs2n_tx_de-skew",
3229aff8079SZhihuan He
3239aff8079SZhihuan He "cs1_dm3_rx_de-skew",
3249aff8079SZhihuan He "cs1_dm3_tx_de-skew",
3259aff8079SZhihuan He "cs1_dq24_rx_de-skew",
3269aff8079SZhihuan He "cs1_dq24_tx_de-skew",
3279aff8079SZhihuan He "cs1_dq25_rx_de-skew",
3289aff8079SZhihuan He "cs1_dq25_tx_de-skew",
3299aff8079SZhihuan He "cs1_dq26_rx_de-skew",
3309aff8079SZhihuan He "cs1_dq26_tx_de-skew",
3319aff8079SZhihuan He "cs1_dq27_rx_de-skew",
3329aff8079SZhihuan He "cs1_dq27_tx_de-skew",
3339aff8079SZhihuan He "cs1_dq28_rx_de-skew",
3349aff8079SZhihuan He "cs1_dq28_tx_de-skew",
3359aff8079SZhihuan He "cs1_dq29_rx_de-skew",
3369aff8079SZhihuan He "cs1_dq29_tx_de-skew",
3379aff8079SZhihuan He "cs1_dq30_rx_de-skew",
3389aff8079SZhihuan He "cs1_dq30_tx_de-skew",
3399aff8079SZhihuan He "cs1_dq31_rx_de-skew",
3409aff8079SZhihuan He "cs1_dq31_tx_de-skew",
3419aff8079SZhihuan He "cs1_dqs3_rx_de-skew",
3429aff8079SZhihuan He "cs1_dqs3p_tx_de-skew",
3439aff8079SZhihuan He "cs1_dqs3n_tx_de-skew",
3449aff8079SZhihuan He };
3459aff8079SZhihuan He
get_atf_version(void)346d8e26cc8SYouMin Chen static int get_atf_version(void)
347d8e26cc8SYouMin Chen {
348d8e26cc8SYouMin Chen struct arm_smccc_res res;
349d8e26cc8SYouMin Chen
350d8e26cc8SYouMin Chen res = sip_smc_dram(0, 0, ROCKCHIP_SIP_CONFIG_DRAM_GET_VERSION);
351d8e26cc8SYouMin Chen
352d8e26cc8SYouMin Chen if (res.a0)
353d8e26cc8SYouMin Chen return -ENOMEM;
354d8e26cc8SYouMin Chen else
355d8e26cc8SYouMin Chen return res.a1;
356d8e26cc8SYouMin Chen }
357d8e26cc8SYouMin Chen
dmc_fsp_probe(struct udevice * dev)358d8e26cc8SYouMin Chen static int dmc_fsp_probe(struct udevice *dev)
359d8e26cc8SYouMin Chen {
3609aff8079SZhihuan He struct device_node *np_params, *np_tim;
361d8e26cc8SYouMin Chen struct arm_smccc_res res;
362d8e26cc8SYouMin Chen void *pmugrf_base;
363d8e26cc8SYouMin Chen int *p = NULL;
364d8e26cc8SYouMin Chen char *phandle_name = NULL;
365d8e26cc8SYouMin Chen char **ddr_params;
366*e97e46abSZhihuan He char **ddr_params_exp;
367d8e26cc8SYouMin Chen int ddr_params_version;
368*e97e46abSZhihuan He int expanded_version;
369d8e26cc8SYouMin Chen u32 dram_type, os_reg2_val, os_reg3_val;
3709aff8079SZhihuan He u32 phy_de_skew_en;
371*e97e46abSZhihuan He u32 i = 0, count = 0, size = 0, count_exp = 0;
372d8e26cc8SYouMin Chen ulong atf_version_limit;
373d8e26cc8SYouMin Chen
374d8e26cc8SYouMin Chen atf_version_limit = dev_get_driver_data(dev);
375d8e26cc8SYouMin Chen if (get_atf_version() < atf_version_limit) {
376d8e26cc8SYouMin Chen printf("%s: trusted firmware need to update or is invalid!\n", __func__);
377d8e26cc8SYouMin Chen printf("%s: current ATF version 0x%x, required version 0x%lx\n",
378d8e26cc8SYouMin Chen __func__, get_atf_version(), atf_version_limit);
379d8e26cc8SYouMin Chen return 0;
380d8e26cc8SYouMin Chen }
381d8e26cc8SYouMin Chen
382d8e26cc8SYouMin Chen pmugrf_base = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
383d8e26cc8SYouMin Chen os_reg2_val = readl(pmugrf_base + PMUGRF_OS_REG(2));
384d8e26cc8SYouMin Chen os_reg3_val = readl(pmugrf_base + PMUGRF_OS_REG(3));
385d8e26cc8SYouMin Chen dram_type = SYS_REG_DEC_DDRTYPE_V3(os_reg2_val, os_reg3_val);
386d8e26cc8SYouMin Chen
387d8e26cc8SYouMin Chen if (dram_type == DDR2)
388d8e26cc8SYouMin Chen phandle_name = DDR2_PARAMS_PHANDLE_NAME;
389d8e26cc8SYouMin Chen else if (dram_type == DDR3)
390d8e26cc8SYouMin Chen phandle_name = DDR3_PARAMS_PHANDLE_NAME;
391d8e26cc8SYouMin Chen else if (dram_type == DDR4)
392d8e26cc8SYouMin Chen phandle_name = DDR4_PARAMS_PHANDLE_NAME;
393d8e26cc8SYouMin Chen else if (dram_type == LPDDR2)
394d8e26cc8SYouMin Chen phandle_name = LPDDR2_PARAMS_PHANDLE_NAME;
395d8e26cc8SYouMin Chen else if (dram_type == LPDDR3)
396d8e26cc8SYouMin Chen phandle_name = LPDDR3_PARAMS_PHANDLE_NAME;
397d8e26cc8SYouMin Chen else if (dram_type == LPDDR4)
398d8e26cc8SYouMin Chen phandle_name = LPDDR4_PARAMS_PHANDLE_NAME;
399d8e26cc8SYouMin Chen else if (dram_type == LPDDR4X)
400d8e26cc8SYouMin Chen phandle_name = LPDDR4X_PARAMS_PHANDLE_NAME;
401d8e26cc8SYouMin Chen else if (dram_type == LPDDR5)
402d8e26cc8SYouMin Chen phandle_name = LPDDR5_PARAMS_PHANDLE_NAME;
403d8e26cc8SYouMin Chen else
404d8e26cc8SYouMin Chen printf("%s: dram_type unsupported\n", __func__);
405d8e26cc8SYouMin Chen
406d8e26cc8SYouMin Chen np_params = of_parse_phandle(ofnode_to_np(dev_ofnode(dev)), phandle_name, 0);
407d8e26cc8SYouMin Chen if (!np_params) {
408d8e26cc8SYouMin Chen printf("%s: of_parse_phandle %s error!\n", __func__, phandle_name);
409d8e26cc8SYouMin Chen return -EINVAL;
410d8e26cc8SYouMin Chen }
411d8e26cc8SYouMin Chen
412d8e26cc8SYouMin Chen ddr_params_version = ofnode_read_u32_default(np_to_ofnode(np_params), "version", -1);
413d8e26cc8SYouMin Chen if (ddr_params_version < 0) {
414d8e26cc8SYouMin Chen printf("%s: get ddr_params_version error\n", __func__);
415d8e26cc8SYouMin Chen return -EINVAL;
416d8e26cc8SYouMin Chen }
417d8e26cc8SYouMin Chen
418d8e26cc8SYouMin Chen if ((ddr_params_version & 0xff00) == 0x100 &&
4199aff8079SZhihuan He (ddr_params_version & 0xffff) <= 0x101) {
420*e97e46abSZhihuan He count = ARRAY_SIZE(ddr_params_v1);
4219aff8079SZhihuan He ddr_params = ddr_params_v1;
422d8e26cc8SYouMin Chen } else {
423d8e26cc8SYouMin Chen printf("%s: ddr_params_version=0x%x unsupported\n", __func__, ddr_params_version);
424d8e26cc8SYouMin Chen return -EINVAL;
425d8e26cc8SYouMin Chen }
426*e97e46abSZhihuan He
427*e97e46abSZhihuan He expanded_version = ofnode_read_u32_default(np_to_ofnode(np_params),
428*e97e46abSZhihuan He "expanded_version", 0);
429*e97e46abSZhihuan He if (expanded_version != PARAMS_IGNORE_THIS) {
430*e97e46abSZhihuan He if ((expanded_version & 0xff00) == 0x100 &&
431*e97e46abSZhihuan He (expanded_version & 0xffff) <= 0x100) {
432*e97e46abSZhihuan He count_exp = ARRAY_SIZE(ddr_params_exp_v1);
433*e97e46abSZhihuan He ddr_params_exp = ddr_params_exp_v1;
434*e97e46abSZhihuan He } else {
435*e97e46abSZhihuan He printf("expanded_version=0x%x unsupported\n",
436*e97e46abSZhihuan He expanded_version);
437*e97e46abSZhihuan He return -1;
438*e97e46abSZhihuan He }
439*e97e46abSZhihuan He } else if ((ddr_params_version & 0xffff) == 0x101) {
440*e97e46abSZhihuan He count_exp = ARRAY_SIZE(ddr_params_exp_v1);
441*e97e46abSZhihuan He }
4429aff8079SZhihuan He /*
4439aff8079SZhihuan He * page 0 is used for share param
444*e97e46abSZhihuan He * page 1~N is used for dmc_fsp and ddr_params_exp param
4459aff8079SZhihuan He */
446*e97e46abSZhihuan He size = ((count + count_exp) * 4 + 4096);
447d8e26cc8SYouMin Chen res = sip_smc_request_share_mem(DIV_ROUND_UP(size, 4096) + 1, SHARE_PAGE_TYPE_DDRFSP);
448d8e26cc8SYouMin Chen if (res.a0 != 0) {
449d8e26cc8SYouMin Chen printf("%s:no share memory for init\n", __func__);
450d8e26cc8SYouMin Chen return -ENOMEM;
451d8e26cc8SYouMin Chen }
452d8e26cc8SYouMin Chen
453d8e26cc8SYouMin Chen /* fill share memory and pass to the atf */
454d8e26cc8SYouMin Chen p = (int *)(res.a1);
455d8e26cc8SYouMin Chen for (i = 0; i < ARRAY_SIZE(dmc_fsp_params); i++)
456d8e26cc8SYouMin Chen p[i] = dev_read_u32_default(dev, dmc_fsp_params[i], PARAMS_INVALID_VAL);
457d8e26cc8SYouMin Chen
4589aff8079SZhihuan He phy_de_skew_en = p[1];
4599aff8079SZhihuan He
460d8e26cc8SYouMin Chen p = (int *)(res.a1 + DTS_PAR_OFFSET / 4);
4619aff8079SZhihuan He for (i = 0; i < ARRAY_SIZE(ddr_params_v1); i++) {
462d8e26cc8SYouMin Chen p[i] = ofnode_read_u32_default(np_to_ofnode(np_params), ddr_params[i],
463d8e26cc8SYouMin Chen PARAMS_INVALID_VAL);
464d8e26cc8SYouMin Chen }
465*e97e46abSZhihuan He
466*e97e46abSZhihuan He if (expanded_version != PARAMS_IGNORE_THIS) {
467*e97e46abSZhihuan He if ((expanded_version & 0xff00) == 0x100 &&
468*e97e46abSZhihuan He (expanded_version & 0xffff) <= 0x100) {
469*e97e46abSZhihuan He phandle_name = "ddr_timing";
470*e97e46abSZhihuan He np_tim =
471*e97e46abSZhihuan He of_parse_phandle(ofnode_to_np(dev_ofnode(dev)),
472*e97e46abSZhihuan He phandle_name, 0);
473*e97e46abSZhihuan He if (!np_tim) {
474*e97e46abSZhihuan He printf("%s: of_parse_phandle %s error!\n",
475*e97e46abSZhihuan He __func__, phandle_name);
476*e97e46abSZhihuan He return -EINVAL;
477*e97e46abSZhihuan He }
478*e97e46abSZhihuan He for (i = count; i < (count + count_exp); i++) {
479*e97e46abSZhihuan He p[i] =
480*e97e46abSZhihuan He ofnode_read_u32_default(np_to_ofnode(np_tim),
481*e97e46abSZhihuan He ddr_params_exp[i -
482*e97e46abSZhihuan He count],
483*e97e46abSZhihuan He PARAMS_INVALID_VAL);
484*e97e46abSZhihuan He }
485*e97e46abSZhihuan He /* expanded_version and start point */
486*e97e46abSZhihuan He p[1] = (p[1] & 0xffff) | (count << 16);
487*e97e46abSZhihuan He }
488*e97e46abSZhihuan He } else if (phy_de_skew_en && (phy_de_skew_en != PARAMS_INVALID_VAL)) {
4899aff8079SZhihuan He phandle_name = "ddr_timing";
4909aff8079SZhihuan He np_tim = of_parse_phandle(ofnode_to_np(dev_ofnode(dev)), phandle_name, 0);
4919aff8079SZhihuan He if (!np_tim) {
4929aff8079SZhihuan He printf("%s: of_parse_phandle %s error!\n", __func__, phandle_name);
4939aff8079SZhihuan He return -EINVAL;
4949aff8079SZhihuan He }
495*e97e46abSZhihuan He for (i = count;
496*e97e46abSZhihuan He i < (count + ARRAY_SIZE(ddr_params_exp_v1)); i++) {
497*e97e46abSZhihuan He p[i] =
498*e97e46abSZhihuan He ofnode_read_u32_default(np_to_ofnode(np_tim),
499*e97e46abSZhihuan He ddr_params_exp_v1[i - count],
5009aff8079SZhihuan He PARAMS_INVALID_VAL);
5019aff8079SZhihuan He }
5029aff8079SZhihuan He }
503d8e26cc8SYouMin Chen
504d8e26cc8SYouMin Chen flush_cache((unsigned long)(res.a1), (DIV_ROUND_UP(size, 4096) + 1) * 0x1000);
505d8e26cc8SYouMin Chen res = sip_smc_dram(SHARE_PAGE_TYPE_DDRFSP, 0, ROCKCHIP_SIP_CONFIG_DRAM_FSP_INIT);
506d8e26cc8SYouMin Chen if (res.a0) {
507d8e26cc8SYouMin Chen printf("%s: rockchip_sip_config_dram_fsp_init error:%lx\n", __func__, res.a0);
508d8e26cc8SYouMin Chen return -ENOMEM;
509d8e26cc8SYouMin Chen }
510d8e26cc8SYouMin Chen
511d8e26cc8SYouMin Chen return 0;
512d8e26cc8SYouMin Chen }
513d8e26cc8SYouMin Chen
514d8e26cc8SYouMin Chen static const struct udevice_id rockchip_dmc_fsp_ids[] = {
515d8e26cc8SYouMin Chen { .compatible = "rockchip,rk3568-dmc-fsp", .data = 0x102},
5169aff8079SZhihuan He { .compatible = "rockchip,px30s-dmc-fsp", .data = 0x106},
517d8e26cc8SYouMin Chen { }
518d8e26cc8SYouMin Chen };
519d8e26cc8SYouMin Chen
520d8e26cc8SYouMin Chen U_BOOT_DRIVER(dmc_fsp) = {
521d8e26cc8SYouMin Chen .name = "rockchip_dmc_fsp",
522d8e26cc8SYouMin Chen .id = UCLASS_DMC,
523d8e26cc8SYouMin Chen .probe = dmc_fsp_probe,
524d8e26cc8SYouMin Chen .of_match = rockchip_dmc_fsp_ids,
525d8e26cc8SYouMin Chen };
526