ARM: exynos: pmu: support the reboot download mode
authorJaehoon Chung <jh80.chung@samsung.com>
Mon, 1 Aug 2016 10:38:41 +0000 (19:38 +0900)
committerSeung-Woo Kim <sw0312.kim@samsung.com>
Thu, 4 Aug 2016 04:35:28 +0000 (13:35 +0900)
Support the reboot download mode functionality.
It can get from device-treee which INFORM register will be used.
If want to use this functionality, it also needs to implement something
on bootloader side.

Change-Id: Iae42f32d69b84ccdcb39fcfc8bc71f9cc8c42302
Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
Documentation/devicetree/bindings/arm/samsung/pmu.txt
arch/arm/mach-exynos/pmu.c

index bf5fc59..89edab7 100644 (file)
@@ -44,6 +44,10 @@ following properties:
 - interrupt-parent: a phandle indicating which interrupt controller
   this PMU signals interrupts to.
 
+- reboot-inform: indicates the offset of the INFORM register which supports
+               reboot special mode. (e.g, reboot download)
+               It requires support from the bootloader.
+
 Example :
 pmu_system_controller: system-controller@10040000 {
        compatible = "samsung,exynos5250-pmu", "syscon";
@@ -58,6 +62,7 @@ pmu_system_controller: system-controller@10040000 {
                <&clock CLK_OUT_LEFTBUS>, <&clock CLK_OUT_RIGHTBUS>,
                <&clock CLK_OUT_CPU>, <&clock CLK_XXTI>,
                <&clock CLK_XUSBXTI>;
+       reboot-inform = <0x0808>; /* Offset of INFORM2 register */
 };
 
 Example of clock consumer :
index e812c1c..6119624 100644 (file)
 
 #define PMU_TABLE_END  (-1U)
 
+#define REBOOT_MODE_PREFIX     0x12345670
+#define REBOOT_MODE_NONE       0
+#define REBOOT_MODE_DOWNLOAD   1
+
 struct exynos_pmu_conf {
        unsigned int offset;
        u8 val[NUM_SYS_POWERDOWN];
@@ -40,6 +44,7 @@ struct exynos_pmu_data {
 struct exynos_pmu_context {
        struct device *dev;
        const struct exynos_pmu_data *pmu_data;
+       u32 reboot_inform_reg;
 };
 
 static void __iomem *pmu_base_addr;
@@ -878,6 +883,19 @@ static void exynos5420_pmu_init(void)
 static int pmu_restart_notify(struct notifier_block *this,
                unsigned long code, void *unused)
 {
+       char *cmd = (char *)unused;
+
+       if (pmu_context->reboot_inform_reg) {
+               if (cmd && !strncmp(cmd, "download", 8)) {
+                       pmu_raw_writel(REBOOT_MODE_PREFIX |
+                               REBOOT_MODE_DOWNLOAD,
+                               pmu_context->reboot_inform_reg);
+               } else
+                       pmu_raw_writel(REBOOT_MODE_PREFIX |
+                               REBOOT_MODE_NONE,
+                               pmu_context->reboot_inform_reg);
+       }
+
        pmu_raw_writel(0x1, EXYNOS_SWRESET);
 
        return NOTIFY_DONE;
@@ -952,7 +970,9 @@ static int exynos_pmu_probe(struct platform_device *pdev)
 {
        const struct of_device_id *match;
        struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
        struct resource *res;
+       u32 inform_reg;
        int ret;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -973,6 +993,10 @@ static int exynos_pmu_probe(struct platform_device *pdev)
 
        pmu_context->pmu_data = match->data;
 
+       ret = of_property_read_u32(np, "reboot-inform", &inform_reg);
+       if (!ret)
+               pmu_context->reboot_inform_reg = inform_reg;
+
        if (pmu_context->pmu_data->pmu_init)
                pmu_context->pmu_data->pmu_init();