drm/msm/dp: move interrupt handling to dp_ctrl

It makes it easier to keep all interrupts-related code in dp_ctrl
submodule. Move all functions to dp_ctrl.c.

Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Tested-by: Stephen Boyd <swboyd@chromium.org> # sc7180-trogdor
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Patchwork: https://patchwork.freedesktop.org/patch/654330/
Link: https://lore.kernel.org/r/20250518-fd-dp-audio-fixup-v6-10-2f0ec3ec000d@oss.qualcomm.com
This commit is contained in:
Dmitry Baryshkov 2025-05-18 14:21:43 +03:00 committed by Dmitry Baryshkov
parent e30cab9dd6
commit d11f5a7a00
8 changed files with 145 additions and 160 deletions

View File

@ -437,9 +437,8 @@ static ssize_t msm_dp_aux_transfer(struct drm_dp_aux *msm_dp_aux,
return ret;
}
irqreturn_t msm_dp_aux_isr(struct drm_dp_aux *msm_dp_aux)
irqreturn_t msm_dp_aux_isr(struct drm_dp_aux *msm_dp_aux, u32 isr)
{
u32 isr;
struct msm_dp_aux_private *aux;
if (!msm_dp_aux) {
@ -449,12 +448,6 @@ irqreturn_t msm_dp_aux_isr(struct drm_dp_aux *msm_dp_aux)
aux = container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux);
isr = msm_dp_catalog_aux_get_irq(aux->catalog);
/* no interrupts pending, return immediately */
if (!isr)
return IRQ_NONE;
if (!aux->cmd_busy) {
DRM_ERROR("Unexpected DP AUX IRQ %#010x when not busy\n", isr);
return IRQ_NONE;

View File

@ -11,7 +11,7 @@
int msm_dp_aux_register(struct drm_dp_aux *msm_dp_aux);
void msm_dp_aux_unregister(struct drm_dp_aux *msm_dp_aux);
irqreturn_t msm_dp_aux_isr(struct drm_dp_aux *msm_dp_aux);
irqreturn_t msm_dp_aux_isr(struct drm_dp_aux *msm_dp_aux, u32 isr);
void msm_dp_aux_enable_xfers(struct drm_dp_aux *msm_dp_aux, bool enabled);
void msm_dp_aux_init(struct drm_dp_aux *msm_dp_aux);
void msm_dp_aux_deinit(struct drm_dp_aux *msm_dp_aux);

View File

@ -15,41 +15,6 @@
#include "dp_catalog.h"
#include "dp_reg.h"
#define POLLING_SLEEP_US 1000
#define POLLING_TIMEOUT_US 10000
#define DP_INTERRUPT_STATUS_ACK_SHIFT 1
#define DP_INTERRUPT_STATUS_MASK_SHIFT 2
#define DP_INTERRUPT_STATUS1 \
(DP_INTR_AUX_XFER_DONE| \
DP_INTR_WRONG_ADDR | DP_INTR_TIMEOUT | \
DP_INTR_NACK_DEFER | DP_INTR_WRONG_DATA_CNT | \
DP_INTR_I2C_NACK | DP_INTR_I2C_DEFER | \
DP_INTR_PLL_UNLOCKED | DP_INTR_AUX_ERROR)
#define DP_INTERRUPT_STATUS1_ACK \
(DP_INTERRUPT_STATUS1 << DP_INTERRUPT_STATUS_ACK_SHIFT)
#define DP_INTERRUPT_STATUS1_MASK \
(DP_INTERRUPT_STATUS1 << DP_INTERRUPT_STATUS_MASK_SHIFT)
#define DP_INTERRUPT_STATUS2 \
(DP_INTR_READY_FOR_VIDEO | DP_INTR_IDLE_PATTERN_SENT | \
DP_INTR_FRAME_END | DP_INTR_CRC_UPDATED)
#define DP_INTERRUPT_STATUS2_ACK \
(DP_INTERRUPT_STATUS2 << DP_INTERRUPT_STATUS_ACK_SHIFT)
#define DP_INTERRUPT_STATUS2_MASK \
(DP_INTERRUPT_STATUS2 << DP_INTERRUPT_STATUS_MASK_SHIFT)
#define DP_INTERRUPT_STATUS4 \
(PSR_UPDATE_INT | PSR_CAPTURE_INT | PSR_EXIT_INT | \
PSR_UPDATE_ERROR_INT | PSR_WAKE_ERROR_INT)
#define DP_INTERRUPT_MASK4 \
(PSR_UPDATE_MASK | PSR_CAPTURE_MASK | PSR_EXIT_MASK | \
PSR_UPDATE_ERROR_MASK | PSR_WAKE_ERROR_MASK)
#define DP_DEFAULT_AHB_OFFSET 0x0000
#define DP_DEFAULT_AHB_SIZE 0x0200
#define DP_DEFAULT_AUX_OFFSET 0x0200
@ -77,66 +42,6 @@ void msm_dp_catalog_snapshot(struct msm_dp_catalog *msm_dp_catalog, struct msm_d
msm_dp_catalog->p0_len, msm_dp_catalog->p0_base, "dp_p0");
}
u32 msm_dp_catalog_aux_get_irq(struct msm_dp_catalog *msm_dp_catalog)
{
u32 intr, intr_ack;
intr = msm_dp_read_ahb(msm_dp_catalog, REG_DP_INTR_STATUS);
intr &= ~DP_INTERRUPT_STATUS1_MASK;
intr_ack = (intr & DP_INTERRUPT_STATUS1)
<< DP_INTERRUPT_STATUS_ACK_SHIFT;
msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS,
intr_ack | DP_INTERRUPT_STATUS1_MASK);
return intr;
}
void msm_dp_catalog_ctrl_enable_irq(struct msm_dp_catalog *msm_dp_catalog,
bool enable)
{
if (enable) {
msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS,
DP_INTERRUPT_STATUS1_MASK);
msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS2,
DP_INTERRUPT_STATUS2_MASK);
} else {
msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS, 0x00);
msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS2, 0x00);
}
}
u32 msm_dp_catalog_ctrl_read_psr_interrupt_status(struct msm_dp_catalog *msm_dp_catalog)
{
u32 intr, intr_ack;
intr = msm_dp_read_ahb(msm_dp_catalog, REG_DP_INTR_STATUS4);
intr_ack = (intr & DP_INTERRUPT_STATUS4)
<< DP_INTERRUPT_STATUS_ACK_SHIFT;
msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS4, intr_ack);
return intr;
}
void msm_dp_catalog_ctrl_config_psr_interrupt(struct msm_dp_catalog *msm_dp_catalog)
{
msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_MASK4, DP_INTERRUPT_MASK4);
}
int msm_dp_catalog_ctrl_get_interrupt(struct msm_dp_catalog *msm_dp_catalog)
{
u32 intr, intr_ack;
intr = msm_dp_read_ahb(msm_dp_catalog, REG_DP_INTR_STATUS2);
intr &= ~DP_INTERRUPT_STATUS2_MASK;
intr_ack = (intr & DP_INTERRUPT_STATUS2)
<< DP_INTERRUPT_STATUS_ACK_SHIFT;
msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS2,
intr_ack | DP_INTERRUPT_STATUS2_MASK);
return intr;
}
static void __iomem *msm_dp_ioremap(struct platform_device *pdev, int idx, size_t *len)
{
struct resource *res;

View File

@ -11,23 +11,6 @@
#include "dp_utils.h"
#include "disp/msm_disp_snapshot.h"
/* interrupts */
#define DP_INTR_HPD BIT(0)
#define DP_INTR_AUX_XFER_DONE BIT(3)
#define DP_INTR_WRONG_ADDR BIT(6)
#define DP_INTR_TIMEOUT BIT(9)
#define DP_INTR_NACK_DEFER BIT(12)
#define DP_INTR_WRONG_DATA_CNT BIT(15)
#define DP_INTR_I2C_NACK BIT(18)
#define DP_INTR_I2C_DEFER BIT(21)
#define DP_INTR_PLL_UNLOCKED BIT(24)
#define DP_INTR_AUX_ERROR BIT(27)
#define DP_INTR_READY_FOR_VIDEO BIT(0)
#define DP_INTR_IDLE_PATTERN_SENT BIT(3)
#define DP_INTR_FRAME_END BIT(6)
#define DP_INTR_CRC_UPDATED BIT(9)
#define DP_HW_VERSION_1_0 0x10000000
#define DP_HW_VERSION_1_2 0x10020000
@ -112,15 +95,6 @@ static inline void msm_dp_write_link(struct msm_dp_catalog *msm_dp_catalog,
/* Debug module */
void msm_dp_catalog_snapshot(struct msm_dp_catalog *msm_dp_catalog, struct msm_disp_state *disp_state);
/* AUX APIs */
u32 msm_dp_catalog_aux_get_irq(struct msm_dp_catalog *msm_dp_catalog);
/* DP Controller APIs */
void msm_dp_catalog_ctrl_enable_irq(struct msm_dp_catalog *msm_dp_catalog, bool enable);
int msm_dp_catalog_ctrl_get_interrupt(struct msm_dp_catalog *msm_dp_catalog);
void msm_dp_catalog_ctrl_config_psr_interrupt(struct msm_dp_catalog *msm_dp_catalog);
u32 msm_dp_catalog_ctrl_read_psr_interrupt_status(struct msm_dp_catalog *msm_dp_catalog);
struct msm_dp_catalog *msm_dp_catalog_get(struct device *dev);
#endif /* _DP_CATALOG_H_ */

View File

@ -31,6 +31,38 @@
#define PSR_OPERATION_COMPLETION_TIMEOUT_JIFFIES (300 * HZ / 1000) /* 300 ms */
#define WAIT_FOR_VIDEO_READY_TIMEOUT_JIFFIES (HZ / 2)
#define DP_INTERRUPT_STATUS_ACK_SHIFT 1
#define DP_INTERRUPT_STATUS_MASK_SHIFT 2
#define DP_INTERRUPT_STATUS1 \
(DP_INTR_AUX_XFER_DONE| \
DP_INTR_WRONG_ADDR | DP_INTR_TIMEOUT | \
DP_INTR_NACK_DEFER | DP_INTR_WRONG_DATA_CNT | \
DP_INTR_I2C_NACK | DP_INTR_I2C_DEFER | \
DP_INTR_PLL_UNLOCKED | DP_INTR_AUX_ERROR)
#define DP_INTERRUPT_STATUS1_ACK \
(DP_INTERRUPT_STATUS1 << DP_INTERRUPT_STATUS_ACK_SHIFT)
#define DP_INTERRUPT_STATUS1_MASK \
(DP_INTERRUPT_STATUS1 << DP_INTERRUPT_STATUS_MASK_SHIFT)
#define DP_INTERRUPT_STATUS2 \
(DP_INTR_READY_FOR_VIDEO | DP_INTR_IDLE_PATTERN_SENT | \
DP_INTR_FRAME_END | DP_INTR_CRC_UPDATED)
#define DP_INTERRUPT_STATUS2_ACK \
(DP_INTERRUPT_STATUS2 << DP_INTERRUPT_STATUS_ACK_SHIFT)
#define DP_INTERRUPT_STATUS2_MASK \
(DP_INTERRUPT_STATUS2 << DP_INTERRUPT_STATUS_MASK_SHIFT)
#define DP_INTERRUPT_STATUS4 \
(PSR_UPDATE_INT | PSR_CAPTURE_INT | PSR_EXIT_INT | \
PSR_UPDATE_ERROR_INT | PSR_WAKE_ERROR_INT)
#define DP_INTERRUPT_MASK4 \
(PSR_UPDATE_MASK | PSR_CAPTURE_MASK | PSR_EXIT_MASK | \
PSR_UPDATE_ERROR_MASK | PSR_WAKE_ERROR_MASK)
#define DP_CTRL_INTR_READY_FOR_VIDEO BIT(0)
#define DP_CTRL_INTR_IDLE_PATTERN_SENT BIT(3)
@ -129,8 +161,10 @@ static int msm_dp_aux_link_configure(struct drm_dp_aux *aux,
/*
* NOTE: resetting DP controller will also clear any pending HPD related interrupts
*/
static void msm_dp_ctrl_reset(struct msm_dp_ctrl_private *ctrl)
void msm_dp_ctrl_reset(struct msm_dp_ctrl *msm_dp_ctrl)
{
struct msm_dp_ctrl_private *ctrl =
container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
u32 sw_reset;
@ -149,6 +183,79 @@ static void msm_dp_ctrl_reset(struct msm_dp_ctrl_private *ctrl)
}
}
static u32 msm_dp_ctrl_get_aux_interrupt(struct msm_dp_ctrl_private *ctrl)
{
struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
u32 intr, intr_ack;
intr = msm_dp_read_ahb(msm_dp_catalog, REG_DP_INTR_STATUS);
intr &= ~DP_INTERRUPT_STATUS1_MASK;
intr_ack = (intr & DP_INTERRUPT_STATUS1)
<< DP_INTERRUPT_STATUS_ACK_SHIFT;
msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS,
intr_ack | DP_INTERRUPT_STATUS1_MASK);
return intr;
}
static u32 msm_dp_ctrl_get_interrupt(struct msm_dp_ctrl_private *ctrl)
{
struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
u32 intr, intr_ack;
intr = msm_dp_read_ahb(msm_dp_catalog, REG_DP_INTR_STATUS2);
intr &= ~DP_INTERRUPT_STATUS2_MASK;
intr_ack = (intr & DP_INTERRUPT_STATUS2)
<< DP_INTERRUPT_STATUS_ACK_SHIFT;
msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS2,
intr_ack | DP_INTERRUPT_STATUS2_MASK);
return intr;
}
void msm_dp_ctrl_enable_irq(struct msm_dp_ctrl *msm_dp_ctrl)
{
struct msm_dp_ctrl_private *ctrl =
container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS,
DP_INTERRUPT_STATUS1_MASK);
msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS2,
DP_INTERRUPT_STATUS2_MASK);
}
void msm_dp_ctrl_disable_irq(struct msm_dp_ctrl *msm_dp_ctrl)
{
struct msm_dp_ctrl_private *ctrl =
container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS, 0x00);
msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS2, 0x00);
}
static u32 msm_dp_ctrl_get_psr_interrupt(struct msm_dp_ctrl_private *ctrl)
{
struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
u32 intr, intr_ack;
intr = msm_dp_read_ahb(msm_dp_catalog, REG_DP_INTR_STATUS4);
intr_ack = (intr & DP_INTERRUPT_STATUS4)
<< DP_INTERRUPT_STATUS_ACK_SHIFT;
msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_STATUS4, intr_ack);
return intr;
}
static void msm_dp_ctrl_config_psr_interrupt(struct msm_dp_ctrl_private *ctrl)
{
struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
msm_dp_write_ahb(msm_dp_catalog, REG_DP_INTR_MASK4, DP_INTERRUPT_MASK4);
}
static void msm_dp_ctrl_psr_mainlink_enable(struct msm_dp_ctrl_private *ctrl)
{
struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
@ -1674,23 +1781,6 @@ static int msm_dp_ctrl_enable_mainlink_clocks(struct msm_dp_ctrl_private *ctrl)
return ret;
}
void msm_dp_ctrl_reset_irq_ctrl(struct msm_dp_ctrl *msm_dp_ctrl, bool enable)
{
struct msm_dp_ctrl_private *ctrl;
ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
msm_dp_ctrl_reset(ctrl);
/*
* all dp controller programmable registers will not
* be reset to default value after DP_SW_RESET
* therefore interrupt mask bits have to be updated
* to enable/disable interrupts
*/
msm_dp_catalog_ctrl_enable_irq(ctrl->catalog, enable);
}
static void msm_dp_ctrl_enable_sdp(struct msm_dp_ctrl_private *ctrl)
{
struct msm_dp_catalog *msm_dp_catalog = ctrl->catalog;
@ -1743,7 +1833,7 @@ void msm_dp_ctrl_config_psr(struct msm_dp_ctrl *msm_dp_ctrl)
cfg |= PSR1_SUPPORTED;
msm_dp_write_link(msm_dp_catalog, REG_PSR_CONFIG, cfg);
msm_dp_catalog_ctrl_config_psr_interrupt(msm_dp_catalog);
msm_dp_ctrl_config_psr_interrupt(ctrl);
msm_dp_ctrl_enable_sdp(ctrl);
cfg = DP_PSR_ENABLE;
@ -1868,7 +1958,7 @@ static int msm_dp_ctrl_deinitialize_mainlink(struct msm_dp_ctrl_private *ctrl)
msm_dp_ctrl_mainlink_disable(ctrl);
msm_dp_ctrl_reset(ctrl);
msm_dp_ctrl_reset(&ctrl->msm_dp_ctrl);
dev_pm_opp_set_rate(ctrl->dev, 0);
msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);
@ -2499,7 +2589,7 @@ void msm_dp_ctrl_off(struct msm_dp_ctrl *msm_dp_ctrl)
msm_dp_ctrl_mainlink_disable(ctrl);
msm_dp_ctrl_reset(ctrl);
msm_dp_ctrl_reset(&ctrl->msm_dp_ctrl);
if (ctrl->stream_clks_on) {
clk_disable_unprepare(ctrl->pixel_clk);
@ -2526,7 +2616,7 @@ irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl)
ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
if (ctrl->panel->psr_cap.version) {
isr = msm_dp_catalog_ctrl_read_psr_interrupt_status(ctrl->catalog);
isr = msm_dp_ctrl_get_psr_interrupt(ctrl);
if (isr)
complete(&ctrl->psr_op_comp);
@ -2541,8 +2631,7 @@ irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl)
drm_dbg_dp(ctrl->drm_dev, "PSR frame capture done\n");
}
isr = msm_dp_catalog_ctrl_get_interrupt(ctrl->catalog);
isr = msm_dp_ctrl_get_interrupt(ctrl);
if (isr & DP_CTRL_INTR_READY_FOR_VIDEO) {
drm_dbg_dp(ctrl->drm_dev, "dp_video_ready\n");
@ -2556,6 +2645,11 @@ irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl)
ret = IRQ_HANDLED;
}
/* DP aux isr */
isr = msm_dp_ctrl_get_aux_interrupt(ctrl);
if (isr)
ret |= msm_dp_aux_isr(ctrl->aux, isr);
return ret;
}

