aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGregory CLEMENT <gregory.clement@free-electrons.com>2014-06-23 11:42:08 -0400
committerJason Cooper <jason@lakedaemon.net>2014-06-30 13:40:59 -0400
commit9674d4a3cf4307dda468a0b48e5e43a2fdb56b68 (patch)
treed126a74cc3792b0c4f91fbf1355f162e308c004d
parent5e80d81acc420fa33b56078f73f38546ab99be6f (diff)
ARM: mvebu: Use system controller to get the soc id when possible
On Armada 38x it is possible to get the SoC Id and the revision without using the PCI register. Accessing the PCI registers implies enabling its clock and, because of the initialization issue, not keeping them enable. So if possible it is better to avoid it. Armada 370 and Armada XP provides the SoC ID values from the system controller but not the revision. Armada 375 provides both but the SoC ID value looks buggy (0x6660 instead of 0x6720). Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com> Link: https://lkml.kernel.org/r/1403538128-27859-1-git-send-email-gregory.clement@free-electrons.com Signed-off-by: Jason Cooper <jason@lakedaemon.net>
-rw-r--r--arch/arm/mach-mvebu/common.h1
-rw-r--r--arch/arm/mach-mvebu/mvebu-soc-id.c19
-rw-r--r--arch/arm/mach-mvebu/system-controller.c19
3 files changed, 38 insertions, 1 deletions
diff --git a/arch/arm/mach-mvebu/common.h b/arch/arm/mach-mvebu/common.h
index 0d05eaa10de5..a97778e28bf6 100644
--- a/arch/arm/mach-mvebu/common.h
+++ b/arch/arm/mach-mvebu/common.h
@@ -21,5 +21,6 @@ void mvebu_restart(enum reboot_mode mode, const char *cmd);
21int mvebu_cpu_reset_deassert(int cpu); 21int mvebu_cpu_reset_deassert(int cpu);
22void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr); 22void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr);
23void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr); 23void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr);
24int mvebu_system_controller_get_soc_id(u32 *dev, u32 *rev);
24 25
25#endif 26#endif
diff --git a/arch/arm/mach-mvebu/mvebu-soc-id.c b/arch/arm/mach-mvebu/mvebu-soc-id.c
index 12c66cac967d..a99434bcee84 100644
--- a/arch/arm/mach-mvebu/mvebu-soc-id.c
+++ b/arch/arm/mach-mvebu/mvebu-soc-id.c
@@ -25,6 +25,7 @@
25#include <linux/of_address.h> 25#include <linux/of_address.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/sys_soc.h> 27#include <linux/sys_soc.h>
28#include "common.h"
28#include "mvebu-soc-id.h" 29#include "mvebu-soc-id.h"
29 30
30#define PCIE_DEV_ID_OFF 0x0 31#define PCIE_DEV_ID_OFF 0x0
@@ -54,7 +55,7 @@ int mvebu_get_soc_id(u32 *dev, u32 *rev)
54 return -ENODEV; 55 return -ENODEV;
55} 56}
56 57
57static int __init mvebu_soc_id_init(void) 58static int __init get_soc_id_by_pci(void)
58{ 59{
59 struct device_node *np; 60 struct device_node *np;
60 int ret = 0; 61 int ret = 0;
@@ -129,6 +130,22 @@ clk_err:
129 130
130 return ret; 131 return ret;
131} 132}
133
134static int __init mvebu_soc_id_init(void)
135{
136
137 /*
138 * First try to get the ID and the revision by the system
139 * register and use PCI registers only if it is not possible
140 */
141 if (!mvebu_system_controller_get_soc_id(&soc_dev_id, &soc_rev)) {
142 is_id_valid = true;
143 pr_info("MVEBU SoC ID=0x%X, Rev=0x%X\n", soc_dev_id, soc_rev);
144 return 0;
145 }
146
147 return get_soc_id_by_pci();
148}
132early_initcall(mvebu_soc_id_init); 149early_initcall(mvebu_soc_id_init);
133 150
134static int __init mvebu_soc_device(void) 151static int __init mvebu_soc_device(void)
diff --git a/arch/arm/mach-mvebu/system-controller.c b/arch/arm/mach-mvebu/system-controller.c
index 0c5524ac75b7..b2b4e3d6558c 100644
--- a/arch/arm/mach-mvebu/system-controller.c
+++ b/arch/arm/mach-mvebu/system-controller.c
@@ -39,6 +39,9 @@ struct mvebu_system_controller {
39 u32 system_soft_reset; 39 u32 system_soft_reset;
40 40
41 u32 resume_boot_addr; 41 u32 resume_boot_addr;
42
43 u32 dev_id;
44 u32 rev_id;
42}; 45};
43static struct mvebu_system_controller *mvebu_sc; 46static struct mvebu_system_controller *mvebu_sc;
44 47
@@ -47,6 +50,8 @@ static const struct mvebu_system_controller armada_370_xp_system_controller = {
47 .system_soft_reset_offset = 0x64, 50 .system_soft_reset_offset = 0x64,
48 .rstoutn_mask_reset_out_en = 0x1, 51 .rstoutn_mask_reset_out_en = 0x1,
49 .system_soft_reset = 0x1, 52 .system_soft_reset = 0x1,
53 .dev_id = 0x38,
54 .rev_id = 0x3c,
50}; 55};
51 56
52static const struct mvebu_system_controller armada_375_system_controller = { 57static const struct mvebu_system_controller armada_375_system_controller = {
@@ -55,6 +60,8 @@ static const struct mvebu_system_controller armada_375_system_controller = {
55 .rstoutn_mask_reset_out_en = 0x1, 60 .rstoutn_mask_reset_out_en = 0x1,
56 .system_soft_reset = 0x1, 61 .system_soft_reset = 0x1,
57 .resume_boot_addr = 0xd4, 62 .resume_boot_addr = 0xd4,
63 .dev_id = 0x38,
64 .rev_id = 0x3c,
58}; 65};
59 66
60static const struct mvebu_system_controller orion_system_controller = { 67static const struct mvebu_system_controller orion_system_controller = {
@@ -101,6 +108,18 @@ void mvebu_restart(enum reboot_mode mode, const char *cmd)
101 ; 108 ;
102} 109}
103 110
111int mvebu_system_controller_get_soc_id(u32 *dev, u32 *rev)
112{
113 if (of_machine_is_compatible("marvell,armada380") &&
114 system_controller_base) {
115 *dev = readl(system_controller_base + mvebu_sc->dev_id) >> 16;
116 *rev = (readl(system_controller_base + mvebu_sc->rev_id) >> 8)
117 & 0xF;
118 return 0;
119 } else
120 return -ENODEV;
121}
122
104#ifdef CONFIG_SMP 123#ifdef CONFIG_SMP
105void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr) 124void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr)
106{ 125{