Skip to content

Commit ec58ba1

Browse files
gustavoSNPSvineetgarc
authored andcommitted
ARC: [plat-hsdk]: Configure APB GPIO controller on ARC HSDK platform
In case of HSDK we have intermediate INTC in for of DW APB GPIO controller which is used as a de-bounce logic for interrupt wires that come from outside the board. We cannot use existing "irq-dw-apb-ictl" driver here because all input lines are routed to corresponding output lines but not muxed into one line (this is configured in RTL and we cannot change this in software). But even if we add such a feature to "irq-dw-apb-ictl" driver that won't benefit us as higher-level INTC (in case of HSDK it is IDU) anyways has per-input control so adding fully-controller intermediate INTC will only bring some overhead on interrupt processing but no other benefits. Thus we just do one-time configuration of DW APB GPIO controller and forget about it. Based on implementation available on arch/arc/plat-axs10x/axs10x.c file. Acked-by: Alexey Brodkin <[email protected]> Signed-off-by: Gustavo Pimentel <[email protected]> Signed-off-by: Vineet Gupta <[email protected]>
1 parent 7605385 commit ec58ba1

File tree

1 file changed

+62
-0
lines changed

1 file changed

+62
-0
lines changed

arch/arc/plat-hsdk/platform.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,66 @@ static void __init hsdk_init_per_cpu(unsigned int cpu)
4242
#define SDIO_UHS_REG_EXT (SDIO_BASE + 0x108)
4343
#define SDIO_UHS_REG_EXT_DIV_2 (2 << 30)
4444

45+
#define HSDK_GPIO_INTC (ARC_PERIPHERAL_BASE + 0x3000)
46+
47+
static void __init hsdk_enable_gpio_intc_wire(void)
48+
{
49+
/*
50+
* Peripherals on CPU Card are wired to cpu intc via intermediate
51+
* DW APB GPIO blocks (mainly for debouncing)
52+
*
53+
* ---------------------
54+
* | snps,archs-intc |
55+
* ---------------------
56+
* |
57+
* ----------------------
58+
* | snps,archs-idu-intc |
59+
* ----------------------
60+
* | | | | |
61+
* | [eth] [USB] [... other peripherals]
62+
* |
63+
* -------------------
64+
* | snps,dw-apb-intc |
65+
* -------------------
66+
* | | | |
67+
* [Bt] [HAPS] [... other peripherals]
68+
*
69+
* Current implementation of "irq-dw-apb-ictl" driver doesn't work well
70+
* with stacked INTCs. In particular problem happens if its master INTC
71+
* not yet instantiated. See discussion here -
72+
* https://lkml.org/lkml/2015/3/4/755
73+
*
74+
* So setup the first gpio block as a passive pass thru and hide it from
75+
* DT hardware topology - connect intc directly to cpu intc
76+
* The GPIO "wire" needs to be init nevertheless (here)
77+
*
78+
* One side adv is that peripheral interrupt handling avoids one nested
79+
* intc ISR hop
80+
*
81+
* According to HSDK User's Manual [1], "Table 2 Interrupt Mapping"
82+
* we have the following GPIO input lines used as sources of interrupt:
83+
* - GPIO[0] - Bluetooth interrupt of RS9113 module
84+
* - GPIO[2] - HAPS interrupt (on HapsTrak 3 connector)
85+
* - GPIO[3] - Audio codec (MAX9880A) interrupt
86+
* - GPIO[8-23] - Available on Arduino and PMOD_x headers
87+
* For now there's no use of Arduino and PMOD_x headers in Linux
88+
* use-case so we only enable lines 0, 2 and 3.
89+
*
90+
* [1] https://github.com/foss-for-synopsys-dwc-arc-processors/ARC-Development-Systems-Forum/wiki/docs/ARC_HSDK_User_Guide.pdf
91+
*/
92+
#define GPIO_INTEN (HSDK_GPIO_INTC + 0x30)
93+
#define GPIO_INTMASK (HSDK_GPIO_INTC + 0x34)
94+
#define GPIO_INTTYPE_LEVEL (HSDK_GPIO_INTC + 0x38)
95+
#define GPIO_INT_POLARITY (HSDK_GPIO_INTC + 0x3c)
96+
#define GPIO_INT_CONNECTED_MASK 0x0d
97+
98+
iowrite32(0xffffffff, (void __iomem *) GPIO_INTMASK);
99+
iowrite32(~GPIO_INT_CONNECTED_MASK, (void __iomem *) GPIO_INTMASK);
100+
iowrite32(0x00000000, (void __iomem *) GPIO_INTTYPE_LEVEL);
101+
iowrite32(0xffffffff, (void __iomem *) GPIO_INT_POLARITY);
102+
iowrite32(GPIO_INT_CONNECTED_MASK, (void __iomem *) GPIO_INTEN);
103+
}
104+
45105
static void __init hsdk_init_early(void)
46106
{
47107
/*
@@ -62,6 +122,8 @@ static void __init hsdk_init_early(void)
62122
* minimum possible div-by-2.
63123
*/
64124
iowrite32(SDIO_UHS_REG_EXT_DIV_2, (void __iomem *) SDIO_UHS_REG_EXT);
125+
126+
hsdk_enable_gpio_intc_wire();
65127
}
66128

67129
static const char *hsdk_compat[] __initconst = {

0 commit comments

Comments
 (0)