power: reset: rockchip-reboot: add rk3368 reboot driver
authorHuang, Tao <huangtao@rock-chips.com>
Fri, 6 Feb 2015 13:37:06 +0000 (21:37 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Fri, 6 Feb 2015 13:37:06 +0000 (21:37 +0800)
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
arch/arm64/boot/dts/rk3368.dtsi
arch/arm64/configs/rockchip_defconfig
drivers/power/reset/Kconfig
drivers/power/reset/Makefile
drivers/power/reset/rockchip-reboot.c [new file with mode: 0644]

index 1fbfe56fd8c83fdb18ed138aeaf7ac7231d985c4..2a6dc1291fc98352673fba1afd56541eb22b101c 100755 (executable)
 
        };
 
+       cru: syscon@ff760000 {
+               compatible = "rockchip,rk3368-cru", "rockchip,cru", "syscon";
+               reg = <0x0 0xff760000 0x0 0x1000>;
+       };
+
        grf: syscon@ff770000 {
                compatible = "rockchip,rk3368-grf", "rockchip,grf", "syscon";
                reg = <0x0 0xff770000 0x0 0x1000>;
                         };
                };
        };
+
+       reboot {
+               compatible = "rockchip,rk3368-reboot";
+               rockchip,cru = <&cru>;
+               rockchip,pmugrf = <&pmugrf>;
+       };
 };
index c736e2db2bcb8b4204c48f2ad804f43861775f90..c66957b95b955826f691fe691efa44d9fe5417be 100644 (file)
@@ -348,6 +348,7 @@ CONFIG_BATTERY_BQ27320=y
 CONFIG_BATTERY_RK30_ADC_FAC=y
 CONFIG_CW2015_BATTERY=y
 CONFIG_POWER_RESET_GPIO=y
+CONFIG_POWER_RESET_ROCKCHIP=y
 CONFIG_POWER_AVS=y
 CONFIG_ROCKCHIP_IODOMAIN=y
 CONFIG_SENSORS_ROCKCHIP_TSADC=y
index ee039dcead04782a5389ff7827f271e2d3aa2192..305a65440732f7c48a1ca79a55936f9dff404b71 100644 (file)
@@ -31,6 +31,12 @@ config POWER_RESET_RESTART
          Instead they restart, and u-boot holds the SoC until the
          user presses a key. u-boot then boots into Linux.
 
+config POWER_RESET_ROCKCHIP
+       bool "Rockchip reset driver"
+       depends on POWER_RESET && MFD_SYSCON && ARCH_ROCKCHIP
+       help
+         Restart support for Rockchip SoCs.
+
 config POWER_RESET_VEXPRESS
        bool "ARM Versatile Express power-off and reset driver"
        depends on ARM || ARM64
index 372807fd83f78d32d352e1479721407293c24fce..47229c85cdf02dc2def96c2ffb625e9b3d94fd41 100644 (file)
@@ -1,4 +1,5 @@
 obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o
 obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o
 obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o
+obj-$(CONFIG_POWER_RESET_ROCKCHIP) += rockchip-reboot.o
 obj-$(CONFIG_POWER_RESET_VEXPRESS) += vexpress-poweroff.o
diff --git a/drivers/power/reset/rockchip-reboot.c b/drivers/power/reset/rockchip-reboot.c
new file mode 100644 (file)
index 0000000..93f1c3f
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Rockchip SoCs Reboot Driver
+ *
+ * Copyright (C) 2015 Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <linux/regmap.h>
+#include <linux/of.h>
+#include <linux/mfd/syscon.h>
+#include <asm/system_misc.h>
+
+static struct regmap *cru;
+
+#define RK3368_CRU_APLLB_CON3  0x0c
+#define RK3368_CRU_APLLL_CON3  0x01c
+#define RK3368_CRU_CPLL_CON3   0x03c
+#define RK3368_CRU_GPLL_CON3   0x04c
+#define RK3368_CRU_NPLL_CON3   0x05c
+#define RK3368_CRU_GLB_SRST_FST_VALUE  0x280
+#define RK3368_CRU_GLB_SRST_SND_VALUE  0x284
+#define RK3368_CRU_GLB_RST_CON 0x388
+
+static void rk3368_reboot(char str, const char *cmd)
+{
+       /* pll enter slow mode */
+       regmap_write(cru, RK3368_CRU_APLLB_CON3, 0x03000000);
+       regmap_write(cru, RK3368_CRU_APLLL_CON3, 0x03000000);
+       regmap_write(cru, RK3368_CRU_CPLL_CON3, 0x03000000);
+       regmap_write(cru, RK3368_CRU_GPLL_CON3, 0x03000000);
+       regmap_write(cru, RK3368_CRU_NPLL_CON3, 0x03000000);
+       regmap_update_bits(cru, RK3368_CRU_GLB_RST_CON, 3 << 2, 1 << 2);
+       regmap_write(cru, RK3368_CRU_GLB_SRST_SND_VALUE, 0xeca8);
+}
+
+static __init int rk3368_reboot_init(struct platform_device *pdev)
+{
+       struct device_node *np = pdev->dev.of_node;
+
+       cru = syscon_regmap_lookup_by_phandle(np, "rockchip,cru");
+       if (IS_ERR(cru)) {
+               dev_err(&pdev->dev, "No rockchip,cru phandle specified");
+               return PTR_ERR(cru);
+       }
+
+       arm_pm_restart = rk3368_reboot;
+
+       return 0;
+}
+
+static struct of_device_id rockchip_reboot_of_match[] __refdata = {
+       { .compatible = "rockchip,rk3368-reboot", .data = rk3368_reboot_init },
+       {}
+};
+
+static int __init rockchip_reboot_probe(struct platform_device *pdev)
+{
+       const struct of_device_id *match;
+       int (*init)(struct platform_device *);
+
+       match = of_match_node(rockchip_reboot_of_match, pdev->dev.of_node);
+       if (match) {
+               init = match->data;
+               if (init)
+                       return init(pdev);
+       }
+
+       return 0;
+}
+
+static struct platform_driver rockchip_reboot_driver = {
+       .driver = {
+               .name = "rockchip-reboot",
+               .of_match_table = rockchip_reboot_of_match,
+       },
+};
+
+static int __init rockchip_reboot_init(void)
+{
+       return platform_driver_probe(&rockchip_reboot_driver,
+                       rockchip_reboot_probe);
+}
+subsys_initcall(rockchip_reboot_init);