RK3368 DDR: new ddr change freq method
authorTang Yun ping <typ@rock-chips.com>
Fri, 21 Aug 2015 09:14:10 +0000 (17:14 +0800)
committerTang Yun ping <typ@rock-chips.com>
Tue, 25 Aug 2015 03:05:11 +0000 (11:05 +0800)
Using fiq to notify trust to stop cpu when ddr changing freq.
1.bl30 must update to rk3368bl30_v2.10.bin  and bl31 must update to
rk3368bl31_v1.5.bin.
2.Insure kernel commit 7643ffa0e67d5 and cc6e554e54fe1 were merged.

Change-Id: I2449613221c49a49ba14dab54e77714e961dcd16
Signed-off-by: Tang Yun ping <typ@rock-chips.com>
drivers/devfreq/ddr_rk3368.c
drivers/mailbox/scpi_protocol.c
include/linux/scpi_protocol.h

index 87e2bcb..dec8642 100644 (file)
 #include <linux/rockchip/pmu.h>
 #include <linux/rk_fb.h>
 #include <linux/scpi_protocol.h>
+#include <asm/compiler.h>
 
 #define GRF_DDRC0_CON0    0x600
 #define GRF_SOC_STATUS5  0x494
 #define DDR_PCTL_TOGCNT_1U  0xc0
 
