xref: /rk3399_rockchip-uboot/include/irq-generic.h (revision 1b461e2d3af6210f3e788aab491c8f89d9cfdd8e)
14e6670feSJoseph Chen /*
24e6670feSJoseph Chen  * (C) Copyright 2017 Rockchip Electronics Co., Ltd
34e6670feSJoseph Chen  *
44e6670feSJoseph Chen  * SPDX-License-Identifier:     GPL-2.0+
54e6670feSJoseph Chen  */
64e6670feSJoseph Chen 
74e6670feSJoseph Chen #ifndef _IRQ_GENERIC_H
84e6670feSJoseph Chen #define _IRQ_GENERIC_H
94e6670feSJoseph Chen 
104e6670feSJoseph Chen #include <asm-generic/gpio.h>
114e6670feSJoseph Chen #include <common.h>
124e6670feSJoseph Chen #include <dt-bindings/pinctrl/rockchip.h>
134e6670feSJoseph Chen 
14269512fdSJoseph Chen #define IRQ_I(fmt, args...)	printf("IRQ: "fmt, ##args)
15269512fdSJoseph Chen #define IRQ_W(fmt, args...)	printf("IRQ Warn: "fmt, ##args)
16269512fdSJoseph Chen #define IRQ_E(fmt, args...)	printf("IRQ Err: "fmt, ##args)
17269512fdSJoseph Chen #define IRQ_D(fmt, args...)	 debug("IRQ Debug "fmt, ##args)
18269512fdSJoseph Chen 
194e6670feSJoseph Chen /*
204e6670feSJoseph Chen  * IRQ line status.
214e6670feSJoseph Chen  *
224e6670feSJoseph Chen  * IRQ_TYPE_NONE		- default, unspecified type
234e6670feSJoseph Chen  * IRQ_TYPE_EDGE_RISING		- rising edge triggered
244e6670feSJoseph Chen  * IRQ_TYPE_EDGE_FALLING	- falling edge triggered
254e6670feSJoseph Chen  * IRQ_TYPE_EDGE_BOTH		- rising and falling edge triggered
264e6670feSJoseph Chen  * IRQ_TYPE_LEVEL_HIGH		- high level triggered
274e6670feSJoseph Chen  * IRQ_TYPE_LEVEL_LOW		- low level triggered
284e6670feSJoseph Chen  * IRQ_TYPE_LEVEL_MASK		- mask to filter out the level bits
294e6670feSJoseph Chen  * IRQ_TYPE_SENSE_MASK		- mask for all the above bits
304e6670feSJoseph Chen  */
314e6670feSJoseph Chen enum {
324e6670feSJoseph Chen 	IRQ_TYPE_NONE		= 0x00000000,
334e6670feSJoseph Chen 	IRQ_TYPE_EDGE_RISING	= 0x00000001,
344e6670feSJoseph Chen 	IRQ_TYPE_EDGE_FALLING	= 0x00000002,
354e6670feSJoseph Chen 	IRQ_TYPE_EDGE_BOTH	= (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING),
364e6670feSJoseph Chen 	IRQ_TYPE_LEVEL_HIGH	= 0x00000004,
374e6670feSJoseph Chen 	IRQ_TYPE_LEVEL_LOW	= 0x00000008,
384e6670feSJoseph Chen 	IRQ_TYPE_LEVEL_MASK	= (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH),
394e6670feSJoseph Chen 	IRQ_TYPE_SENSE_MASK	= 0x0000000f,
404e6670feSJoseph Chen };
414e6670feSJoseph Chen 
424e6670feSJoseph Chen /*
434e6670feSJoseph Chen  * struct irq_chip - hardware interrupt chip descriptor
444e6670feSJoseph Chen  *
454e6670feSJoseph Chen  * @name:		name for irq chip
464e6670feSJoseph Chen  * @irq_enable:		enable the interrupt (defaults to chip->unmask if NULL)
474e6670feSJoseph Chen  * @irq_disable:	disable the interrupt
484e6670feSJoseph Chen  * @irq_ack:		start of a new interrupt
494e6670feSJoseph Chen  * @irq_eoi:		end of interrupt
504e6670feSJoseph Chen  * @irq_set_type:	set the flow type (IRQ_TYPE_LEVEL/etc.) of an IRQ
514e6670feSJoseph Chen  */
524e6670feSJoseph Chen struct irq_chip {
534e6670feSJoseph Chen 	const char	*name;
544e6670feSJoseph Chen 	int		(*irq_init)(void);
55ed837edfSJoseph Chen 	int		(*irq_suspend)(void);
56ed837edfSJoseph Chen 	int		(*irq_resume)(void);
574e6670feSJoseph Chen 	int		(*irq_get)(void);
584e6670feSJoseph Chen 	int		(*irq_enable)(int irq);
594e6670feSJoseph Chen 	int		(*irq_disable)(int irq);
604e6670feSJoseph Chen 	void		(*irq_ack)(int irq);
614e6670feSJoseph Chen 	void		(*irq_eoi)(int irq);
624e6670feSJoseph Chen 	int		(*irq_set_type)(int irq, unsigned int flow_type);
63c234b81eSJoseph Chen 	int		(*irq_revert_type)(int irq);
64c234b81eSJoseph Chen 	int		(*irq_get_gpio_level)(int irq);
654e6670feSJoseph Chen };
664e6670feSJoseph Chen 
6741766119SJoseph Chen /*
6841766119SJoseph Chen  * Virtual irq chip structure
6941766119SJoseph Chen  */
70*1b461e2dSJoseph Chen typedef int(virq_write_t)(struct udevice *dev, uint reg, uint value);
71*1b461e2dSJoseph Chen typedef int(virq_read_t)(struct udevice *dev, uint reg);
7241766119SJoseph Chen 
7341766119SJoseph Chen struct virq_reg {
7441766119SJoseph Chen 	uint reg_offset;
7541766119SJoseph Chen 	uint mask;
7641766119SJoseph Chen };
7741766119SJoseph Chen 
7841766119SJoseph Chen struct virq_chip {
7941766119SJoseph Chen 	uint status_base;
8041766119SJoseph Chen 	uint mask_base;
8141766119SJoseph Chen 	uint irq_reg_stride;
8241766119SJoseph Chen 	uint irq_unalign_reg_idx;
8341766119SJoseph Chen 	uint irq_unalign_reg_stride;
8441766119SJoseph Chen 	int num_regs;
8541766119SJoseph Chen 	const struct virq_reg *irqs;
8641766119SJoseph Chen 	int num_irqs;
87*1b461e2dSJoseph Chen 	virq_read_t *read;
88*1b461e2dSJoseph Chen 	virq_write_t *write;
8941766119SJoseph Chen };
9041766119SJoseph Chen 
914e6670feSJoseph Chen /* APIs for irqs */
924e6670feSJoseph Chen void irq_install_handler(int irq, interrupt_handler_t *handler, void *data);
934e6670feSJoseph Chen void irq_free_handler(int irq);
944e6670feSJoseph Chen int irq_set_irq_type(int irq, unsigned int type);
95c234b81eSJoseph Chen int irq_revert_irq_type(int irq);
964e6670feSJoseph Chen int irq_handler_enable(int irq);
972c4e90c1SJoseph Chen int irq_handler_enable_suspend_only(int irq);
984e6670feSJoseph Chen int irq_handler_disable(int irq);
99c234b81eSJoseph Chen int irq_get_gpio_level(int irq);
100ed837edfSJoseph Chen int irqs_suspend(void);
101ed837edfSJoseph Chen int irqs_resume(void);
1028696cc38SJoseph Chen int irq_is_busy(int irq);
1034e6670feSJoseph Chen int gpio_to_irq(struct gpio_desc *gpio);
1044e6670feSJoseph Chen 
1054e6670feSJoseph Chen /*
1064e6670feSJoseph Chen  * Assign gpio to irq directly. Don't use it without special reasons.
1074e6670feSJoseph Chen  *
1084e6670feSJoseph Chen  * Usage example:
1094e6670feSJoseph Chen  *	int gpio0_a0, irq;
1104e6670feSJoseph Chen  *
1114e6670feSJoseph Chen  *	gpio = RK_IRQ_GPIO(RK_GPIO0, RK_PA0);
1124e6670feSJoseph Chen  *	irq = hard_gpio_to_irq(gpio0_a0);
1134e6670feSJoseph Chen  *	irq_install_handler(irq, ...);
1144e6670feSJoseph Chen  */
1154e6670feSJoseph Chen #define GPIO_BANK_SHIFT			8
1164e6670feSJoseph Chen #define RK_IRQ_GPIO(bank, pin) 		(((bank) << GPIO_BANK_SHIFT) | (pin))
117269512fdSJoseph Chen 
1184e6670feSJoseph Chen int hard_gpio_to_irq(unsigned gpio);
1195db1153eSJoseph Chen int phandle_gpio_to_irq(u32 gpio_phandle, u32 pin);
1204e6670feSJoseph Chen 
12141766119SJoseph Chen /* Virtual irq */
12241766119SJoseph Chen int virq_to_irq(struct virq_chip *chip, int virq);
12325c13168SJoseph Chen int virq_add_chip(struct udevice *dev, struct virq_chip *chip, int irq);
12441766119SJoseph Chen 
1254e6670feSJoseph Chen #endif /* _IRQ_GENERIC_H */
126