RK3368 MCU: add MCU suspend and resume function
authorTang Yun ping <typ@rock-chips.com>
Mon, 11 May 2015 06:54:22 +0000 (14:54 +0800)
committerTang Yun ping <typ@rock-chips.com>
Mon, 11 May 2015 06:54:22 +0000 (14:54 +0800)
Signed-off-by: Tang Yun ping <typ@rock-chips.com>
drivers/devfreq/ddr_rk3368.c
drivers/mailbox/rockchip_mailbox.c
drivers/mailbox/scpi_cmd.h
drivers/mailbox/scpi_protocol.c
include/linux/scpi_protocol.h

index d7ed33cd8d3a4bbb07bf3c73fbabfc0baf1c7d19..56d3b679475f0c3359bb18aa0530a5b5d3a15338 100644 (file)
@@ -257,6 +257,12 @@ static void ddr_init(u32 dram_speed_bin, u32 freq)
                printk(KERN_DEBUG pr_fmt("%s out\n"), __func__);
 }
 
                printk(KERN_DEBUG pr_fmt("%s out\n"), __func__);
 }
 
+static int ddr_init_resume(struct platform_device *pdev)
+{
+       ddr_init(DDR3_DEFAULT, 0);
+       return 0;
+}
+
 static int __init rockchip_ddr_probe(struct platform_device *pdev)
 {
        struct device_node *np;
 static int __init rockchip_ddr_probe(struct platform_device *pdev)
 {
        struct device_node *np;
@@ -311,6 +317,9 @@ static const struct of_device_id rockchip_ddr_of_match[] __refdata = {
 };
 
 static struct platform_driver rockchip_ddr_driver = {
 };
 
 static struct platform_driver rockchip_ddr_driver = {
+#ifdef CONFIG_PM
+       .resume = ddr_init_resume,
+#endif /* CONFIG_PM */
        .driver = {
                   .name = "rockchip_ddr",
                   .of_match_table = rockchip_ddr_of_match,
        .driver = {
                   .name = "rockchip_ddr",
                   .of_match_table = rockchip_ddr_of_match,
index ca8cb4d1aeb363a2301be7ab9fefbf7527f23905..ca88773a48ed7dd73237dcec2b33fa08c139eeef 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/clk.h>
 
 #include <linux/rockchip-mailbox.h>
 #include <linux/clk.h>
 
 #include <linux/rockchip-mailbox.h>
+#include <linux/scpi_protocol.h>
 
 #define MAILBOX_A2B_INTEN              0x00
 #define MAILBOX_A2B_STATUS             0x04
 
 #define MAILBOX_A2B_INTEN              0x00
 #define MAILBOX_A2B_STATUS             0x04
@@ -160,6 +161,30 @@ static struct of_device_id rockchip_mbox_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, rockchp_mbox_of_match);
 
 };
 MODULE_DEVICE_TABLE(of, rockchp_mbox_of_match);
 
+#ifdef CONFIG_PM
+static int rockchip_mbox_suspend(struct platform_device *pdev,
+                                pm_message_t state)
+{
+       struct rockchip_mbox *mb = platform_get_drvdata(pdev);
+
+       if (scpi_sys_set_mcu_state_suspend())
+               dev_err(mb->mbox.dev, "scpi_sys_set_mcu_state_suspend timeout.\n");
+       return 0;
+}
+
+static int rockchip_mbox_resume(struct platform_device *pdev)
+{
+       struct rockchip_mbox *mb = platform_get_drvdata(pdev);
+
+       writel_relaxed((1 << mb->mbox.num_chans) - 1,
+                      mb->mbox_base + MAILBOX_B2A_INTEN);
+
+       if (scpi_sys_set_mcu_state_resume())
+               dev_err(mb->mbox.dev, "scpi_sys_set_mcu_state_resume timeout.\n");
+       return 0;
+}
+#endif /* CONFIG_PM */
+
 static int rockchip_mbox_probe(struct platform_device *pdev)
 {
        struct rockchip_mbox *mb;
 static int rockchip_mbox_probe(struct platform_device *pdev)
 {
        struct rockchip_mbox *mb;
@@ -266,6 +291,10 @@ static int rockchip_mbox_remove(struct platform_device *pdev)
 static struct platform_driver rockchip_mbox_driver = {
        .probe  = rockchip_mbox_probe,
        .remove = rockchip_mbox_remove,
 static struct platform_driver rockchip_mbox_driver = {
        .probe  = rockchip_mbox_probe,
        .remove = rockchip_mbox_remove,
+#ifdef CONFIG_PM
+       .suspend = rockchip_mbox_suspend,
+       .resume = rockchip_mbox_resume,
+#endif /* CONFIG_PM */
        .driver = {
                .name = "rockchip-mailbox",
                .of_match_table = of_match_ptr(rockchip_mbox_of_match),
        .driver = {
                .name = "rockchip-mailbox",
                .of_match_table = of_match_ptr(rockchip_mbox_of_match),
index 5f5ca45474dfdd68672b5f76526c15094536285b..0f6b9345616ad788f8aca7a6c93d65e4e7aef5df 100644 (file)
@@ -57,6 +57,8 @@ enum scpi_ddr_cmd {
 enum scpi_sys_cmd {
        SCPI_SYS_GET_VERSION,
        SCPI_SYS_REFRESH_MCU_FREQ,
 enum scpi_sys_cmd {
        SCPI_SYS_GET_VERSION,
        SCPI_SYS_REFRESH_MCU_FREQ,
+       SCPI_SYS_SET_MCU_STATE_SUSPEND,
+       SCPI_SYS_SET_MCU_STATE_RESUME,
 };
 
 enum scpi_std_cmd {
 };
 
 enum scpi_std_cmd {
index 9ddb1221545a049341b106f4a37b22352992c7bc..8313912ea8b9f91016b6998c518667d02a97fbf2 100644 (file)
@@ -400,6 +400,43 @@ static int scpi_get_version(u32 old, u32 *ver)
        return ret;
 }
 
        return ret;
 }
 
+int scpi_sys_set_mcu_state_suspend(void)
+{
+       struct scpi_data_buf sdata;
+       struct rockchip_mbox_msg mdata;
+       struct __packed1 {
+               u32 status;
+       } tx_buf;
+       struct __packed2 {
+               u32 status;
+       } rx_buf;
+
+       tx_buf.status = 0;
+       SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_SYS,
+                       SCPI_SYS_SET_MCU_STATE_SUSPEND, tx_buf, rx_buf);
+       return scpi_execute_cmd(&sdata);
+}
+EXPORT_SYMBOL_GPL(scpi_sys_set_mcu_state_suspend);
+
+int scpi_sys_set_mcu_state_resume(void)
+{
+       struct scpi_data_buf sdata;
+       struct rockchip_mbox_msg mdata;
+       struct __packed1 {
+               u32 status;
+       } tx_buf;
+       struct __packed2 {
+               u32 status;
+       } rx_buf;
+
+       tx_buf.status = 0;
+
+       SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_SYS,
+                       SCPI_SYS_SET_MCU_STATE_RESUME, tx_buf, rx_buf);
+       return scpi_execute_cmd(&sdata);
+}
+EXPORT_SYMBOL_GPL(scpi_sys_set_mcu_state_resume);
+
 int scpi_ddr_init(u32 dram_speed_bin, u32 freq, u32 lcdc_type)
 {
        struct scpi_data_buf sdata;
 int scpi_ddr_init(u32 dram_speed_bin, u32 freq, u32 lcdc_type)
 {
        struct scpi_data_buf sdata;
index 4df7c00a073b742947ab55173f79f559b78bc421..fb32c0b543bf0eba7a1dfcc9cbe8729f0e33daea 100644 (file)
@@ -37,6 +37,9 @@ struct scpi_opp *scpi_dvfs_get_opps(u8 domain);
 int scpi_get_sensor(char *name);
 int scpi_get_sensor_value(u16 sensor, u32 *val);
 
 int scpi_get_sensor(char *name);
 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_set_clk_rate(u32 rate);
 int scpi_ddr_round_rate(u32 m_hz);
 int scpi_ddr_init(u32 dram_speed_bin, u32 freq, u32 lcdc_type);
 int scpi_ddr_set_clk_rate(u32 rate);
 int scpi_ddr_round_rate(u32 m_hz);