1 /*
2 * Copyright (c) 2006-2022, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2022-08-24 GuEe-GUI first version
9 */
10
11 #ifndef __PIC_H__
12 #define __PIC_H__
13
14 #include <rthw.h>
15
16 #include <bitmap.h>
17 #include <drivers/ofw.h>
18 #include <drivers/core/dm.h>
19
20 struct rt_pci_msi_desc;
21 struct rt_pci_msi_msg;
22
23 struct rt_pic_ops;
24 struct rt_pic_irq;
25
26 struct rt_pic
27 {
28 /*
29 * Other IC is not implemented with PIC but rt_device/object, we need to
30 * identify with this object:
31 *
32 * struct rt_ic_XYZ_device
33 * {
34 * struct rt_device parent;
35 * struct rt_pic pic;
36 * ...
37 * };
38 */
39 struct rt_object parent;
40
41 rt_list_t list;
42
43 const struct rt_pic_ops *ops;
44
45 void *priv_data;
46 void *user_data;
47
48 int irq_start;
49 rt_size_t irq_nr;
50 struct rt_pic_irq *pirqs;
51 };
52
53 struct rt_pic_ops
54 {
55 const char *name;
56
57 rt_err_t (*irq_init)(struct rt_pic *pic);
58 rt_err_t (*irq_finit)(struct rt_pic *pic);
59
60 void (*irq_enable)(struct rt_pic_irq *pirq);
61 void (*irq_disable)(struct rt_pic_irq *pirq);
62 void (*irq_ack)(struct rt_pic_irq *pirq);
63 void (*irq_mask)(struct rt_pic_irq *pirq);
64 void (*irq_unmask)(struct rt_pic_irq *pirq);
65 void (*irq_eoi)(struct rt_pic_irq *pirq);
66
67 rt_err_t (*irq_set_priority)(struct rt_pic_irq *pirq, rt_uint32_t priority);
68 rt_err_t (*irq_set_affinity)(struct rt_pic_irq *pirq, rt_bitmap_t *affinity);
69 rt_err_t (*irq_set_triger_mode)(struct rt_pic_irq *pirq, rt_uint32_t mode);
70
71 void (*irq_send_ipi)(struct rt_pic_irq *pirq, rt_bitmap_t *cpumask);
72
73 void (*irq_compose_msi_msg)(struct rt_pic_irq *pirq, struct rt_pci_msi_msg *msg);
74 void (*irq_write_msi_msg)(struct rt_pic_irq *pirq, struct rt_pci_msi_msg *msg);
75 int (*irq_alloc_msi)(struct rt_pic *pic, struct rt_pci_msi_desc *msi_desc);
76 void (*irq_free_msi)(struct rt_pic *pic, int irq);
77
78 #define RT_IRQ_STATE_PENDING 0
79 #define RT_IRQ_STATE_ACTIVE 1
80 #define RT_IRQ_STATE_MASKED 2
81 rt_err_t (*irq_set_state)(struct rt_pic *pic, int hwirq, int type, rt_bool_t state);
82 rt_err_t (*irq_get_state)(struct rt_pic *pic, int hwirq, int type, rt_bool_t *out_state);
83
84 int (*irq_map)(struct rt_pic *pic, int hwirq, rt_uint32_t mode);
85 rt_err_t (*irq_parse)(struct rt_pic *pic, struct rt_ofw_cell_args *args, struct rt_pic_irq *out_pirq);
86
87 #define RT_PIC_F_IRQ_ROUTING RT_BIT(0) /* Routing ISR when cascade */
88 rt_ubase_t flags;
89 };
90
91 struct rt_pic_isr
92 {
93 rt_list_t list;
94
95 #define RT_IRQ_F_NONE 0
96 int flags;
97 struct rt_irq_desc action;
98 };
99
100 #define RT_IRQ_AFFINITY_DECLARE(name) RT_BITMAP_DECLARE(name, RT_CPUS_NR)
101 #define RT_IRQ_AFFINITY_SET(affinity, cpuid) rt_bitmap_set_bit(affinity, cpuid)
102 #define RT_IRQ_AFFINITY_CLEAR(affinity, cpuid) rt_bitmap_clear_bit(affinity, cpuid)
103
104 #ifdef RT_USING_PIC_STATISTICS
105 struct rt_pic_irq_statistics
106 {
107 rt_ubase_t max_irq_time_ns;
108 rt_ubase_t min_irq_time_ns;
109 rt_ubase_t sum_irq_time_ns;
110 };
111 #endif
112
113 struct rt_pic_irq
114 {
115 int irq;
116 int hwirq;
117
118 #define RT_IRQ_MODE_NONE 0
119 #define RT_IRQ_MODE_EDGE_RISING 1
120 #define RT_IRQ_MODE_EDGE_FALLING 2
121 #define RT_IRQ_MODE_EDGE_BOTH (RT_IRQ_MODE_EDGE_FALLING | RT_IRQ_MODE_EDGE_RISING)
122 #define RT_IRQ_MODE_LEVEL_HIGH 4
123 #define RT_IRQ_MODE_LEVEL_LOW 8
124 #define RT_IRQ_MODE_LEVEL_MASK (RT_IRQ_MODE_LEVEL_LOW | RT_IRQ_MODE_LEVEL_HIGH)
125 #define RT_IRQ_MODE_MASK 0xf
126 rt_uint32_t mode;
127
128 rt_uint32_t priority;
129 RT_IRQ_AFFINITY_DECLARE(affinity);
130
131 rt_list_t list;
132 rt_list_t children_nodes;
133
134 struct rt_pci_msi_desc *msi_desc;
135
136 struct rt_pic_isr isr;
137
138 struct rt_spinlock rw_lock;
139
140 struct rt_pic *pic;
141 struct rt_pic_irq *parent;
142 #ifdef RT_USING_PIC_STATISTICS
143 struct rt_pic_irq_statistics stat;
144 #endif
145 };
146
147 void rt_pic_default_name(struct rt_pic *pic);
148 struct rt_pic *rt_pic_dynamic_cast(void *ptr);
149
150 rt_err_t rt_pic_linear_irq(struct rt_pic *pic, rt_size_t irq_nr);
151 rt_err_t rt_pic_cancel_irq(struct rt_pic *pic);
152
153 int rt_pic_config_ipi(struct rt_pic *pic, int ipi_index, int hwirq);
154 int rt_pic_config_irq(struct rt_pic *pic, int irq_index, int hwirq);
155
rt_pic_find_irq(struct rt_pic * pic,int irq_index)156 rt_inline struct rt_pic_irq *rt_pic_find_irq(struct rt_pic *pic, int irq_index)
157 {
158 /* This is a quickly interface */
159 RT_ASSERT(pic != RT_NULL);
160 RT_ASSERT(pic->pirqs != RT_NULL);
161 RT_ASSERT(irq_index < pic->irq_nr);
162
163 return &pic->pirqs[irq_index];
164 }
165
166 struct rt_pic_irq *rt_pic_find_ipi(struct rt_pic *pic, int ipi_index);
167 struct rt_pic_irq *rt_pic_find_pirq(struct rt_pic *pic, int irq);
168
169 rt_err_t rt_pic_cascade(struct rt_pic_irq *pirq, int parent_irq);
170 rt_err_t rt_pic_uncascade(struct rt_pic_irq *pirq);
171
172 rt_err_t rt_pic_attach_irq(int irq, rt_isr_handler_t handler, void *uid, const char *name, int flags);
173 rt_err_t rt_pic_detach_irq(int irq, void *uid);
174
175 rt_err_t rt_pic_add_traps(rt_bool_t (*handler)(void *), void *data);
176 rt_err_t rt_pic_do_traps(void);
177 rt_err_t rt_pic_handle_isr(struct rt_pic_irq *pirq);
178
179 /* User-implemented extensions */
180 rt_err_t rt_pic_user_extends(struct rt_pic *pic);
181
182 rt_err_t rt_pic_irq_init(void);
183 rt_err_t rt_pic_irq_finit(void);
184 void rt_pic_irq_enable(int irq);
185 void rt_pic_irq_disable(int irq);
186 void rt_pic_irq_ack(int irq);
187 void rt_pic_irq_mask(int irq);
188 void rt_pic_irq_unmask(int irq);
189 void rt_pic_irq_eoi(int irq);
190 rt_err_t rt_pic_irq_set_priority(int irq, rt_uint32_t priority);
191 rt_uint32_t rt_pic_irq_get_priority(int irq);
192 rt_err_t rt_pic_irq_set_affinity(int irq, rt_bitmap_t *affinity);
193 rt_err_t rt_pic_irq_get_affinity(int irq, rt_bitmap_t *out_affinity);
194 rt_err_t rt_pic_irq_set_triger_mode(int irq, rt_uint32_t mode);
195 rt_uint32_t rt_pic_irq_get_triger_mode(int irq);
196 void rt_pic_irq_send_ipi(int irq, rt_bitmap_t *cpumask);
197
198 rt_err_t rt_pic_irq_set_state_raw(struct rt_pic *pic, int hwirq, int type, rt_bool_t state);
199 rt_err_t rt_pic_irq_get_state_raw(struct rt_pic *pic, int hwirq, int type, rt_bool_t *out_state);
200 rt_err_t rt_pic_irq_set_state(int irq, int type, rt_bool_t state);
201 rt_err_t rt_pic_irq_get_state(int irq, int type, rt_bool_t *out_state);
202
203 void rt_pic_irq_parent_enable(struct rt_pic_irq *pirq);
204 void rt_pic_irq_parent_disable(struct rt_pic_irq *pirq);
205 void rt_pic_irq_parent_ack(struct rt_pic_irq *pirq);
206 void rt_pic_irq_parent_mask(struct rt_pic_irq *pirq);
207 void rt_pic_irq_parent_unmask(struct rt_pic_irq *pirq);
208 void rt_pic_irq_parent_eoi(struct rt_pic_irq *pirq);
209 rt_err_t rt_pic_irq_parent_set_priority(struct rt_pic_irq *pirq, rt_uint32_t priority);
210 rt_err_t rt_pic_irq_parent_set_affinity(struct rt_pic_irq *pirq, rt_bitmap_t *affinity);
211 rt_err_t rt_pic_irq_parent_set_triger_mode(struct rt_pic_irq *pirq, rt_uint32_t mode);
212
213 #define RT_PIC_OFW_DECLARE(name, ids, handler) RT_OFW_STUB_EXPORT(name, ids, pic, handler)
214
215 rt_err_t rt_pic_init(void);
216
217 #endif /* __PIC_H__ */
218