Skip to content

Commit af8d1c6

Browse files
gclementJason Cooper
authored andcommitted
ARM: mvebu: Add support to get the ID and the revision of a SoC
All the mvebu SoCs have information related to their variant and revision that can be read from the PCI control register. This patch adds support for Armada XP and Armada 370. This reading of the revision and the ID are done before the PCI initialization to avoid any conflicts. Once these data are retrieved, the resources are freed to let the PCI subsystem use it. Cc: stable@vger.kernel.org # v3.12+ Fixes: 930ab3d (i2c: mv64xxx: Add I2C Transaction Generator support) Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Jason Cooper <jason@lakedaemon.net>
1 parent 6ce4eac commit af8d1c6

File tree

3 files changed

+152
-1
lines changed

3 files changed

+152
-1
lines changed

arch/arm/mach-mvebu/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \
33

44
AFLAGS_coherency_ll.o := -Wa,-march=armv7-a
55

6-
obj-y += system-controller.o
6+
obj-y += system-controller.o mvebu-soc-id.o
77
obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o
88
obj-$(CONFIG_ARCH_MVEBU) += coherency.o coherency_ll.o pmsu.o
99
obj-$(CONFIG_SMP) += platsmp.o headsmp.o

arch/arm/mach-mvebu/mvebu-soc-id.c

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
* ID and revision information for mvebu SoCs
3+
*
4+
* Copyright (C) 2014 Marvell
5+
*
6+
* Gregory CLEMENT <gregory.clement@free-electrons.com>
7+
*
8+
* This file is licensed under the terms of the GNU General Public
9+
* License version 2. This program is licensed "as is" without any
10+
* warranty of any kind, whether express or implied.
11+
*
12+
* All the mvebu SoCs have information related to their variant and
13+
* revision that can be read from the PCI control register. This is
14+
* done before the PCI initialization to avoid any conflict. Once the
15+
* ID and revision are retrieved, the mapping is freed.
16+
*/
17+
18+
#define pr_fmt(fmt) "mvebu-soc-id: " fmt
19+
20+
#include <linux/clk.h>
21+
#include <linux/init.h>
22+
#include <linux/io.h>
23+
#include <linux/kernel.h>
24+
#include <linux/of.h>
25+
#include <linux/of_address.h>
26+
#include "mvebu-soc-id.h"
27+
28+
#define PCIE_DEV_ID_OFF 0x0
29+
#define PCIE_DEV_REV_OFF 0x8
30+
31+
#define SOC_ID_MASK 0xFFFF0000
32+
#define SOC_REV_MASK 0xFF
33+
34+
static u32 soc_dev_id;
35+
static u32 soc_rev;
36+
static bool is_id_valid;
37+
38+
static const struct of_device_id mvebu_pcie_of_match_table[] = {
39+
{ .compatible = "marvell,armada-xp-pcie", },
40+
{ .compatible = "marvell,armada-370-pcie", },
41+
{},
42+
};
43+
44+
int mvebu_get_soc_id(u32 *dev, u32 *rev)
45+
{
46+
if (is_id_valid) {
47+
*dev = soc_dev_id;
48+
*rev = soc_rev;
49+
return 0;
50+
} else
51+
return -1;
52+
}
53+
54+
static int __init mvebu_soc_id_init(void)
55+
{
56+
struct device_node *np;
57+
int ret = 0;
58+
void __iomem *pci_base;
59+
struct clk *clk;
60+
struct device_node *child;
61+
62+
np = of_find_matching_node(NULL, mvebu_pcie_of_match_table);
63+
if (!np)
64+
return ret;
65+
66+
/*
67+
* ID and revision are available from any port, so we
68+
* just pick the first one
69+
*/
70+
child = of_get_next_child(np, NULL);
71+
if (child == NULL) {
72+
pr_err("cannot get pci node\n");
73+
ret = -ENOMEM;
74+
goto clk_err;
75+
}
76+
77+
clk = of_clk_get_by_name(child, NULL);
78+
if (IS_ERR(clk)) {
79+
pr_err("cannot get clock\n");
80+
ret = -ENOMEM;
81+
goto clk_err;
82+
}
83+
84+
ret = clk_prepare_enable(clk);
85+
if (ret) {
86+
pr_err("cannot enable clock\n");
87+
goto clk_err;
88+
}
89+
90+
pci_base = of_iomap(child, 0);
91+
if (IS_ERR(pci_base)) {
92+
pr_err("cannot map registers\n");
93+
ret = -ENOMEM;
94+
goto res_ioremap;
95+
}
96+
97+
/* SoC ID */
98+
soc_dev_id = readl(pci_base + PCIE_DEV_ID_OFF) >> 16;
99+
100+
/* SoC revision */
101+
soc_rev = readl(pci_base + PCIE_DEV_REV_OFF) & SOC_REV_MASK;
102+
103+
is_id_valid = true;
104+
105+
pr_info("MVEBU SoC ID=0x%X, Rev=0x%X\n", soc_dev_id, soc_rev);
106+
107+
iounmap(pci_base);
108+
109+
res_ioremap:
110+
clk_disable_unprepare(clk);
111+
112+
clk_err:
113+
of_node_put(child);
114+
of_node_put(np);
115+
116+
return ret;
117+
}
118+
core_initcall(mvebu_soc_id_init);
119+

arch/arm/mach-mvebu/mvebu-soc-id.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Marvell EBU SoC ID and revision definitions.
3+
*
4+
* Copyright (C) 2014 Marvell Semiconductor
5+
*
6+
* This file is licensed under the terms of the GNU General Public
7+
* License version 2. This program is licensed "as is" without any
8+
* warranty of any kind, whether express or implied.
9+
*/
10+
11+
#ifndef __LINUX_MVEBU_SOC_ID_H
12+
#define __LINUX_MVEBU_SOC_ID_H
13+
14+
/* Armada XP ID */
15+
#define MV78230_DEV_ID 0x7823
16+
#define MV78260_DEV_ID 0x7826
17+
#define MV78460_DEV_ID 0x7846
18+
19+
/* Armada XP Revision */
20+
#define MV78XX0_A0_REV 0x1
21+
#define MV78XX0_B0_REV 0x2
22+
23+
#ifdef CONFIG_ARCH_MVEBU
24+
int mvebu_get_soc_id(u32 *dev, u32 *rev);
25+
#else
26+
static inline int mvebu_get_soc_id(u32 *dev, u32 *rev)
27+
{
28+
return -1;
29+
}
30+
#endif
31+
32+
#endif /* __LINUX_MVEBU_SOC_ID_H */

0 commit comments

Comments
 (0)