File Index
Files and directories
Sign in
FILE

irq_service_dce60.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/amd/display/dc/irq/dce60/irq_service_dce60.c C
  1/*
  2 * Copyright 2020 Mauro Rossi <issor.oruam@gmail.com>
  3 *
  4 * Permission is hereby granted, free of charge, to any person obtaining a
  5 * copy of this software and associated documentation files (the "Software"),
  6 * to deal in the Software without restriction, including without limitation
  7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8 * and/or sell copies of the Software, and to permit persons to whom the
  9 * Software is furnished to do so, subject to the following conditions:
 10 *
 11 * The above copyright notice and this permission notice shall be included in
 12 * all copies or substantial portions of the Software.
 13 *
 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 20 * OTHER DEALINGS IN THE SOFTWARE.
 21 *
 22 * Authors: AMD
 23 *
 24 */
 25
 26#include <linux/slab.h>
 27
 28#include "dm_services.h"
 29
 30#include "include/logger_interface.h"
 31
 32#include "irq_service_dce60.h"
 33#include "../dce110/irq_service_dce110.h"
 34
 35#include "dce/dce_6_0_d.h"
 36#include "dce/dce_6_0_sh_mask.h"
 37
 38#include "ivsrcid/ivsrcid_vislands30.h"
 39
 40#define VISLANDS30_IV_SRCID_D1_VBLANK                        1
 41#define VISLANDS30_IV_SRCID_D2_VBLANK                        2
 42#define VISLANDS30_IV_SRCID_D3_VBLANK                        3
 43#define VISLANDS30_IV_SRCID_D4_VBLANK                        4
 44#define VISLANDS30_IV_SRCID_D5_VBLANK                        5
 45#define VISLANDS30_IV_SRCID_D6_VBLANK                        6
 46
 47#include "dc_types.h"
 48
 49static struct irq_source_info_funcs hpd_irq_info_funcs  = {
 50	.set = NULL,
 51	.ack = hpd1_ack
 52};
 53
 54static struct irq_source_info_funcs hpd_rx_irq_info_funcs = {
 55	.set = NULL,
 56	.ack = NULL
 57};
 58
 59static struct irq_source_info_funcs pflip_irq_info_funcs = {
 60	.set = NULL,
 61	.ack = NULL
 62};
 63
 64static struct irq_source_info_funcs vblank_irq_info_funcs = {
 65	.set = dce110_vblank_set,
 66	.ack = NULL
 67};
 68
 69static struct irq_source_info_funcs vblank_irq_info_funcs_dce60 = {
 70	.set = NULL,
 71	.ack = NULL
 72};
 73
 74#define hpd_int_entry(reg_num)\
 75	[DC_IRQ_SOURCE_INVALID + reg_num] = {\
 76		.enable_reg = mmDC_HPD ## reg_num ## _INT_CONTROL,\
 77		.enable_mask = DC_HPD1_INT_CONTROL__DC_HPD1_INT_EN_MASK,\
 78		.enable_value = {\
 79			DC_HPD1_INT_CONTROL__DC_HPD1_INT_EN_MASK,\
 80			~DC_HPD1_INT_CONTROL__DC_HPD1_INT_EN_MASK\
 81		},\
 82		.ack_reg = mmDC_HPD ## reg_num ## _INT_CONTROL,\
 83		.ack_mask = DC_HPD1_INT_CONTROL__DC_HPD1_INT_ACK_MASK,\
 84		.ack_value = DC_HPD1_INT_CONTROL__DC_HPD1_INT_ACK_MASK,\
 85		.status_reg = mmDC_HPD ## reg_num ## _INT_STATUS,\
 86		.funcs = &hpd_irq_info_funcs\
 87	}
 88
 89#define hpd_rx_int_entry(reg_num)\
 90	[DC_IRQ_SOURCE_HPD6 + reg_num] = {\
 91		.enable_reg = mmDC_HPD ## reg_num ## _INT_CONTROL,\
 92		.enable_mask = DC_HPD1_INT_CONTROL__DC_HPD1_RX_INT_EN_MASK,\
 93		.enable_value = {\
 94				DC_HPD1_INT_CONTROL__DC_HPD1_RX_INT_EN_MASK,\
 95			~DC_HPD1_INT_CONTROL__DC_HPD1_RX_INT_EN_MASK },\
 96		.ack_reg = mmDC_HPD ## reg_num ## _INT_CONTROL,\
 97		.ack_mask = DC_HPD1_INT_CONTROL__DC_HPD1_RX_INT_ACK_MASK,\
 98		.ack_value = DC_HPD1_INT_CONTROL__DC_HPD1_RX_INT_ACK_MASK,\
 99		.status_reg = mmDC_HPD ## reg_num ## _INT_STATUS,\
100		.funcs = &hpd_rx_irq_info_funcs\
101	}
102
103#define pflip_int_entry(reg_num)\
104	[DC_IRQ_SOURCE_PFLIP1 + reg_num] = {\
105		.enable_reg = mmDCP ## reg_num ## _GRPH_INTERRUPT_CONTROL,\
106		.enable_mask =\
107		GRPH_INTERRUPT_CONTROL__GRPH_PFLIP_INT_MASK_MASK,\
108		.enable_value = {\
109			GRPH_INTERRUPT_CONTROL__GRPH_PFLIP_INT_MASK_MASK,\
110			~GRPH_INTERRUPT_CONTROL__GRPH_PFLIP_INT_MASK_MASK},\
111		.ack_reg = mmDCP ## reg_num ## _GRPH_INTERRUPT_STATUS,\
112		.ack_mask = GRPH_INTERRUPT_STATUS__GRPH_PFLIP_INT_CLEAR_MASK,\
113		.ack_value = GRPH_INTERRUPT_STATUS__GRPH_PFLIP_INT_CLEAR_MASK,\
114		.status_reg = mmDCP ## reg_num ##_GRPH_INTERRUPT_STATUS,\
115		.funcs = &pflip_irq_info_funcs\
116 	}
117
118#define vupdate_int_entry(reg_num)\
119	[DC_IRQ_SOURCE_VUPDATE1 + reg_num] = {\
120		.enable_reg = mmCRTC ## reg_num ## _CRTC_INTERRUPT_CONTROL,\
121		.enable_mask =\
122		CRTC_INTERRUPT_CONTROL__CRTC_V_UPDATE_INT_MSK_MASK,\
123		.enable_value = {\
124			CRTC_INTERRUPT_CONTROL__CRTC_V_UPDATE_INT_MSK_MASK,\
125			~CRTC_INTERRUPT_CONTROL__CRTC_V_UPDATE_INT_MSK_MASK},\
126		.ack_reg = mmCRTC ## reg_num ## _CRTC_V_UPDATE_INT_STATUS,\
127		.ack_mask =\
128		CRTC_V_UPDATE_INT_STATUS__CRTC_V_UPDATE_INT_CLEAR_MASK,\
129		.ack_value =\
130		CRTC_V_UPDATE_INT_STATUS__CRTC_V_UPDATE_INT_CLEAR_MASK,\
131		.funcs = &vblank_irq_info_funcs\
132	}
133
134#define vblank_int_entry(reg_num)\
135	[DC_IRQ_SOURCE_VBLANK1 + reg_num] = {\
136		.enable_reg = mmLB ## reg_num ## _INT_MASK,\
137		.enable_mask =\
138			INT_MASK__VBLANK_INT_MASK,\
139		.enable_value = {\
140			INT_MASK__VBLANK_INT_MASK,\
141			~INT_MASK__VBLANK_INT_MASK},\
142		.ack_reg = mmLB ## reg_num ## _VBLANK_STATUS,\
143		.ack_mask =\
144		VBLANK_STATUS__VBLANK_ACK_MASK,\
145		.ack_value =\
146		VBLANK_STATUS__VBLANK_ACK_MASK,\
147		.funcs = &vblank_irq_info_funcs_dce60\
148	}
149
150#define dummy_irq_entry() \
151	{\
152		.funcs = &dummy_irq_info_funcs\
153	}
154
155#define i2c_int_entry(reg_num) \
156	[DC_IRQ_SOURCE_I2C_DDC ## reg_num] = dummy_irq_entry()
157
158#define dp_sink_int_entry(reg_num) \
159	[DC_IRQ_SOURCE_DPSINK ## reg_num] = dummy_irq_entry()
160
161#define gpio_pad_int_entry(reg_num) \
162	[DC_IRQ_SOURCE_GPIOPAD ## reg_num] = dummy_irq_entry()
163
164#define dc_underflow_int_entry(reg_num) \
165	[DC_IRQ_SOURCE_DC ## reg_num ## UNDERFLOW] = dummy_irq_entry()
166
167
168static struct irq_source_info_funcs dummy_irq_info_funcs = {
169	.set = dal_irq_service_dummy_set,
170	.ack = dal_irq_service_dummy_ack
171};
172
173static const struct irq_source_info
174irq_source_info_dce60[DAL_IRQ_SOURCES_NUMBER] = {
175	[DC_IRQ_SOURCE_INVALID] = dummy_irq_entry(),
176	hpd_int_entry(1),
177	hpd_int_entry(2),
178	hpd_int_entry(3),
179	hpd_int_entry(4),
180	hpd_int_entry(5),
181	hpd_int_entry(6),
182	hpd_rx_int_entry(1),
183	hpd_rx_int_entry(2),
184	hpd_rx_int_entry(3),
185	hpd_rx_int_entry(4),
186	hpd_rx_int_entry(5),
187	hpd_rx_int_entry(6),
188	i2c_int_entry(1),
189	i2c_int_entry(2),
190	i2c_int_entry(3),
191	i2c_int_entry(4),
192	i2c_int_entry(5),
193	i2c_int_entry(6),
194	dp_sink_int_entry(1),
195	dp_sink_int_entry(2),
196	dp_sink_int_entry(3),
197	dp_sink_int_entry(4),
198	dp_sink_int_entry(5),
199	dp_sink_int_entry(6),
200	[DC_IRQ_SOURCE_TIMER] = dummy_irq_entry(),
201	pflip_int_entry(0),
202	pflip_int_entry(1),
203	pflip_int_entry(2),
204	pflip_int_entry(3),
205	pflip_int_entry(4),
206	pflip_int_entry(5),
207	[DC_IRQ_SOURCE_PFLIP_UNDERLAY0] = dummy_irq_entry(),
208	gpio_pad_int_entry(0),
209	gpio_pad_int_entry(1),
210	gpio_pad_int_entry(2),
211	gpio_pad_int_entry(3),
212	gpio_pad_int_entry(4),
213	gpio_pad_int_entry(5),
214	gpio_pad_int_entry(6),
215	gpio_pad_int_entry(7),
216	gpio_pad_int_entry(8),
217	gpio_pad_int_entry(9),
218	gpio_pad_int_entry(10),
219	gpio_pad_int_entry(11),
220	gpio_pad_int_entry(12),
221	gpio_pad_int_entry(13),
222	gpio_pad_int_entry(14),
223	gpio_pad_int_entry(15),
224	gpio_pad_int_entry(16),
225	gpio_pad_int_entry(17),
226	gpio_pad_int_entry(18),
227	gpio_pad_int_entry(19),
228	gpio_pad_int_entry(20),
229	gpio_pad_int_entry(21),
230	gpio_pad_int_entry(22),
231	gpio_pad_int_entry(23),
232	gpio_pad_int_entry(24),
233	gpio_pad_int_entry(25),
234	gpio_pad_int_entry(26),
235	gpio_pad_int_entry(27),
236	gpio_pad_int_entry(28),
237	gpio_pad_int_entry(29),
238	gpio_pad_int_entry(30),
239	dc_underflow_int_entry(1),
240	dc_underflow_int_entry(2),
241	dc_underflow_int_entry(3),
242	dc_underflow_int_entry(4),
243	dc_underflow_int_entry(5),
244	dc_underflow_int_entry(6),
245	[DC_IRQ_SOURCE_DMCU_SCP] = dummy_irq_entry(),
246	[DC_IRQ_SOURCE_VBIOS_SW] = dummy_irq_entry(),
247	vupdate_int_entry(0),
248	vupdate_int_entry(1),
249	vupdate_int_entry(2),
250	vupdate_int_entry(3),
251	vupdate_int_entry(4),
252	vupdate_int_entry(5),
253	vblank_int_entry(0),
254	vblank_int_entry(1),
255	vblank_int_entry(2),
256	vblank_int_entry(3),
257	vblank_int_entry(4),
258	vblank_int_entry(5),
259};
260
261enum dc_irq_source to_dal_irq_source_dce60(
262		struct irq_service *irq_service,
263		uint32_t src_id,
264		uint32_t ext_id)
265{
266	switch (src_id) {
267	case VISLANDS30_IV_SRCID_D1_VBLANK:
268		return DC_IRQ_SOURCE_VBLANK1;
269	case VISLANDS30_IV_SRCID_D2_VBLANK:
270		return DC_IRQ_SOURCE_VBLANK2;
271	case VISLANDS30_IV_SRCID_D3_VBLANK:
272		return DC_IRQ_SOURCE_VBLANK3;
273	case VISLANDS30_IV_SRCID_D4_VBLANK:
274		return DC_IRQ_SOURCE_VBLANK4;
275	case VISLANDS30_IV_SRCID_D5_VBLANK:
276		return DC_IRQ_SOURCE_VBLANK5;
277	case VISLANDS30_IV_SRCID_D6_VBLANK:
278		return DC_IRQ_SOURCE_VBLANK6;
279	case VISLANDS30_IV_SRCID_D1_V_UPDATE_INT:
280		return DC_IRQ_SOURCE_VUPDATE1;
281	case VISLANDS30_IV_SRCID_D2_V_UPDATE_INT:
282		return DC_IRQ_SOURCE_VUPDATE2;
283	case VISLANDS30_IV_SRCID_D3_V_UPDATE_INT:
284		return DC_IRQ_SOURCE_VUPDATE3;
285	case VISLANDS30_IV_SRCID_D4_V_UPDATE_INT:
286		return DC_IRQ_SOURCE_VUPDATE4;
287	case VISLANDS30_IV_SRCID_D5_V_UPDATE_INT:
288		return DC_IRQ_SOURCE_VUPDATE5;
289	case VISLANDS30_IV_SRCID_D6_V_UPDATE_INT:
290		return DC_IRQ_SOURCE_VUPDATE6;
291	case VISLANDS30_IV_SRCID_D1_GRPH_PFLIP:
292		return DC_IRQ_SOURCE_PFLIP1;
293	case VISLANDS30_IV_SRCID_D2_GRPH_PFLIP:
294		return DC_IRQ_SOURCE_PFLIP2;
295	case VISLANDS30_IV_SRCID_D3_GRPH_PFLIP:
296		return DC_IRQ_SOURCE_PFLIP3;
297	case VISLANDS30_IV_SRCID_D4_GRPH_PFLIP:
298		return DC_IRQ_SOURCE_PFLIP4;
299	case VISLANDS30_IV_SRCID_D5_GRPH_PFLIP:
300		return DC_IRQ_SOURCE_PFLIP5;
301	case VISLANDS30_IV_SRCID_D6_GRPH_PFLIP:
302		return DC_IRQ_SOURCE_PFLIP6;
303
304	case VISLANDS30_IV_SRCID_HOTPLUG_DETECT_A:
305		/* generic src_id for all HPD and HPDRX interrupts */
306		switch (ext_id) {
307		case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_A:
308			return DC_IRQ_SOURCE_HPD1;
309		case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_B:
310			return DC_IRQ_SOURCE_HPD2;
311		case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_C:
312			return DC_IRQ_SOURCE_HPD3;
313		case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_D:
314			return DC_IRQ_SOURCE_HPD4;
315		case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_E:
316			return DC_IRQ_SOURCE_HPD5;
317		case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_F:
318			return DC_IRQ_SOURCE_HPD6;
319		case VISLANDS30_IV_EXTID_HPD_RX_A:
320			return DC_IRQ_SOURCE_HPD1RX;
321		case VISLANDS30_IV_EXTID_HPD_RX_B:
322			return DC_IRQ_SOURCE_HPD2RX;
323		case VISLANDS30_IV_EXTID_HPD_RX_C:
324			return DC_IRQ_SOURCE_HPD3RX;
325		case VISLANDS30_IV_EXTID_HPD_RX_D:
326			return DC_IRQ_SOURCE_HPD4RX;
327		case VISLANDS30_IV_EXTID_HPD_RX_E:
328			return DC_IRQ_SOURCE_HPD5RX;
329		case VISLANDS30_IV_EXTID_HPD_RX_F:
330			return DC_IRQ_SOURCE_HPD6RX;
331		default:
332			return DC_IRQ_SOURCE_INVALID;
333		}
334		break;
335
336	default:
337		return DC_IRQ_SOURCE_INVALID;
338	}
339}
340
341static const struct irq_service_funcs irq_service_funcs_dce60 = {
342		.to_dal_irq_source = to_dal_irq_source_dce60
343};
344
345static void dce60_irq_construct(
346	struct irq_service *irq_service,
347	struct irq_service_init_data *init_data)
348{
349	dal_irq_service_construct(irq_service, init_data);
350
351	irq_service->info = irq_source_info_dce60;
352	irq_service->funcs = &irq_service_funcs_dce60;
353}
354
355struct irq_service *dal_irq_service_dce60_create(
356	struct irq_service_init_data *init_data)
357{
358	struct irq_service *irq_service = kzalloc(sizeof(*irq_service),
359						  GFP_KERNEL);
360
361	if (!irq_service)
362		return NULL;
363
364	dce60_irq_construct(irq_service, init_data);
365	return irq_service;
366}
~/ Read-only file preview.