View File

@ -30,7 +30,7 @@ struct msm_dp_ctrl *msm_dp_ctrl_get(struct device *dev, struct msm_dp_link *link
struct msm_dp_catalog *catalog,
struct phy *phy);
void msm_dp_ctrl_reset_irq_ctrl(struct msm_dp_ctrl *msm_dp_ctrl, bool enable);
void msm_dp_ctrl_reset(struct msm_dp_ctrl *msm_dp_ctrl);
void msm_dp_ctrl_phy_init(struct msm_dp_ctrl *msm_dp_ctrl);
void msm_dp_ctrl_phy_exit(struct msm_dp_ctrl *msm_dp_ctrl);
void msm_dp_ctrl_irq_phy_exit(struct msm_dp_ctrl *msm_dp_ctrl);
@ -41,4 +41,7 @@ void msm_dp_ctrl_config_psr(struct msm_dp_ctrl *msm_dp_ctrl);
int msm_dp_ctrl_core_clk_enable(struct msm_dp_ctrl *msm_dp_ctrl);
void msm_dp_ctrl_core_clk_disable(struct msm_dp_ctrl *msm_dp_ctrl);
void msm_dp_ctrl_enable_irq(struct msm_dp_ctrl *msm_dp_ctrl);
void msm_dp_ctrl_disable_irq(struct msm_dp_ctrl *msm_dp_ctrl);
#endif /* _DP_CTRL_H_ */

