1 | // SPDX-License-Identifier: GPL-2.0-or-later |
---|---|
2 | /* |
3 | * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved. |
4 | * Copyright 2008 Juergen Beisert, kernel@pengutronix.de |
5 | */ |
6 | |
7 | /* |
8 | * i.MX27 specific CPU detection code |
9 | */ |
10 | |
11 | #include <linux/io.h> |
12 | #include <linux/of_address.h> |
13 | #include <linux/module.h> |
14 | |
15 | #include "hardware.h" |
16 | |
17 | static int mx27_cpu_rev = -1; |
18 | static int mx27_cpu_partnumber; |
19 | |
20 | #define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */ |
21 | #define SYSCTRL_OFFSET 0x800 /* Offset from CCM base address */ |
22 | |
23 | static int mx27_read_cpu_rev(void) |
24 | { |
25 | void __iomem *ccm_base; |
26 | struct device_node *np; |
27 | u32 val; |
28 | |
29 | np = of_find_compatible_node(NULL, NULL, compat: "fsl,imx27-ccm"); |
30 | ccm_base = of_iomap(node: np, index: 0); |
31 | of_node_put(node: np); |
32 | BUG_ON(!ccm_base); |
33 | /* |
34 | * now we have access to the IO registers. As we need |
35 | * the silicon revision very early we read it here to |
36 | * avoid any further hooks |
37 | */ |
38 | val = imx_readl(ccm_base + SYSCTRL_OFFSET + SYS_CHIP_ID); |
39 | |
40 | mx27_cpu_partnumber = (int)((val >> 12) & 0xFFFF); |
41 | |
42 | switch (val >> 28) { |
43 | case 0: |
44 | return IMX_CHIP_REVISION_1_0; |
45 | case 1: |
46 | return IMX_CHIP_REVISION_2_0; |
47 | case 2: |
48 | return IMX_CHIP_REVISION_2_1; |
49 | default: |
50 | return IMX_CHIP_REVISION_UNKNOWN; |
51 | } |
52 | } |
53 | |
54 | /* |
55 | * Returns: |
56 | * the silicon revision of the cpu |
57 | * -EINVAL - not a mx27 |
58 | */ |
59 | int mx27_revision(void) |
60 | { |
61 | if (mx27_cpu_rev == -1) |
62 | mx27_cpu_rev = mx27_read_cpu_rev(); |
63 | |
64 | if (mx27_cpu_partnumber != 0x8821) |
65 | return -EINVAL; |
66 | |
67 | return mx27_cpu_rev; |
68 | } |
69 | EXPORT_SYMBOL(mx27_revision); |
70 |