]>
Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
8673c1d7 LW |
2 | /* |
3 | * Special GIC quirks for the ARM RealView | |
4 | * Copyright (C) 2015 Linus Walleij | |
5 | */ | |
6 | #include <linux/of.h> | |
7 | #include <linux/regmap.h> | |
8 | #include <linux/mfd/syscon.h> | |
9 | #include <linux/bitops.h> | |
10 | #include <linux/irqchip.h> | |
11 | #include <linux/irqchip/arm-gic.h> | |
12 | ||
13 | #define REALVIEW_SYS_LOCK_OFFSET 0x20 | |
82b0a434 LW |
14 | #define REALVIEW_SYS_PLD_CTRL1 0x74 |
15 | #define REALVIEW_EB_REVB_SYS_PLD_CTRL1 0xD8 | |
8673c1d7 LW |
16 | #define VERSATILE_LOCK_VAL 0xA05F |
17 | #define PLD_INTMODE_MASK BIT(22)|BIT(23)|BIT(24) | |
18 | #define PLD_INTMODE_LEGACY 0x0 | |
19 | #define PLD_INTMODE_NEW_DCC BIT(22) | |
20 | #define PLD_INTMODE_NEW_NO_DCC BIT(23) | |
21 | #define PLD_INTMODE_FIQ_ENABLE BIT(24) | |
22 | ||
82b0a434 LW |
23 | /* For some reason RealView EB Rev B moved this register */ |
24 | static const struct of_device_id syscon_pldset_of_match[] = { | |
25 | { | |
26 | .compatible = "arm,realview-eb11mp-revb-syscon", | |
27 | .data = (void *)REALVIEW_EB_REVB_SYS_PLD_CTRL1, | |
28 | }, | |
29 | { | |
30 | .compatible = "arm,realview-eb11mp-revc-syscon", | |
31 | .data = (void *)REALVIEW_SYS_PLD_CTRL1, | |
32 | }, | |
33 | { | |
34 | .compatible = "arm,realview-eb-syscon", | |
35 | .data = (void *)REALVIEW_SYS_PLD_CTRL1, | |
36 | }, | |
37 | { | |
38 | .compatible = "arm,realview-pb11mp-syscon", | |
39 | .data = (void *)REALVIEW_SYS_PLD_CTRL1, | |
40 | }, | |
41 | {}, | |
42 | }; | |
43 | ||
8673c1d7 LW |
44 | static int __init |
45 | realview_gic_of_init(struct device_node *node, struct device_node *parent) | |
46 | { | |
512f9e79 | 47 | struct regmap *map; |
82b0a434 LW |
48 | struct device_node *np; |
49 | const struct of_device_id *gic_id; | |
50 | u32 pld1_ctrl; | |
51 | ||
52 | np = of_find_matching_node_and_match(NULL, syscon_pldset_of_match, | |
53 | &gic_id); | |
54 | if (!np) | |
55 | return -ENODEV; | |
56 | pld1_ctrl = (u32)gic_id->data; | |
8673c1d7 LW |
57 | |
58 | /* The PB11MPCore GIC needs to be configured in the syscon */ | |
82b0a434 | 59 | map = syscon_node_to_regmap(np); |
8673c1d7 LW |
60 | if (!IS_ERR(map)) { |
61 | /* new irq mode with no DCC */ | |
62 | regmap_write(map, REALVIEW_SYS_LOCK_OFFSET, | |
63 | VERSATILE_LOCK_VAL); | |
82b0a434 | 64 | regmap_update_bits(map, pld1_ctrl, |
8673c1d7 LW |
65 | PLD_INTMODE_NEW_NO_DCC, |
66 | PLD_INTMODE_MASK); | |
67 | regmap_write(map, REALVIEW_SYS_LOCK_OFFSET, 0x0000); | |
82b0a434 | 68 | pr_info("RealView GIC: set up interrupt controller to NEW mode, no DCC\n"); |
8673c1d7 | 69 | } else { |
82b0a434 LW |
70 | pr_err("RealView GIC setup: could not find syscon\n"); |
71 | return -ENODEV; | |
8673c1d7 LW |
72 | } |
73 | return gic_of_init(node, parent); | |
74 | } | |
75 | IRQCHIP_DECLARE(armtc11mp_gic, "arm,tc11mp-gic", realview_gic_of_init); | |
82b0a434 | 76 | IRQCHIP_DECLARE(armeb11mp_gic, "arm,eb11mp-gic", realview_gic_of_init); |