View File

@ -462,7 +462,8 @@ static void msm_dp_display_host_init(struct msm_dp_display_private *dp)
dp->phy_initialized);
msm_dp_ctrl_core_clk_enable(dp->ctrl);
msm_dp_ctrl_reset_irq_ctrl(dp->ctrl, true);
msm_dp_ctrl_reset(dp->ctrl);
msm_dp_ctrl_enable_irq(dp->ctrl);
msm_dp_aux_init(dp->aux);
dp->core_initialized = true;
}
@ -473,7 +474,8 @@ static void msm_dp_display_host_deinit(struct msm_dp_display_private *dp)
dp->msm_dp_display.connector_type, dp->core_initialized,
dp->phy_initialized);
msm_dp_ctrl_reset_irq_ctrl(dp->ctrl, false);
msm_dp_ctrl_reset(dp->ctrl);
msm_dp_ctrl_disable_irq(dp->ctrl);
msm_dp_aux_deinit(dp->aux);
msm_dp_ctrl_core_clk_disable(dp->ctrl);
dp->core_initialized = false;
@ -1175,9 +1177,6 @@ static irqreturn_t msm_dp_display_irq_handler(int irq, void *dev_id)
/* DP controller isr */
ret |= msm_dp_ctrl_isr(dp->ctrl);
/* DP aux isr */
ret |= msm_dp_aux_isr(dp->aux);
return ret;
}