+#define PSCI_SIP_RKTF_VER              (0x82000001)
+#define FIQ_CPU_TGT_BOOT               0x0 /* to booting cpu */
+#define RKSIP_EL3FIQ_CFG               (0x82000006)
+#define FIQ_NUM_FOR_DCF                (143)  /*NA irq map to fiq for dcf*/
+
+
+#define DDR_VERSION                    "V1.01 20150819"
+
 enum ddr_bandwidth_id {
        ddrbw_wr_num = 0,
        ddrbw_rd_num,
@@ -64,6 +73,24 @@ struct rockchip_ddr {
 
 static struct rockchip_ddr *ddr_data = NULL;
 
+static noinline int __invoke_reg_dcf_fn_smc(u64 function_id, u64 arg0, u64 arg1,
+                                           u64 arg2)
+{
+       asm volatile(
+                       __asmeq("%0", "x0")
+                       __asmeq("%1", "x1")
+                       __asmeq("%2", "x2")
+                       __asmeq("%3", "x3")
+                       "smc    #0\n"
+               : "+r" (function_id)
+               : "r" (arg0), "r" (arg1), "r" (arg2));
+
+       return function_id;
+}
+
+static int (*invoke_reg_dcf_fn_smc)(u64, u64 , u64, u64) =
+           __invoke_reg_dcf_fn_smc;
+
 static int _ddr_recalc_rate(void)
 {
        int ddr_freq;
@@ -254,12 +281,16 @@ end:
        ddr_monitor_start();
 }
 
-static void ddr_init(u32 dram_speed_bin, u32 freq)
+static void ddr_init(u32 dram_speed_bin, u32 freq, u32 addr_mcu_el3)
 {
        int lcdc_type;
+       static u32 addr = 0;
 
        struct rk_lcdc_driver *lcdc_dev = NULL;
 
+       if (addr == 0)
+               addr = addr_mcu_el3;
+
        lcdc_dev = rk_get_lcdc_drv("lcdc0");
        if (lcdc_dev == NULL)
                lcdc_type = 0;
@@ -267,7 +298,7 @@ static void ddr_init(u32 dram_speed_bin, u32 freq)
                lcdc_type = (u32)lcdc_dev->cur_screen->type;
        printk(KERN_DEBUG pr_fmt("In Func:%s,dram_speed_bin:%d,freq:%d,lcdc_type:%d\n"),
               __func__, dram_speed_bin, freq, lcdc_type);
-       if (scpi_ddr_init(dram_speed_bin, freq, lcdc_type))
+       if (scpi_ddr_init(dram_speed_bin, freq, lcdc_type, addr))
                pr_info("ddr init error\n");
        else
                printk(KERN_DEBUG pr_fmt("%s out\n"), __func__);
@@ -275,14 +306,43 @@ static void ddr_init(u32 dram_speed_bin, u32 freq)
 
 static int ddr_init_resume(struct platform_device *pdev)
 {
-       ddr_init(DDR3_DEFAULT, 0);
+       ddr_init(DDR3_DEFAULT, 0, 0);
+       return 0;
+}
+#define RKTF_VER_MAJOR(ver) (((ver) >> 16) & 0xffff)
+#define RKTF_VER_MINOR(ver) ((ver) & 0xffff)
+/* valid ver */
+#define RKTF_VLDVER_MAJOR (1)
+#define RKTF_VLDVER_MINOR (5)
+
+static int __init rockchip_tf_ver_check(void)
+{
+       u32 version;
+
+       version = invoke_reg_dcf_fn_smc(PSCI_SIP_RKTF_VER, 0, 0, 0);
+
+       if ((RKTF_VER_MAJOR(version) >= RKTF_VLDVER_MAJOR) &&
+           (RKTF_VER_MINOR(version) >= RKTF_VLDVER_MINOR))
+               return 0;
+
+       pr_err("read tf version 0x%x!\n", version);
+
+       do {
+               mdelay(1000);
+               pr_err("trusted firmware need to update to(%d.%d) or is invaild!\n",
+                      RKTF_VLDVER_MAJOR, RKTF_VLDVER_MINOR);
+       } while (1);
+
        return 0;
 }
 
+
 static int __init rockchip_ddr_probe(struct platform_device *pdev)
 {
+       u32 addr_mcu_el3;
        struct device_node *np;
 
+       pr_info("Rockchip DDR Initialize, verision: "DDR_VERSION"\n");
        np = pdev->dev.of_node;
        ddr_data =
            devm_kzalloc(&pdev->dev, sizeof(struct rockchip_ddr), GFP_KERNEL);
@@ -322,7 +382,12 @@ static int __init rockchip_ddr_probe(struct platform_device *pdev)
        ddr_set_auto_self_refresh = _ddr_set_auto_self_refresh;
        ddr_bandwidth_get = _ddr_bandwidth_get;
        ddr_recalc_rate = _ddr_recalc_rate;
-       ddr_init(DDR3_DEFAULT, 0);
+       rockchip_tf_ver_check();
+       addr_mcu_el3 = invoke_reg_dcf_fn_smc(RKSIP_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);
        pr_info("%s: success\n", __func__);
        return 0;
 }
index 673437a..efcc927 100644 (file)
@@ -492,7 +492,7 @@ int scpi_sys_set_mcu_state_resume(void)
 }
 EXPORT_SYMBOL_GPL(scpi_sys_set_mcu_state_resume);
 
-int scpi_ddr_init(u32 dram_speed_bin, u32 freq, u32 lcdc_type)
+int scpi_ddr_init(u32 dram_speed_bin, u32 freq, u32 lcdc_type, u32 addr_mcu_el3)
 {
        struct scpi_data_buf sdata;
        struct rockchip_mbox_msg mdata;
@@ -500,6 +500,7 @@ int scpi_ddr_init(u32 dram_speed_bin, u32 freq, u32 lcdc_type)
                u32 dram_speed_bin;
                u32 freq;
                u32 lcdc_type;
+               u32 addr_mcu_el3;
        } tx_buf;
        struct __packed2 {
                u32 status;
@@ -508,7 +509,7 @@ int scpi_ddr_init(u32 dram_speed_bin, u32 freq, u32 lcdc_type)
        tx_buf.dram_speed_bin = (u32)dram_speed_bin;
        tx_buf.freq = (u32)freq;
        tx_buf.lcdc_type = (u32)lcdc_type;
-
+       tx_buf.addr_mcu_el3 = addr_mcu_el3;
        SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_DDR,
                        SCPI_DDR_INIT, tx_buf, rx_buf);
        return scpi_execute_cmd(&sdata);
index 5219ff1..c472ddf 100644 (file)
@@ -40,7 +40,8 @@ int scpi_get_sensor_value(u16 sensor, u32 *val);
 int scpi_sys_set_mcu_state_suspend(void);
 int scpi_sys_set_mcu_state_resume(void);
 
-int scpi_ddr_init(u32 dram_speed_bin, u32 freq, u32 lcdc_type);
+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_round_rate(u32 m_hz);
 int scpi_ddr_set_auto_self_refresh(u32 en);