From: Tang Yun ping Date: Fri, 11 Sep 2015 03:46:36 +0000 (+0800) Subject: rk3368 ddr: add configure ddr timing function X-Git-Tag: firefly_0821_release~3775 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=52f8f5cff002064cccc4e86175b5eabe2a6727a1;p=firefly-linux-kernel-4.4.55.git rk3368 ddr: add configure ddr timing function 1.add the function of configure ddr timing such us sr_idle, pd_idle, odt disable frequency, dll bypass frequency, odt strength, driver strength in dts. 2.make sure commit 8be554a50237051e45e ("rk3368 dts: add ddr timing node in rk3368.dtsi" add ddr timing node in dts that user can configure ddr timing in dts file.) was merged. 3.bl30 must update to rk3368bl30_v2.11.bin. Change-Id: Ie8ae559c8128eb01788271a4333c465e21954ab1 Signed-off-by: Tang Yun ping --- diff --git a/drivers/devfreq/ddr_rk3368.c b/drivers/devfreq/ddr_rk3368.c index b465e48c7c47..6caec6ee8684 100644 --- a/drivers/devfreq/ddr_rk3368.c +++ b/drivers/devfreq/ddr_rk3368.c @@ -17,7 +17,6 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include #include #include #include @@ -28,6 +27,7 @@ #include #include #include +#include #define GRF_DDRC0_CON0 0x600 #define GRF_SOC_STATUS5 0x494 @@ -37,7 +37,7 @@ #define FIQ_NUM_FOR_DCF (143) /*NA irq map to fiq for dcf*/ -#define DDR_VERSION "V1.02 20150907" +#define DDR_VERSION "V1.03 20150910" enum ddr_bandwidth_id { ddrbw_wr_num = 0, @@ -48,14 +48,70 @@ enum ddr_bandwidth_id { ddrbw_id_end }; +struct ddr_timing { + u32 dram_spd_bin; + u32 sr_idle; + u32 pd_idle; + u32 dram_dll_dis_freq; + u32 phy_dll_dis_freq; + u32 dram_odt_dis_freq; + u32 phy_odt_dis_freq; + u32 ddr3_drv; + u32 ddr3_odt; + u32 lpddr3_drv; + u32 lpddr3_odt; + u32 lpddr2_drv; + u32 phy_clk_drv; + u32 phy_cmd_drv; + u32 phy_dqs_drv; + u32 phy_odt; +}; + struct rockchip_ddr { struct regmap *ddrpctl_regs; struct regmap *msch_regs; struct regmap *grf_regs; + struct ddr_timing dram_timing; }; static struct rockchip_ddr *ddr_data = NULL; +static int of_do_get_timings(struct device_node *np, struct ddr_timing *tim) +{ + struct device_node *np_tim; + int ret; + + ret = 0; + + np_tim = of_parse_phandle(np, "rockchip,ddr_timing", 0); + if (!np_tim) + return 1; + + ret |= of_property_read_u32(np_tim, "dram_spd_bin", + &tim->dram_spd_bin); + ret |= of_property_read_u32(np_tim, "sr_idle", &tim->sr_idle); + ret |= of_property_read_u32(np_tim, "pd_idle", &tim->pd_idle); + ret |= of_property_read_u32(np_tim, "dram_dll_disb_freq", + &tim->dram_dll_dis_freq); + ret |= of_property_read_u32(np_tim, "phy_dll_disb_freq", + &tim->phy_dll_dis_freq); + ret |= of_property_read_u32(np_tim, "dram_odt_disb_freq", + &tim->dram_odt_dis_freq); + ret |= of_property_read_u32(np_tim, "phy_odt_disb_freq", + &tim->phy_odt_dis_freq); + ret |= of_property_read_u32(np_tim, "ddr3_drv", &tim->ddr3_drv); + ret |= of_property_read_u32(np_tim, "ddr3_odt", &tim->ddr3_odt); + ret |= of_property_read_u32(np_tim, "lpddr3_drv", &tim->lpddr3_drv); + ret |= of_property_read_u32(np_tim, "lpddr3_odt", &tim->lpddr3_odt); + ret |= of_property_read_u32(np_tim, "lpddr2_drv", &tim->lpddr2_drv); + ret |= of_property_read_u32(np_tim, "phy_clk_drv", &tim->phy_clk_drv); + ret |= of_property_read_u32(np_tim, "phy_cmd_drv", &tim->phy_cmd_drv); + ret |= of_property_read_u32(np_tim, "phy_dqs_drv", &tim->phy_dqs_drv); + ret |= of_property_read_u32(np_tim, "phy_odt", &tim->phy_odt); + + return ret; +} + static int _ddr_recalc_rate(void) { int ddr_freq; @@ -348,12 +404,20 @@ static int __init rockchip_ddr_probe(struct platform_device *pdev) ddr_bandwidth_get = _ddr_bandwidth_get; ddr_recalc_rate = _ddr_recalc_rate; rockchip_tf_ver_check(); + if (!of_do_get_timings(np, (struct ddr_timing *)&ddr_data->dram_timing)) { + if (scpi_ddr_send_timing((u32 *)&ddr_data->dram_timing, + sizeof(struct ddr_timing))) + pr_info("send ddr timing timeout\n"); + } else { + pr_err("get ddr timing from dts error\n"); + ddr_data->dram_timing.dram_spd_bin = DDR3_DEFAULT; + } addr_mcu_el3 = rockchip_psci_smc_write(PSCI_SIP_EL3FIQ_CFG, FIQ_NUM_FOR_DCF, FIQ_CPU_TGT_BOOT, 0); if ((addr_mcu_el3 == 0) || (addr_mcu_el3 > 0x80000)) pr_info("Trust version error, pls check trust version\n"); - ddr_init(DDR3_DEFAULT, 0, addr_mcu_el3); + ddr_init(ddr_data->dram_timing.dram_spd_bin, 0, addr_mcu_el3); pr_info("%s: success\n", __func__); return 0; } @@ -375,7 +439,6 @@ static struct platform_driver rockchip_ddr_driver = { static int __init rockchip_ddr_init(void) { - pr_info("rockchip_ddr_init\n"); return platform_driver_probe(&rockchip_ddr_driver, rockchip_ddr_probe); } diff --git a/drivers/mailbox/scpi_cmd.h b/drivers/mailbox/scpi_cmd.h index f516e42b4669..9b89d371e512 100644 --- a/drivers/mailbox/scpi_cmd.h +++ b/drivers/mailbox/scpi_cmd.h @@ -52,6 +52,7 @@ enum scpi_ddr_cmd { SCPI_DDR_AUTO_SELF_REFRESH, SCPI_DDR_BANDWIDTH_GET, SCPI_DDR_GET_FREQ, + SCPI_DDR_SEND_TIMING, }; enum scpi_sys_cmd { diff --git a/drivers/mailbox/scpi_protocol.c b/drivers/mailbox/scpi_protocol.c index efcc92721c20..c58a608596f7 100644 --- a/drivers/mailbox/scpi_protocol.c +++ b/drivers/mailbox/scpi_protocol.c @@ -207,6 +207,20 @@ do { \ scpi_buf.timeout_ms = SCPI_CMD_DEFAULT_TIMEOUT_MS; \ } while (0) +#define SCPI_SETUP_DBUF_BY_SIZE(scpi_buf, mbox_buf, _client_id, \ + _cmd, _tx_buf, _tx_size, _rx_buf) \ +do { \ + struct rockchip_mbox_msg *pdata = &mbox_buf; \ + pdata->cmd = _cmd; \ + pdata->tx_buf = _tx_buf; \ + pdata->tx_size = _tx_size; \ + pdata->rx_buf = &_rx_buf; \ + pdata->rx_size = sizeof(_rx_buf); \ + scpi_buf.client_id = _client_id; \ + scpi_buf.data = pdata; \ + scpi_buf.timeout_ms = SCPI_CMD_DEFAULT_TIMEOUT_MS; \ +} while (0) + static int scpi_execute_cmd(struct scpi_data_buf *scpi_buf) { struct rockchip_mbox_msg *data; @@ -536,6 +550,19 @@ int scpi_ddr_set_clk_rate(u32 rate, u32 lcdc_type) } EXPORT_SYMBOL_GPL(scpi_ddr_set_clk_rate); +int scpi_ddr_send_timing(u32 *p, u32 size) +{ + struct scpi_data_buf sdata; + struct rockchip_mbox_msg mdata; + struct __packed2 { + u32 status; + } rx_buf; + SCPI_SETUP_DBUF_BY_SIZE(sdata, mdata, SCPI_CL_DDR, + SCPI_DDR_SEND_TIMING, p, size, rx_buf); + return scpi_execute_cmd(&sdata); +} +EXPORT_SYMBOL_GPL(scpi_ddr_send_timing); + int scpi_ddr_round_rate(u32 m_hz) { struct scpi_data_buf sdata; diff --git a/include/linux/scpi_protocol.h b/include/linux/scpi_protocol.h index c472ddfa58b5..c57df9759ea5 100644 --- a/include/linux/scpi_protocol.h +++ b/include/linux/scpi_protocol.h @@ -43,6 +43,7 @@ int scpi_sys_set_mcu_state_resume(void); int scpi_ddr_init(u32 dram_speed_bin, u32 freq, u32 lcdc_type, u32 addr_mcu_el3); int scpi_ddr_set_clk_rate(u32 rate, u32 lcdc_type); +int scpi_ddr_send_timing(u32 *p, u32 size); int scpi_ddr_round_rate(u32 m_hz); int scpi_ddr_set_auto_self_refresh(u32 en); int scpi_ddr_bandwidth_get(struct ddr_bw_info *ddr_bw_ch0,