Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
   1// SPDX-License-Identifier: GPL-2.0-only
   2/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
   3 */
   4
   5#include <linux/bitops.h>
   6#include <linux/slab.h>
   7
   8#include "dpu_kms.h"
   9#include "dpu_hw_interrupts.h"
  10#include "dpu_hw_util.h"
  11#include "dpu_hw_mdss.h"
  12
  13/**
  14 * Register offsets in MDSS register file for the interrupt registers
  15 * w.r.t. to the MDP base
  16 */
  17#define MDP_SSPP_TOP0_OFF		0x0
  18#define MDP_INTF_0_OFF			0x6A000
  19#define MDP_INTF_1_OFF			0x6A800
  20#define MDP_INTF_2_OFF			0x6B000
  21#define MDP_INTF_3_OFF			0x6B800
  22#define MDP_INTF_4_OFF			0x6C000
  23#define MDP_AD4_0_OFF			0x7C000
  24#define MDP_AD4_1_OFF			0x7D000
  25#define MDP_AD4_INTR_EN_OFF		0x41c
  26#define MDP_AD4_INTR_CLEAR_OFF		0x424
  27#define MDP_AD4_INTR_STATUS_OFF		0x420
  28
  29/**
  30 * WB interrupt status bit definitions
  31 */
  32#define DPU_INTR_WB_0_DONE BIT(0)
  33#define DPU_INTR_WB_1_DONE BIT(1)
  34#define DPU_INTR_WB_2_DONE BIT(4)
  35
  36/**
  37 * WDOG timer interrupt status bit definitions
  38 */
  39#define DPU_INTR_WD_TIMER_0_DONE BIT(2)
  40#define DPU_INTR_WD_TIMER_1_DONE BIT(3)
  41#define DPU_INTR_WD_TIMER_2_DONE BIT(5)
  42#define DPU_INTR_WD_TIMER_3_DONE BIT(6)
  43#define DPU_INTR_WD_TIMER_4_DONE BIT(7)
  44
  45/**
  46 * Pingpong interrupt status bit definitions
  47 */
  48#define DPU_INTR_PING_PONG_0_DONE BIT(8)
  49#define DPU_INTR_PING_PONG_1_DONE BIT(9)
  50#define DPU_INTR_PING_PONG_2_DONE BIT(10)
  51#define DPU_INTR_PING_PONG_3_DONE BIT(11)
  52#define DPU_INTR_PING_PONG_0_RD_PTR BIT(12)
  53#define DPU_INTR_PING_PONG_1_RD_PTR BIT(13)
  54#define DPU_INTR_PING_PONG_2_RD_PTR BIT(14)
  55#define DPU_INTR_PING_PONG_3_RD_PTR BIT(15)
  56#define DPU_INTR_PING_PONG_0_WR_PTR BIT(16)
  57#define DPU_INTR_PING_PONG_1_WR_PTR BIT(17)
  58#define DPU_INTR_PING_PONG_2_WR_PTR BIT(18)
  59#define DPU_INTR_PING_PONG_3_WR_PTR BIT(19)
  60#define DPU_INTR_PING_PONG_0_AUTOREFRESH_DONE BIT(20)
  61#define DPU_INTR_PING_PONG_1_AUTOREFRESH_DONE BIT(21)
  62#define DPU_INTR_PING_PONG_2_AUTOREFRESH_DONE BIT(22)
  63#define DPU_INTR_PING_PONG_3_AUTOREFRESH_DONE BIT(23)
  64
  65/**
  66 * Interface interrupt status bit definitions
  67 */
  68#define DPU_INTR_INTF_0_UNDERRUN BIT(24)
  69#define DPU_INTR_INTF_1_UNDERRUN BIT(26)
  70#define DPU_INTR_INTF_2_UNDERRUN BIT(28)
  71#define DPU_INTR_INTF_3_UNDERRUN BIT(30)
  72#define DPU_INTR_INTF_0_VSYNC BIT(25)
  73#define DPU_INTR_INTF_1_VSYNC BIT(27)
  74#define DPU_INTR_INTF_2_VSYNC BIT(29)
  75#define DPU_INTR_INTF_3_VSYNC BIT(31)
  76
  77/**
  78 * Pingpong Secondary interrupt status bit definitions
  79 */
  80#define DPU_INTR_PING_PONG_S0_AUTOREFRESH_DONE BIT(0)
  81#define DPU_INTR_PING_PONG_S0_WR_PTR BIT(4)
  82#define DPU_INTR_PING_PONG_S0_RD_PTR BIT(8)
  83#define DPU_INTR_PING_PONG_S0_TEAR_DETECTED BIT(22)
  84#define DPU_INTR_PING_PONG_S0_TE_DETECTED BIT(28)
  85
  86/**
  87 * Pingpong TEAR detection interrupt status bit definitions
  88 */
  89#define DPU_INTR_PING_PONG_0_TEAR_DETECTED BIT(16)
  90#define DPU_INTR_PING_PONG_1_TEAR_DETECTED BIT(17)
  91#define DPU_INTR_PING_PONG_2_TEAR_DETECTED BIT(18)
  92#define DPU_INTR_PING_PONG_3_TEAR_DETECTED BIT(19)
  93
  94/**
  95 * Pingpong TE detection interrupt status bit definitions
  96 */
  97#define DPU_INTR_PING_PONG_0_TE_DETECTED BIT(24)
  98#define DPU_INTR_PING_PONG_1_TE_DETECTED BIT(25)
  99#define DPU_INTR_PING_PONG_2_TE_DETECTED BIT(26)
 100#define DPU_INTR_PING_PONG_3_TE_DETECTED BIT(27)
 101
 102/**
 103 * Ctl start interrupt status bit definitions
 104 */
 105#define DPU_INTR_CTL_0_START BIT(9)
 106#define DPU_INTR_CTL_1_START BIT(10)
 107#define DPU_INTR_CTL_2_START BIT(11)
 108#define DPU_INTR_CTL_3_START BIT(12)
 109#define DPU_INTR_CTL_4_START BIT(13)
 110
 111/**
 112 * Concurrent WB overflow interrupt status bit definitions
 113 */
 114#define DPU_INTR_CWB_2_OVERFLOW BIT(14)
 115#define DPU_INTR_CWB_3_OVERFLOW BIT(15)
 116
 117/**
 118 * Histogram VIG done interrupt status bit definitions
 119 */
 120#define DPU_INTR_HIST_VIG_0_DONE BIT(0)
 121#define DPU_INTR_HIST_VIG_1_DONE BIT(4)
 122#define DPU_INTR_HIST_VIG_2_DONE BIT(8)
 123#define DPU_INTR_HIST_VIG_3_DONE BIT(10)
 124
 125/**
 126 * Histogram VIG reset Sequence done interrupt status bit definitions
 127 */
 128#define DPU_INTR_HIST_VIG_0_RSTSEQ_DONE BIT(1)
 129#define DPU_INTR_HIST_VIG_1_RSTSEQ_DONE BIT(5)
 130#define DPU_INTR_HIST_VIG_2_RSTSEQ_DONE BIT(9)
 131#define DPU_INTR_HIST_VIG_3_RSTSEQ_DONE BIT(11)
 132
 133/**
 134 * Histogram DSPP done interrupt status bit definitions
 135 */
 136#define DPU_INTR_HIST_DSPP_0_DONE BIT(12)
 137#define DPU_INTR_HIST_DSPP_1_DONE BIT(16)
 138#define DPU_INTR_HIST_DSPP_2_DONE BIT(20)
 139#define DPU_INTR_HIST_DSPP_3_DONE BIT(22)
 140
 141/**
 142 * Histogram DSPP reset Sequence done interrupt status bit definitions
 143 */
 144#define DPU_INTR_HIST_DSPP_0_RSTSEQ_DONE BIT(13)
 145#define DPU_INTR_HIST_DSPP_1_RSTSEQ_DONE BIT(17)
 146#define DPU_INTR_HIST_DSPP_2_RSTSEQ_DONE BIT(21)
 147#define DPU_INTR_HIST_DSPP_3_RSTSEQ_DONE BIT(23)
 148
 149/**
 150 * INTF interrupt status bit definitions
 151 */
 152#define DPU_INTR_VIDEO_INTO_STATIC BIT(0)
 153#define DPU_INTR_VIDEO_OUTOF_STATIC BIT(1)
 154#define DPU_INTR_DSICMD_0_INTO_STATIC BIT(2)
 155#define DPU_INTR_DSICMD_0_OUTOF_STATIC BIT(3)
 156#define DPU_INTR_DSICMD_1_INTO_STATIC BIT(4)
 157#define DPU_INTR_DSICMD_1_OUTOF_STATIC BIT(5)
 158#define DPU_INTR_DSICMD_2_INTO_STATIC BIT(6)
 159#define DPU_INTR_DSICMD_2_OUTOF_STATIC BIT(7)
 160#define DPU_INTR_PROG_LINE BIT(8)
 161
 162/**
 163 * AD4 interrupt status bit definitions
 164 */
 165#define DPU_INTR_BACKLIGHT_UPDATED BIT(0)
 166/**
 167 * struct dpu_intr_reg - array of DPU register sets
 168 * @clr_off:	offset to CLEAR reg
 169 * @en_off:	offset to ENABLE reg
 170 * @status_off:	offset to STATUS reg
 171 */
 172struct dpu_intr_reg {
 173	u32 clr_off;
 174	u32 en_off;
 175	u32 status_off;
 176};
 177
 178/**
 179 * struct dpu_irq_type - maps each irq with i/f
 180 * @intr_type:		type of interrupt listed in dpu_intr_type
 181 * @instance_idx:	instance index of the associated HW block in DPU
 182 * @irq_mask:		corresponding bit in the interrupt status reg
 183 * @reg_idx:		which reg set to use
 184 */
 185struct dpu_irq_type {
 186	u32 intr_type;
 187	u32 instance_idx;
 188	u32 irq_mask;
 189	u32 reg_idx;
 190};
 191
 192/**
 193 * List of DPU interrupt registers
 194 */
 195static const struct dpu_intr_reg dpu_intr_set[] = {
 196	{
 197		MDP_SSPP_TOP0_OFF+INTR_CLEAR,
 198		MDP_SSPP_TOP0_OFF+INTR_EN,
 199		MDP_SSPP_TOP0_OFF+INTR_STATUS
 200	},
 201	{
 202		MDP_SSPP_TOP0_OFF+INTR2_CLEAR,
 203		MDP_SSPP_TOP0_OFF+INTR2_EN,
 204		MDP_SSPP_TOP0_OFF+INTR2_STATUS
 205	},
 206	{
 207		MDP_SSPP_TOP0_OFF+HIST_INTR_CLEAR,
 208		MDP_SSPP_TOP0_OFF+HIST_INTR_EN,
 209		MDP_SSPP_TOP0_OFF+HIST_INTR_STATUS
 210	},
 211	{
 212		MDP_INTF_0_OFF+INTF_INTR_CLEAR,
 213		MDP_INTF_0_OFF+INTF_INTR_EN,
 214		MDP_INTF_0_OFF+INTF_INTR_STATUS
 215	},
 216	{
 217		MDP_INTF_1_OFF+INTF_INTR_CLEAR,
 218		MDP_INTF_1_OFF+INTF_INTR_EN,
 219		MDP_INTF_1_OFF+INTF_INTR_STATUS
 220	},
 221	{
 222		MDP_INTF_2_OFF+INTF_INTR_CLEAR,
 223		MDP_INTF_2_OFF+INTF_INTR_EN,
 224		MDP_INTF_2_OFF+INTF_INTR_STATUS
 225	},
 226	{
 227		MDP_INTF_3_OFF+INTF_INTR_CLEAR,
 228		MDP_INTF_3_OFF+INTF_INTR_EN,
 229		MDP_INTF_3_OFF+INTF_INTR_STATUS
 230	},
 231	{
 232		MDP_INTF_4_OFF+INTF_INTR_CLEAR,
 233		MDP_INTF_4_OFF+INTF_INTR_EN,
 234		MDP_INTF_4_OFF+INTF_INTR_STATUS
 235	},
 236	{
 237		MDP_AD4_0_OFF + MDP_AD4_INTR_CLEAR_OFF,
 238		MDP_AD4_0_OFF + MDP_AD4_INTR_EN_OFF,
 239		MDP_AD4_0_OFF + MDP_AD4_INTR_STATUS_OFF,
 240	},
 241	{
 242		MDP_AD4_1_OFF + MDP_AD4_INTR_CLEAR_OFF,
 243		MDP_AD4_1_OFF + MDP_AD4_INTR_EN_OFF,
 244		MDP_AD4_1_OFF + MDP_AD4_INTR_STATUS_OFF,
 245	}
 246};
 247
 248/**
 249 * IRQ mapping table - use for lookup an irq_idx in this table that have
 250 *                     a matching interface type and instance index.
 251 */
 252static const struct dpu_irq_type dpu_irq_map[] = {
 253	/* BEGIN MAP_RANGE: 0-31, INTR */
 254	/* irq_idx: 0-3 */
 255	{ DPU_IRQ_TYPE_WB_ROT_COMP, WB_0, DPU_INTR_WB_0_DONE, 0},
 256	{ DPU_IRQ_TYPE_WB_ROT_COMP, WB_1, DPU_INTR_WB_1_DONE, 0},
 257	{ DPU_IRQ_TYPE_WD_TIMER, WD_TIMER_0, DPU_INTR_WD_TIMER_0_DONE, 0},
 258	{ DPU_IRQ_TYPE_WD_TIMER, WD_TIMER_1, DPU_INTR_WD_TIMER_1_DONE, 0},
 259	/* irq_idx: 4-7 */
 260	{ DPU_IRQ_TYPE_WB_WFD_COMP, WB_2, DPU_INTR_WB_2_DONE, 0},
 261	{ DPU_IRQ_TYPE_WD_TIMER, WD_TIMER_2, DPU_INTR_WD_TIMER_2_DONE, 0},
 262	{ DPU_IRQ_TYPE_WD_TIMER, WD_TIMER_3, DPU_INTR_WD_TIMER_3_DONE, 0},
 263	{ DPU_IRQ_TYPE_WD_TIMER, WD_TIMER_4, DPU_INTR_WD_TIMER_4_DONE, 0},
 264	/* irq_idx: 8-11 */
 265	{ DPU_IRQ_TYPE_PING_PONG_COMP, PINGPONG_0,
 266		DPU_INTR_PING_PONG_0_DONE, 0},
 267	{ DPU_IRQ_TYPE_PING_PONG_COMP, PINGPONG_1,
 268		DPU_INTR_PING_PONG_1_DONE, 0},
 269	{ DPU_IRQ_TYPE_PING_PONG_COMP, PINGPONG_2,
 270		DPU_INTR_PING_PONG_2_DONE, 0},
 271	{ DPU_IRQ_TYPE_PING_PONG_COMP, PINGPONG_3,
 272		DPU_INTR_PING_PONG_3_DONE, 0},
 273	/* irq_idx: 12-15 */
 274	{ DPU_IRQ_TYPE_PING_PONG_RD_PTR, PINGPONG_0,
 275		DPU_INTR_PING_PONG_0_RD_PTR, 0},
 276	{ DPU_IRQ_TYPE_PING_PONG_RD_PTR, PINGPONG_1,
 277		DPU_INTR_PING_PONG_1_RD_PTR, 0},
 278	{ DPU_IRQ_TYPE_PING_PONG_RD_PTR, PINGPONG_2,
 279		DPU_INTR_PING_PONG_2_RD_PTR, 0},
 280	{ DPU_IRQ_TYPE_PING_PONG_RD_PTR, PINGPONG_3,
 281		DPU_INTR_PING_PONG_3_RD_PTR, 0},
 282	/* irq_idx: 16-19 */
 283	{ DPU_IRQ_TYPE_PING_PONG_WR_PTR, PINGPONG_0,
 284		DPU_INTR_PING_PONG_0_WR_PTR, 0},
 285	{ DPU_IRQ_TYPE_PING_PONG_WR_PTR, PINGPONG_1,
 286		DPU_INTR_PING_PONG_1_WR_PTR, 0},
 287	{ DPU_IRQ_TYPE_PING_PONG_WR_PTR, PINGPONG_2,
 288		DPU_INTR_PING_PONG_2_WR_PTR, 0},
 289	{ DPU_IRQ_TYPE_PING_PONG_WR_PTR, PINGPONG_3,
 290		DPU_INTR_PING_PONG_3_WR_PTR, 0},
 291	/* irq_idx: 20-23 */
 292	{ DPU_IRQ_TYPE_PING_PONG_AUTO_REF, PINGPONG_0,
 293		DPU_INTR_PING_PONG_0_AUTOREFRESH_DONE, 0},
 294	{ DPU_IRQ_TYPE_PING_PONG_AUTO_REF, PINGPONG_1,
 295		DPU_INTR_PING_PONG_1_AUTOREFRESH_DONE, 0},
 296	{ DPU_IRQ_TYPE_PING_PONG_AUTO_REF, PINGPONG_2,
 297		DPU_INTR_PING_PONG_2_AUTOREFRESH_DONE, 0},
 298	{ DPU_IRQ_TYPE_PING_PONG_AUTO_REF, PINGPONG_3,
 299		DPU_INTR_PING_PONG_3_AUTOREFRESH_DONE, 0},
 300	/* irq_idx: 24-27 */
 301	{ DPU_IRQ_TYPE_INTF_UNDER_RUN, INTF_0, DPU_INTR_INTF_0_UNDERRUN, 0},
 302	{ DPU_IRQ_TYPE_INTF_VSYNC, INTF_0, DPU_INTR_INTF_0_VSYNC, 0},
 303	{ DPU_IRQ_TYPE_INTF_UNDER_RUN, INTF_1, DPU_INTR_INTF_1_UNDERRUN, 0},
 304	{ DPU_IRQ_TYPE_INTF_VSYNC, INTF_1, DPU_INTR_INTF_1_VSYNC, 0},
 305	/* irq_idx: 28-31 */
 306	{ DPU_IRQ_TYPE_INTF_UNDER_RUN, INTF_2, DPU_INTR_INTF_2_UNDERRUN, 0},
 307	{ DPU_IRQ_TYPE_INTF_VSYNC, INTF_2, DPU_INTR_INTF_2_VSYNC, 0},
 308	{ DPU_IRQ_TYPE_INTF_UNDER_RUN, INTF_3, DPU_INTR_INTF_3_UNDERRUN, 0},
 309	{ DPU_IRQ_TYPE_INTF_VSYNC, INTF_3, DPU_INTR_INTF_3_VSYNC, 0},
 310
 311	/* BEGIN MAP_RANGE: 32-64, INTR2 */
 312	/* irq_idx: 32-35 */
 313	{ DPU_IRQ_TYPE_PING_PONG_AUTO_REF, PINGPONG_S0,
 314		DPU_INTR_PING_PONG_S0_AUTOREFRESH_DONE, 1},
 315	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 1},
 316	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 1},
 317	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 1},
 318	/* irq_idx: 36-39 */
 319	{ DPU_IRQ_TYPE_PING_PONG_WR_PTR, PINGPONG_S0,
 320		DPU_INTR_PING_PONG_S0_WR_PTR, 1},
 321	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 1},
 322	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 1},
 323	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 1},
 324	/* irq_idx: 40 */
 325	{ DPU_IRQ_TYPE_PING_PONG_RD_PTR, PINGPONG_S0,
 326		DPU_INTR_PING_PONG_S0_RD_PTR, 1},
 327	/* irq_idx: 41-45 */
 328	{ DPU_IRQ_TYPE_CTL_START, CTL_0,
 329		DPU_INTR_CTL_0_START, 1},
 330	{ DPU_IRQ_TYPE_CTL_START, CTL_1,
 331		DPU_INTR_CTL_1_START, 1},
 332	{ DPU_IRQ_TYPE_CTL_START, CTL_2,
 333		DPU_INTR_CTL_2_START, 1},
 334	{ DPU_IRQ_TYPE_CTL_START, CTL_3,
 335		DPU_INTR_CTL_3_START, 1},
 336	{ DPU_IRQ_TYPE_CTL_START, CTL_4,
 337		DPU_INTR_CTL_4_START, 1},
 338	/* irq_idx: 46-47 */
 339	{ DPU_IRQ_TYPE_CWB_OVERFLOW, CWB_2, DPU_INTR_CWB_2_OVERFLOW, 1},
 340	{ DPU_IRQ_TYPE_CWB_OVERFLOW, CWB_3, DPU_INTR_CWB_3_OVERFLOW, 1},
 341	/* irq_idx: 48-51 */
 342	{ DPU_IRQ_TYPE_PING_PONG_TEAR_CHECK, PINGPONG_0,
 343		DPU_INTR_PING_PONG_0_TEAR_DETECTED, 1},
 344	{ DPU_IRQ_TYPE_PING_PONG_TEAR_CHECK, PINGPONG_1,
 345		DPU_INTR_PING_PONG_1_TEAR_DETECTED, 1},
 346	{ DPU_IRQ_TYPE_PING_PONG_TEAR_CHECK, PINGPONG_2,
 347		DPU_INTR_PING_PONG_2_TEAR_DETECTED, 1},
 348	{ DPU_IRQ_TYPE_PING_PONG_TEAR_CHECK, PINGPONG_3,
 349		DPU_INTR_PING_PONG_3_TEAR_DETECTED, 1},
 350	/* irq_idx: 52-55 */
 351	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 1},
 352	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 1},
 353	{ DPU_IRQ_TYPE_PING_PONG_TEAR_CHECK, PINGPONG_S0,
 354		DPU_INTR_PING_PONG_S0_TEAR_DETECTED, 1},
 355	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 1},
 356	/* irq_idx: 56-59 */
 357	{ DPU_IRQ_TYPE_PING_PONG_TE_CHECK, PINGPONG_0,
 358		DPU_INTR_PING_PONG_0_TE_DETECTED, 1},
 359	{ DPU_IRQ_TYPE_PING_PONG_TE_CHECK, PINGPONG_1,
 360		DPU_INTR_PING_PONG_1_TE_DETECTED, 1},
 361	{ DPU_IRQ_TYPE_PING_PONG_TE_CHECK, PINGPONG_2,
 362		DPU_INTR_PING_PONG_2_TE_DETECTED, 1},
 363	{ DPU_IRQ_TYPE_PING_PONG_TE_CHECK, PINGPONG_3,
 364		DPU_INTR_PING_PONG_3_TE_DETECTED, 1},
 365	/* irq_idx: 60-63 */
 366	{ DPU_IRQ_TYPE_PING_PONG_TE_CHECK, PINGPONG_S0,
 367		DPU_INTR_PING_PONG_S0_TE_DETECTED, 1},
 368	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 1},
 369	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 1},
 370	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 1},
 371
 372	/* BEGIN MAP_RANGE: 64-95 HIST */
 373	/* irq_idx: 64-67 */
 374	{ DPU_IRQ_TYPE_HIST_VIG_DONE, SSPP_VIG0, DPU_INTR_HIST_VIG_0_DONE, 2},
 375	{ DPU_IRQ_TYPE_HIST_VIG_RSTSEQ, SSPP_VIG0,
 376		DPU_INTR_HIST_VIG_0_RSTSEQ_DONE, 2},
 377	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
 378	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
 379	/* irq_idx: 68-71 */
 380	{ DPU_IRQ_TYPE_HIST_VIG_DONE, SSPP_VIG1, DPU_INTR_HIST_VIG_1_DONE, 2},
 381	{ DPU_IRQ_TYPE_HIST_VIG_RSTSEQ, SSPP_VIG1,
 382		DPU_INTR_HIST_VIG_1_RSTSEQ_DONE, 2},
 383	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
 384	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
 385	/* irq_idx: 72-75 */
 386	{ DPU_IRQ_TYPE_HIST_VIG_DONE, SSPP_VIG2, DPU_INTR_HIST_VIG_2_DONE, 2},
 387	{ DPU_IRQ_TYPE_HIST_VIG_RSTSEQ, SSPP_VIG2,
 388		DPU_INTR_HIST_VIG_2_RSTSEQ_DONE, 2},
 389	{ DPU_IRQ_TYPE_HIST_VIG_DONE, SSPP_VIG3, DPU_INTR_HIST_VIG_3_DONE, 2},
 390	{ DPU_IRQ_TYPE_HIST_VIG_RSTSEQ, SSPP_VIG3,
 391		DPU_INTR_HIST_VIG_3_RSTSEQ_DONE, 2},
 392	/* irq_idx: 76-79 */
 393	{ DPU_IRQ_TYPE_HIST_DSPP_DONE, DSPP_0, DPU_INTR_HIST_DSPP_0_DONE, 2},
 394	{ DPU_IRQ_TYPE_HIST_DSPP_RSTSEQ, DSPP_0,
 395		DPU_INTR_HIST_DSPP_0_RSTSEQ_DONE, 2},
 396	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
 397	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
 398	/* irq_idx: 80-83 */
 399	{ DPU_IRQ_TYPE_HIST_DSPP_DONE, DSPP_1, DPU_INTR_HIST_DSPP_1_DONE, 2},
 400	{ DPU_IRQ_TYPE_HIST_DSPP_RSTSEQ, DSPP_1,
 401		DPU_INTR_HIST_DSPP_1_RSTSEQ_DONE, 2},
 402	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
 403	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
 404	/* irq_idx: 84-87 */
 405	{ DPU_IRQ_TYPE_HIST_DSPP_DONE, DSPP_2, DPU_INTR_HIST_DSPP_2_DONE, 2},
 406	{ DPU_IRQ_TYPE_HIST_DSPP_RSTSEQ, DSPP_2,
 407		DPU_INTR_HIST_DSPP_2_RSTSEQ_DONE, 2},
 408	{ DPU_IRQ_TYPE_HIST_DSPP_DONE, DSPP_3, DPU_INTR_HIST_DSPP_3_DONE, 2},
 409	{ DPU_IRQ_TYPE_HIST_DSPP_RSTSEQ, DSPP_3,
 410		DPU_INTR_HIST_DSPP_3_RSTSEQ_DONE, 2},
 411	/* irq_idx: 88-91 */
 412	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
 413	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
 414	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
 415	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
 416	/* irq_idx: 92-95 */
 417	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
 418	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
 419	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
 420	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
 421
 422	/* BEGIN MAP_RANGE: 96-127 INTF_0_INTR */
 423	/* irq_idx: 96-99 */
 424	{ DPU_IRQ_TYPE_SFI_VIDEO_IN, INTF_0,
 425		DPU_INTR_VIDEO_INTO_STATIC, 3},
 426	{ DPU_IRQ_TYPE_SFI_VIDEO_OUT, INTF_0,
 427		DPU_INTR_VIDEO_OUTOF_STATIC, 3},
 428	{ DPU_IRQ_TYPE_SFI_CMD_0_IN, INTF_0,
 429		DPU_INTR_DSICMD_0_INTO_STATIC, 3},
 430	{ DPU_IRQ_TYPE_SFI_CMD_0_OUT, INTF_0,
 431		DPU_INTR_DSICMD_0_OUTOF_STATIC, 3},
 432	/* irq_idx: 100-103 */
 433	{ DPU_IRQ_TYPE_SFI_CMD_1_IN, INTF_0,
 434		DPU_INTR_DSICMD_1_INTO_STATIC, 3},
 435	{ DPU_IRQ_TYPE_SFI_CMD_1_OUT, INTF_0,
 436		DPU_INTR_DSICMD_1_OUTOF_STATIC, 3},
 437	{ DPU_IRQ_TYPE_SFI_CMD_2_IN, INTF_0,
 438		DPU_INTR_DSICMD_2_INTO_STATIC, 3},
 439	{ DPU_IRQ_TYPE_SFI_CMD_2_OUT, INTF_0,
 440		DPU_INTR_DSICMD_2_OUTOF_STATIC, 3},
 441	/* irq_idx: 104-107 */
 442	{ DPU_IRQ_TYPE_PROG_LINE, INTF_0, DPU_INTR_PROG_LINE, 3},
 443	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
 444	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
 445	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
 446	/* irq_idx: 108-111 */
 447	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
 448	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
 449	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
 450	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
 451	/* irq_idx: 112-115 */
 452	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
 453	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
 454	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
 455	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
 456	/* irq_idx: 116-119 */
 457	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
 458	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
 459	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
 460	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
 461	/* irq_idx: 120-123 */
 462	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
 463	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
 464	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
 465	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
 466	/* irq_idx: 124-127 */
 467	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
 468	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
 469	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
 470	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
 471
 472	/* BEGIN MAP_RANGE: 128-159 INTF_1_INTR */
 473	/* irq_idx: 128-131 */
 474	{ DPU_IRQ_TYPE_SFI_VIDEO_IN, INTF_1,
 475		DPU_INTR_VIDEO_INTO_STATIC, 4},
 476	{ DPU_IRQ_TYPE_SFI_VIDEO_OUT, INTF_1,
 477		DPU_INTR_VIDEO_OUTOF_STATIC, 4},
 478	{ DPU_IRQ_TYPE_SFI_CMD_0_IN, INTF_1,
 479		DPU_INTR_DSICMD_0_INTO_STATIC, 4},
 480	{ DPU_IRQ_TYPE_SFI_CMD_0_OUT, INTF_1,
 481		DPU_INTR_DSICMD_0_OUTOF_STATIC, 4},
 482	/* irq_idx: 132-135 */
 483	{ DPU_IRQ_TYPE_SFI_CMD_1_IN, INTF_1,
 484		DPU_INTR_DSICMD_1_INTO_STATIC, 4},
 485	{ DPU_IRQ_TYPE_SFI_CMD_1_OUT, INTF_1,
 486		DPU_INTR_DSICMD_1_OUTOF_STATIC, 4},
 487	{ DPU_IRQ_TYPE_SFI_CMD_2_IN, INTF_1,
 488		DPU_INTR_DSICMD_2_INTO_STATIC, 4},
 489	{ DPU_IRQ_TYPE_SFI_CMD_2_OUT, INTF_1,
 490		DPU_INTR_DSICMD_2_OUTOF_STATIC, 4},
 491	/* irq_idx: 136-139 */
 492	{ DPU_IRQ_TYPE_PROG_LINE, INTF_1, DPU_INTR_PROG_LINE, 4},
 493	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
 494	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
 495	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
 496	/* irq_idx: 140-143 */
 497	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
 498	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
 499	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
 500	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
 501	/* irq_idx: 144-147 */
 502	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
 503	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
 504	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
 505	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
 506	/* irq_idx: 148-151 */
 507	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
 508	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
 509	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
 510	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
 511	/* irq_idx: 152-155 */
 512	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
 513	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
 514	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
 515	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
 516	/* irq_idx: 156-159 */
 517	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
 518	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
 519	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
 520	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
 521
 522	/* BEGIN MAP_RANGE: 160-191 INTF_2_INTR */
 523	/* irq_idx: 160-163 */
 524	{ DPU_IRQ_TYPE_SFI_VIDEO_IN, INTF_2,
 525		DPU_INTR_VIDEO_INTO_STATIC, 5},
 526	{ DPU_IRQ_TYPE_SFI_VIDEO_OUT, INTF_2,
 527		DPU_INTR_VIDEO_OUTOF_STATIC, 5},
 528	{ DPU_IRQ_TYPE_SFI_CMD_0_IN, INTF_2,
 529		DPU_INTR_DSICMD_0_INTO_STATIC, 5},
 530	{ DPU_IRQ_TYPE_SFI_CMD_0_OUT, INTF_2,
 531		DPU_INTR_DSICMD_0_OUTOF_STATIC, 5},
 532	/* irq_idx: 164-167 */
 533	{ DPU_IRQ_TYPE_SFI_CMD_1_IN, INTF_2,
 534		DPU_INTR_DSICMD_1_INTO_STATIC, 5},
 535	{ DPU_IRQ_TYPE_SFI_CMD_1_OUT, INTF_2,
 536		DPU_INTR_DSICMD_1_OUTOF_STATIC, 5},
 537	{ DPU_IRQ_TYPE_SFI_CMD_2_IN, INTF_2,
 538		DPU_INTR_DSICMD_2_INTO_STATIC, 5},
 539	{ DPU_IRQ_TYPE_SFI_CMD_2_OUT, INTF_2,
 540		DPU_INTR_DSICMD_2_OUTOF_STATIC, 5},
 541	/* irq_idx: 168-171 */
 542	{ DPU_IRQ_TYPE_PROG_LINE, INTF_2, DPU_INTR_PROG_LINE, 5},
 543	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
 544	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
 545	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
 546	/* irq_idx: 172-175 */
 547	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
 548	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
 549	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
 550	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
 551	/* irq_idx: 176-179 */
 552	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
 553	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
 554	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
 555	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
 556	/* irq_idx: 180-183 */
 557	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
 558	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
 559	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
 560	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
 561	/* irq_idx: 184-187 */
 562	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
 563	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
 564	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
 565	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
 566	/* irq_idx: 188-191 */
 567	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
 568	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
 569	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
 570	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
 571
 572	/* BEGIN MAP_RANGE: 192-223 INTF_3_INTR */
 573	/* irq_idx: 192-195 */
 574	{ DPU_IRQ_TYPE_SFI_VIDEO_IN, INTF_3,
 575		DPU_INTR_VIDEO_INTO_STATIC, 6},
 576	{ DPU_IRQ_TYPE_SFI_VIDEO_OUT, INTF_3,
 577		DPU_INTR_VIDEO_OUTOF_STATIC, 6},
 578	{ DPU_IRQ_TYPE_SFI_CMD_0_IN, INTF_3,
 579		DPU_INTR_DSICMD_0_INTO_STATIC, 6},
 580	{ DPU_IRQ_TYPE_SFI_CMD_0_OUT, INTF_3,
 581		DPU_INTR_DSICMD_0_OUTOF_STATIC, 6},
 582	/* irq_idx: 196-199 */
 583	{ DPU_IRQ_TYPE_SFI_CMD_1_IN, INTF_3,
 584		DPU_INTR_DSICMD_1_INTO_STATIC, 6},
 585	{ DPU_IRQ_TYPE_SFI_CMD_1_OUT, INTF_3,
 586		DPU_INTR_DSICMD_1_OUTOF_STATIC, 6},
 587	{ DPU_IRQ_TYPE_SFI_CMD_2_IN, INTF_3,
 588		DPU_INTR_DSICMD_2_INTO_STATIC, 6},
 589	{ DPU_IRQ_TYPE_SFI_CMD_2_OUT, INTF_3,
 590		DPU_INTR_DSICMD_2_OUTOF_STATIC, 6},
 591	/* irq_idx: 200-203 */
 592	{ DPU_IRQ_TYPE_PROG_LINE, INTF_3, DPU_INTR_PROG_LINE, 6},
 593	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
 594	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
 595	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
 596	/* irq_idx: 204-207 */
 597	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
 598	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
 599	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
 600	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
 601	/* irq_idx: 208-211 */
 602	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
 603	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
 604	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
 605	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
 606	/* irq_idx: 212-215 */
 607	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
 608	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
 609	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
 610	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
 611	/* irq_idx: 216-219 */
 612	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
 613	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
 614	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
 615	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
 616	/* irq_idx: 220-223 */
 617	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
 618	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
 619	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
 620	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
 621
 622	/* BEGIN MAP_RANGE: 224-255 INTF_4_INTR */
 623	/* irq_idx: 224-227 */
 624	{ DPU_IRQ_TYPE_SFI_VIDEO_IN, INTF_4,
 625		DPU_INTR_VIDEO_INTO_STATIC, 7},
 626	{ DPU_IRQ_TYPE_SFI_VIDEO_OUT, INTF_4,
 627		DPU_INTR_VIDEO_OUTOF_STATIC, 7},
 628	{ DPU_IRQ_TYPE_SFI_CMD_0_IN, INTF_4,
 629		DPU_INTR_DSICMD_0_INTO_STATIC, 7},
 630	{ DPU_IRQ_TYPE_SFI_CMD_0_OUT, INTF_4,
 631		DPU_INTR_DSICMD_0_OUTOF_STATIC, 7},
 632	/* irq_idx: 228-231 */
 633	{ DPU_IRQ_TYPE_SFI_CMD_1_IN, INTF_4,
 634		DPU_INTR_DSICMD_1_INTO_STATIC, 7},
 635	{ DPU_IRQ_TYPE_SFI_CMD_1_OUT, INTF_4,
 636		DPU_INTR_DSICMD_1_OUTOF_STATIC, 7},
 637	{ DPU_IRQ_TYPE_SFI_CMD_2_IN, INTF_4,
 638		DPU_INTR_DSICMD_2_INTO_STATIC, 7},
 639	{ DPU_IRQ_TYPE_SFI_CMD_2_OUT, INTF_4,
 640		DPU_INTR_DSICMD_2_OUTOF_STATIC, 7},
 641	/* irq_idx: 232-235 */
 642	{ DPU_IRQ_TYPE_PROG_LINE, INTF_4, DPU_INTR_PROG_LINE, 7},
 643	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
 644	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
 645	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
 646	/* irq_idx: 236-239 */
 647	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
 648	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
 649	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
 650	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
 651	/* irq_idx: 240-243 */
 652	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
 653	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
 654	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
 655	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
 656	/* irq_idx: 244-247 */
 657	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
 658	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
 659	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
 660	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
 661	/* irq_idx: 248-251 */
 662	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
 663	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
 664	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
 665	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
 666	/* irq_idx: 252-255 */
 667	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
 668	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
 669	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
 670	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
 671
 672	/* BEGIN MAP_RANGE: 256-287 AD4_0_INTR */
 673	/* irq_idx: 256-259 */
 674	{ DPU_IRQ_TYPE_AD4_BL_DONE, DSPP_0, DPU_INTR_BACKLIGHT_UPDATED, 8},
 675	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 676	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 677	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 678	/* irq_idx: 260-263 */
 679	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 680	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 681	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 682	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 683	/* irq_idx: 264-267 */
 684	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 685	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 686	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 687	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 688	/* irq_idx: 268-271 */
 689	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 690	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 691	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 692	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 693	/* irq_idx: 272-275 */
 694	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 695	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 696	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 697	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 698	/* irq_idx: 276-279 */
 699	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 700	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 701	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 702	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 703	/* irq_idx: 280-283 */
 704	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 705	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 706	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 707	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 708	/* irq_idx: 284-287 */
 709	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 710	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 711	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 712	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
 713
 714	/* BEGIN MAP_RANGE: 288-319 AD4_1_INTR */
 715	/* irq_idx: 288-291 */
 716	{ DPU_IRQ_TYPE_AD4_BL_DONE, DSPP_1, DPU_INTR_BACKLIGHT_UPDATED, 9},
 717	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 718	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 719	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 720	/* irq_idx: 292-295 */
 721	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 722	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 723	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 724	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 725	/* irq_idx: 296-299 */
 726	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 727	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 728	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 729	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 730	/* irq_idx: 300-303 */
 731	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 732	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 733	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 734	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 735	/* irq_idx: 304-307 */
 736	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 737	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 738	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 739	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 740	/* irq_idx: 308-311 */
 741	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 742	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 743	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 744	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 745	/* irq_idx: 312-315 */
 746	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 747	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 748	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 749	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 750	/* irq_idx: 315-319 */
 751	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 752	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 753	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 754	{ DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
 755};
 756
 757static int dpu_hw_intr_irqidx_lookup(enum dpu_intr_type intr_type,
 758		u32 instance_idx)
 759{
 760	int i;
 761
 762	for (i = 0; i < ARRAY_SIZE(dpu_irq_map); i++) {
 763		if (intr_type == dpu_irq_map[i].intr_type &&
 764			instance_idx == dpu_irq_map[i].instance_idx)
 765			return i;
 766	}
 767
 768	pr_debug("IRQ lookup fail!! intr_type=%d, instance_idx=%d\n",
 769			intr_type, instance_idx);
 770	return -EINVAL;
 771}
 772
 773static void dpu_hw_intr_dispatch_irq(struct dpu_hw_intr *intr,
 774		void (*cbfunc)(void *, int),
 775		void *arg)
 776{
 777	int reg_idx;
 778	int irq_idx;
 779	int start_idx;
 780	int end_idx;
 781	u32 irq_status;
 782	unsigned long irq_flags;
 783
 784	if (!intr)
 785		return;
 786
 787	/*
 788	 * The dispatcher will save the IRQ status before calling here.
 789	 * Now need to go through each IRQ status and find matching
 790	 * irq lookup index.
 791	 */
 792	spin_lock_irqsave(&intr->irq_lock, irq_flags);
 793	for (reg_idx = 0; reg_idx < ARRAY_SIZE(dpu_intr_set); reg_idx++) {
 794		irq_status = intr->save_irq_status[reg_idx];
 795
 796		/*
 797		 * Each Interrupt register has a range of 32 indexes, and
 798		 * that is static for dpu_irq_map.
 799		 */
 800		start_idx = reg_idx * 32;
 801		end_idx = start_idx + 32;
 802
 803		if (!test_bit(reg_idx, &intr->irq_mask) ||
 804			start_idx >= ARRAY_SIZE(dpu_irq_map))
 805			continue;
 806
 807		/*
 808		 * Search through matching intr status from irq map.
 809		 * start_idx and end_idx defined the search range in
 810		 * the dpu_irq_map.
 811		 */
 812		for (irq_idx = start_idx;
 813				(irq_idx < end_idx) && irq_status;
 814				irq_idx++)
 815			if ((irq_status & dpu_irq_map[irq_idx].irq_mask) &&
 816				(dpu_irq_map[irq_idx].reg_idx == reg_idx)) {
 817				/*
 818				 * Once a match on irq mask, perform a callback
 819				 * to the given cbfunc. cbfunc will take care
 820				 * the interrupt status clearing. If cbfunc is
 821				 * not provided, then the interrupt clearing
 822				 * is here.
 823				 */
 824				if (cbfunc)
 825					cbfunc(arg, irq_idx);
 826				else
 827					intr->ops.clear_intr_status_nolock(
 828							intr, irq_idx);
 829
 830				/*
 831				 * When callback finish, clear the irq_status
 832				 * with the matching mask. Once irq_status
 833				 * is all cleared, the search can be stopped.
 834				 */
 835				irq_status &= ~dpu_irq_map[irq_idx].irq_mask;
 836			}
 837	}
 838	spin_unlock_irqrestore(&intr->irq_lock, irq_flags);
 839}
 840
 841static int dpu_hw_intr_enable_irq(struct dpu_hw_intr *intr, int irq_idx)
 842{
 843	int reg_idx;
 844	unsigned long irq_flags;
 845	const struct dpu_intr_reg *reg;
 846	const struct dpu_irq_type *irq;
 847	const char *dbgstr = NULL;
 848	uint32_t cache_irq_mask;
 849
 850	if (!intr)
 851		return -EINVAL;
 852
 853	if (irq_idx < 0 || irq_idx >= ARRAY_SIZE(dpu_irq_map)) {
 854		pr_err("invalid IRQ index: [%d]\n", irq_idx);
 855		return -EINVAL;
 856	}
 857
 858	irq = &dpu_irq_map[irq_idx];
 859	reg_idx = irq->reg_idx;
 860	reg = &dpu_intr_set[reg_idx];
 861
 862	spin_lock_irqsave(&intr->irq_lock, irq_flags);
 863	cache_irq_mask = intr->cache_irq_mask[reg_idx];
 864	if (cache_irq_mask & irq->irq_mask) {
 865		dbgstr = "DPU IRQ already set:";
 866	} else {
 867		dbgstr = "DPU IRQ enabled:";
 868
 869		cache_irq_mask |= irq->irq_mask;
 870		/* Cleaning any pending interrupt */
 871		DPU_REG_WRITE(&intr->hw, reg->clr_off, irq->irq_mask);
 872		/* Enabling interrupts with the new mask */
 873		DPU_REG_WRITE(&intr->hw, reg->en_off, cache_irq_mask);
 874
 875		/* ensure register write goes through */
 876		wmb();
 877
 878		intr->cache_irq_mask[reg_idx] = cache_irq_mask;
 879	}
 880	spin_unlock_irqrestore(&intr->irq_lock, irq_flags);
 881
 882	pr_debug("%s MASK:0x%.8x, CACHE-MASK:0x%.8x\n", dbgstr,
 883			irq->irq_mask, cache_irq_mask);
 884
 885	return 0;
 886}
 887
 888static int dpu_hw_intr_disable_irq_nolock(struct dpu_hw_intr *intr, int irq_idx)
 889{
 890	int reg_idx;
 891	const struct dpu_intr_reg *reg;
 892	const struct dpu_irq_type *irq;
 893	const char *dbgstr = NULL;
 894	uint32_t cache_irq_mask;
 895
 896	if (!intr)
 897		return -EINVAL;
 898
 899	if (irq_idx < 0 || irq_idx >= ARRAY_SIZE(dpu_irq_map)) {
 900		pr_err("invalid IRQ index: [%d]\n", irq_idx);
 901		return -EINVAL;
 902	}
 903
 904	irq = &dpu_irq_map[irq_idx];
 905	reg_idx = irq->reg_idx;
 906	reg = &dpu_intr_set[reg_idx];
 907
 908	cache_irq_mask = intr->cache_irq_mask[reg_idx];
 909	if ((cache_irq_mask & irq->irq_mask) == 0) {
 910		dbgstr = "DPU IRQ is already cleared:";
 911	} else {
 912		dbgstr = "DPU IRQ mask disable:";
 913
 914		cache_irq_mask &= ~irq->irq_mask;
 915		/* Disable interrupts based on the new mask */
 916		DPU_REG_WRITE(&intr->hw, reg->en_off, cache_irq_mask);
 917		/* Cleaning any pending interrupt */
 918		DPU_REG_WRITE(&intr->hw, reg->clr_off, irq->irq_mask);
 919
 920		/* ensure register write goes through */
 921		wmb();
 922
 923		intr->cache_irq_mask[reg_idx] = cache_irq_mask;
 924	}
 925
 926	pr_debug("%s MASK:0x%.8x, CACHE-MASK:0x%.8x\n", dbgstr,
 927			irq->irq_mask, cache_irq_mask);
 928
 929	return 0;
 930}
 931
 932static int dpu_hw_intr_disable_irq(struct dpu_hw_intr *intr, int irq_idx)
 933{
 934	unsigned long irq_flags;
 935
 936	if (!intr)
 937		return -EINVAL;
 938
 939	if (irq_idx < 0 || irq_idx >= ARRAY_SIZE(dpu_irq_map)) {
 940		pr_err("invalid IRQ index: [%d]\n", irq_idx);
 941		return -EINVAL;
 942	}
 943
 944	spin_lock_irqsave(&intr->irq_lock, irq_flags);
 945	dpu_hw_intr_disable_irq_nolock(intr, irq_idx);
 946	spin_unlock_irqrestore(&intr->irq_lock, irq_flags);
 947
 948	return 0;
 949}
 950
 951static int dpu_hw_intr_clear_irqs(struct dpu_hw_intr *intr)
 952{
 953	int i;
 954
 955	if (!intr)
 956		return -EINVAL;
 957
 958	for (i = 0; i < ARRAY_SIZE(dpu_intr_set); i++) {
 959		if (test_bit(i, &intr->irq_mask))
 960			DPU_REG_WRITE(&intr->hw,
 961					dpu_intr_set[i].clr_off, 0xffffffff);
 962	}
 963
 964	/* ensure register writes go through */
 965	wmb();
 966
 967	return 0;
 968}
 969
 970static int dpu_hw_intr_disable_irqs(struct dpu_hw_intr *intr)
 971{
 972	int i;
 973
 974	if (!intr)
 975		return -EINVAL;
 976
 977	for (i = 0; i < ARRAY_SIZE(dpu_intr_set); i++) {
 978		if (test_bit(i, &intr->irq_mask))
 979			DPU_REG_WRITE(&intr->hw,
 980					dpu_intr_set[i].en_off, 0x00000000);
 981	}
 982
 983	/* ensure register writes go through */
 984	wmb();
 985
 986	return 0;
 987}
 988
 989static void dpu_hw_intr_get_interrupt_statuses(struct dpu_hw_intr *intr)
 990{
 991	int i;
 992	u32 enable_mask;
 993	unsigned long irq_flags;
 994
 995	if (!intr)
 996		return;
 997
 998	spin_lock_irqsave(&intr->irq_lock, irq_flags);
 999	for (i = 0; i < ARRAY_SIZE(dpu_intr_set); i++) {
1000		if (!test_bit(i, &intr->irq_mask))
1001			continue;
1002
1003		/* Read interrupt status */
1004		intr->save_irq_status[i] = DPU_REG_READ(&intr->hw,
1005				dpu_intr_set[i].status_off);
1006
1007		/* Read enable mask */
1008		enable_mask = DPU_REG_READ(&intr->hw, dpu_intr_set[i].en_off);
1009
1010		/* and clear the interrupt */
1011		if (intr->save_irq_status[i])
1012			DPU_REG_WRITE(&intr->hw, dpu_intr_set[i].clr_off,
1013					intr->save_irq_status[i]);
1014
1015		/* Finally update IRQ status based on enable mask */
1016		intr->save_irq_status[i] &= enable_mask;
1017	}
1018
1019	/* ensure register writes go through */
1020	wmb();
1021
1022	spin_unlock_irqrestore(&intr->irq_lock, irq_flags);
1023}
1024
1025static void dpu_hw_intr_clear_intr_status_nolock(struct dpu_hw_intr *intr,
1026		int irq_idx)
1027{
1028	int reg_idx;
1029
1030	if (!intr)
1031		return;
1032
1033	reg_idx = dpu_irq_map[irq_idx].reg_idx;
1034	DPU_REG_WRITE(&intr->hw, dpu_intr_set[reg_idx].clr_off,
1035			dpu_irq_map[irq_idx].irq_mask);
1036
1037	/* ensure register writes go through */
1038	wmb();
1039}
1040
1041static u32 dpu_hw_intr_get_interrupt_status(struct dpu_hw_intr *intr,
1042		int irq_idx, bool clear)
1043{
1044	int reg_idx;
1045	unsigned long irq_flags;
1046	u32 intr_status;
1047
1048	if (!intr)
1049		return 0;
1050
1051	if (irq_idx >= ARRAY_SIZE(dpu_irq_map) || irq_idx < 0) {
1052		pr_err("invalid IRQ index: [%d]\n", irq_idx);
1053		return 0;
1054	}
1055
1056	spin_lock_irqsave(&intr->irq_lock, irq_flags);
1057
1058	reg_idx = dpu_irq_map[irq_idx].reg_idx;
1059	intr_status = DPU_REG_READ(&intr->hw,
1060			dpu_intr_set[reg_idx].status_off) &
1061					dpu_irq_map[irq_idx].irq_mask;
1062	if (intr_status && clear)
1063		DPU_REG_WRITE(&intr->hw, dpu_intr_set[reg_idx].clr_off,
1064				intr_status);
1065
1066	/* ensure register writes go through */
1067	wmb();
1068
1069	spin_unlock_irqrestore(&intr->irq_lock, irq_flags);
1070
1071	return intr_status;
1072}
1073
1074static void __setup_intr_ops(struct dpu_hw_intr_ops *ops)
1075{
1076	ops->irq_idx_lookup = dpu_hw_intr_irqidx_lookup;
1077	ops->enable_irq = dpu_hw_intr_enable_irq;
1078	ops->disable_irq = dpu_hw_intr_disable_irq;
1079	ops->dispatch_irqs = dpu_hw_intr_dispatch_irq;
1080	ops->clear_all_irqs = dpu_hw_intr_clear_irqs;
1081	ops->disable_all_irqs = dpu_hw_intr_disable_irqs;
1082	ops->get_interrupt_statuses = dpu_hw_intr_get_interrupt_statuses;
1083	ops->clear_intr_status_nolock = dpu_hw_intr_clear_intr_status_nolock;
1084	ops->get_interrupt_status = dpu_hw_intr_get_interrupt_status;
1085}
1086
1087static void __intr_offset(struct dpu_mdss_cfg *m,
1088		void __iomem *addr, struct dpu_hw_blk_reg_map *hw)
1089{
1090	hw->base_off = addr;
1091	hw->blk_off = m->mdp[0].base;
1092	hw->hwversion = m->hwversion;
1093}
1094
1095struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr,
1096		struct dpu_mdss_cfg *m)
1097{
1098	struct dpu_hw_intr *intr;
1099
1100	if (!addr || !m)
1101		return ERR_PTR(-EINVAL);
1102
1103	intr = kzalloc(sizeof(*intr), GFP_KERNEL);
1104	if (!intr)
1105		return ERR_PTR(-ENOMEM);
1106
1107	__intr_offset(m, addr, &intr->hw);
1108	__setup_intr_ops(&intr->ops);
1109
1110	intr->irq_idx_tbl_size = ARRAY_SIZE(dpu_irq_map);
1111
1112	intr->cache_irq_mask = kcalloc(ARRAY_SIZE(dpu_intr_set), sizeof(u32),
1113			GFP_KERNEL);
1114	if (intr->cache_irq_mask == NULL) {
1115		kfree(intr);
1116		return ERR_PTR(-ENOMEM);
1117	}
1118
1119	intr->save_irq_status = kcalloc(ARRAY_SIZE(dpu_intr_set), sizeof(u32),
1120			GFP_KERNEL);
1121	if (intr->save_irq_status == NULL) {
1122		kfree(intr->cache_irq_mask);
1123		kfree(intr);
1124		return ERR_PTR(-ENOMEM);
1125	}
1126
1127	intr->irq_mask = m->mdss_irqs;
1128	spin_lock_init(&intr->irq_lock);
1129
1130	return intr;
1131}
1132
1133void dpu_hw_intr_destroy(struct dpu_hw_intr *intr)
1134{
1135	if (intr) {
1136		kfree(intr->cache_irq_mask);
1137		kfree(intr->save_irq_status);
1138		kfree(intr);
1139	}
1140}
1141