View File

@ -21,8 +21,25 @@
#define REG_DP_CLK_CTRL (0x00000018)
#define REG_DP_CLK_ACTIVE (0x0000001C)
#define REG_DP_INTR_STATUS (0x00000020)
#define DP_INTR_HPD BIT(0)
#define DP_INTR_AUX_XFER_DONE BIT(3)
#define DP_INTR_WRONG_ADDR BIT(6)
#define DP_INTR_TIMEOUT BIT(9)
#define DP_INTR_NACK_DEFER BIT(12)
#define DP_INTR_WRONG_DATA_CNT BIT(15)
#define DP_INTR_I2C_NACK BIT(18)
#define DP_INTR_I2C_DEFER BIT(21)
#define DP_INTR_PLL_UNLOCKED BIT(24)
#define DP_INTR_AUX_ERROR BIT(27)
#define REG_DP_INTR_STATUS2 (0x00000024)
#define DP_INTR_READY_FOR_VIDEO BIT(0)
#define DP_INTR_IDLE_PATTERN_SENT BIT(3)
#define DP_INTR_FRAME_END BIT(6)
#define DP_INTR_CRC_UPDATED BIT(9)
#define REG_DP_INTR_STATUS3 (0x00000028)
#define REG_DP_INTR_STATUS4 (0x0000002C)