1 // SPDX-License-Identifier: GPL-2.0-only
3 * Tegra host1x Interrupt Management
5 * Copyright (C) 2010 Google, Inc.
6 * Copyright (c) 2010-2013, NVIDIA Corporation.
14 static irqreturn_t
syncpt_thresh_isr(int irq
, void *dev_id
)
16 struct host1x_intr_irq_data
*irq_data
= dev_id
;
17 struct host1x
*host
= irq_data
->host
;
21 for (i
= irq_data
->offset
; i
< DIV_ROUND_UP(host
->info
->nb_pts
, 32);
22 i
+= host
->num_syncpt_irqs
) {
23 reg
= host1x_sync_readl(host
,
24 HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(i
));
26 host1x_sync_writel(host
, reg
,
27 HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(i
));
28 host1x_sync_writel(host
, reg
,
29 HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(i
));
31 for_each_set_bit(id
, ®
, 32)
32 host1x_intr_handle_interrupt(host
, i
* 32 + id
);
38 static void host1x_intr_disable_all_syncpt_intrs(struct host1x
*host
)
42 for (i
= 0; i
< DIV_ROUND_UP(host
->info
->nb_pts
, 32); ++i
) {
43 host1x_sync_writel(host
, 0xffffffffu
,
44 HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(i
));
45 host1x_sync_writel(host
, 0xffffffffu
,
46 HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(i
));
51 host1x_intr_init_host_sync(struct host1x
*host
, u32 cpm
)
54 /* disable the ip_busy_timeout. this prevents write drops */
55 host1x_sync_writel(host
, 0, HOST1X_SYNC_IP_BUSY_TIMEOUT
);
58 * increase the auto-ack timout to the maximum value. 2d will hang
59 * otherwise on Tegra2.
61 host1x_sync_writel(host
, 0xff, HOST1X_SYNC_CTXSW_TIMEOUT_CFG
);
63 /* update host clocks per usec */
64 host1x_sync_writel(host
, cpm
, HOST1X_SYNC_USEC_CLK
);
70 * Program threshold interrupt destination among 8 lines per VM,
71 * per syncpoint. For each group of 32 syncpoints (corresponding to one
72 * interrupt status register), direct to one interrupt line, going
73 * around in a round robin fashion.
75 for (id
= 0; id
< host
->info
->nb_pts
; id
++) {
76 u32 reg_offset
= id
/ 32;
77 u32 irq_index
= reg_offset
% host
->num_syncpt_irqs
;
79 host1x_sync_writel(host
, irq_index
, HOST1X_SYNC_SYNCPT_INTR_DEST(id
));
86 static void host1x_intr_set_syncpt_threshold(struct host1x
*host
,
90 host1x_sync_writel(host
, thresh
, HOST1X_SYNC_SYNCPT_INT_THRESH(id
));
93 static void host1x_intr_enable_syncpt_intr(struct host1x
*host
,
96 host1x_sync_writel(host
, BIT(id
% 32),
97 HOST1X_SYNC_SYNCPT_THRESH_INT_ENABLE_CPU0(id
/ 32));
100 static void host1x_intr_disable_syncpt_intr(struct host1x
*host
,
103 host1x_sync_writel(host
, BIT(id
% 32),
104 HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(id
/ 32));
105 host1x_sync_writel(host
, BIT(id
% 32),
106 HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(id
/ 32));
109 static const struct host1x_intr_ops host1x_intr_ops
= {
110 .init_host_sync
= host1x_intr_init_host_sync
,
111 .set_syncpt_threshold
= host1x_intr_set_syncpt_threshold
,
112 .enable_syncpt_intr
= host1x_intr_enable_syncpt_intr
,
113 .disable_syncpt_intr
= host1x_intr_disable_syncpt_intr
,
114 .disable_all_syncpt_intrs
= host1x_intr_disable_all_syncpt_intrs
,
115 .isr
= syncpt_thresh_isr
,