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