Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 212837d8 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm/msm/dsi-staging: enable interrupt support"

parents d893d9df 80ada7ff
Loading
Loading
Loading
Loading
+316 −57
Original line number Diff line number Diff line
@@ -9,7 +9,6 @@
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#define pr_fmt(fmt)	"dsi-ctrl:[%s] " fmt, __func__
@@ -884,7 +883,7 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl,
			  const struct mipi_dsi_msg *msg,
			  u32 flags)
{
	int rc = 0;
	int rc = 0, ret = 0;
	struct mipi_dsi_packet packet;
	struct dsi_ctrl_cmd_dma_fifo_info cmd;
	struct dsi_ctrl_cmd_dma_info cmd_mem;
@@ -948,9 +947,7 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl,
	hw_flags |= (flags & DSI_CTRL_CMD_DEFER_TRIGGER) ?
			DSI_CTRL_HW_CMD_WAIT_FOR_TRIGGER : 0;

	if (!(flags & DSI_CTRL_CMD_DEFER_TRIGGER))
		reinit_completion(&dsi_ctrl->int_info.cmd_dma_done);

	if (flags & DSI_CTRL_CMD_DEFER_TRIGGER) {
		if (flags & DSI_CTRL_CMD_FETCH_MEMORY) {
			dsi_ctrl->hw.ops.kickoff_command(&dsi_ctrl->hw,
							&cmd_mem,
@@ -960,30 +957,49 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl,
							      &cmd,
							      hw_flags);
		}
	}

	if (!(flags & DSI_CTRL_CMD_DEFER_TRIGGER)) {
		u32 retry = 10;
		dsi_ctrl_enable_status_interrupt(dsi_ctrl,
					DSI_SINT_CMD_MODE_DMA_DONE, NULL);
		reinit_completion(&dsi_ctrl->irq_info.cmd_dma_done);

		if (flags & DSI_CTRL_CMD_FETCH_MEMORY) {
			dsi_ctrl->hw.ops.kickoff_command(&dsi_ctrl->hw,
						      &cmd_mem,
						      hw_flags);
		} else if (flags & DSI_CTRL_CMD_FIFO_STORE) {
			dsi_ctrl->hw.ops.kickoff_fifo_command(&dsi_ctrl->hw,
							      &cmd,
							      hw_flags);
		}

		ret = wait_for_completion_timeout(
				&dsi_ctrl->irq_info.cmd_dma_done,
				msecs_to_jiffies(DSI_CTRL_TX_TO_MS));

		if (ret == 0) {
			u32 status = 0;
		u64 error = 0;
		u32 mask = (DSI_CMD_MODE_DMA_DONE);
			u32 mask = DSI_CMD_MODE_DMA_DONE;

		while ((status == 0) && (retry > 0)) {
			udelay(1000);
			status = dsi_ctrl->hw.ops.get_interrupt_status(
								&dsi_ctrl->hw);
			error = dsi_ctrl->hw.ops.get_error_status(
								&dsi_ctrl->hw);
			status &= mask;
			retry--;
			dsi_ctrl->hw.ops.clear_interrupt_status(&dsi_ctrl->hw,
			if (status & mask) {
				status |= (DSI_CMD_MODE_DMA_DONE |
						DSI_BTA_DONE);
				dsi_ctrl->hw.ops.clear_interrupt_status(
								&dsi_ctrl->hw,
								status);
			dsi_ctrl->hw.ops.clear_error_status(&dsi_ctrl->hw,
							    error);
		}
		pr_debug("INT STATUS = %x, retry = %d\n", status, retry);
		if (retry == 0)
				dsi_ctrl_disable_status_interrupt(dsi_ctrl,
						DSI_SINT_CMD_MODE_DMA_DONE);
				complete_all(&dsi_ctrl->irq_info.cmd_dma_done);
				pr_warn("dma_tx done but irq not triggered\n");
			} else {
				rc = -ETIMEDOUT;
				dsi_ctrl_disable_status_interrupt(dsi_ctrl,
						DSI_SINT_CMD_MODE_DMA_DONE);
				pr_err("[DSI_%d]Command transfer failed\n",
						dsi_ctrl->cell_index);
			}
		}

		dsi_ctrl->hw.ops.reset_cmd_fifo(&dsi_ctrl->hw);
	}
@@ -1152,15 +1168,6 @@ static int dsi_ctrl_drv_state_init(struct dsi_ctrl *dsi_ctrl)
	return rc;
}

int dsi_ctrl_intr_deinit(struct dsi_ctrl *dsi_ctrl)
{
	struct dsi_ctrl_interrupts *ints = &dsi_ctrl->int_info;

	devm_free_irq(&dsi_ctrl->pdev->dev, ints->irq, dsi_ctrl);

	return 0;
}

static int dsi_ctrl_buffer_deinit(struct dsi_ctrl *dsi_ctrl)
{
	if (dsi_ctrl->tx_cmd_buf) {
@@ -1259,6 +1266,10 @@ static int dsi_ctrl_dev_probe(struct platform_device *pdev)

	dsi_ctrl->cell_index = index;
	dsi_ctrl->version = version;
	dsi_ctrl->irq_info.irq_num = -1;
	dsi_ctrl->irq_info.irq_stat_mask = 0x0;

	spin_lock_init(&dsi_ctrl->irq_info.irq_lock);

	dsi_ctrl->name = of_get_property(pdev->dev.of_node, "label", NULL);
	if (!dsi_ctrl->name)
@@ -1677,6 +1688,236 @@ int dsi_ctrl_phy_reset_config(struct dsi_ctrl *dsi_ctrl, bool enable)
	return 0;
}

static void dsi_ctrl_handle_error_status(struct dsi_ctrl *dsi_ctrl,
				unsigned long int error)
{
	pr_err("%s: %lu\n", __func__, error);

	/* DTLN PHY error */
	if (error & 0x3000e00)
		if (dsi_ctrl->hw.ops.clear_error_status)
			dsi_ctrl->hw.ops.clear_error_status(&dsi_ctrl->hw,
					0x3000e00);

	/* DSI FIFO OVERFLOW error */
	if (error & 0xf0000) {
		if (dsi_ctrl->hw.ops.clear_error_status)
			dsi_ctrl->hw.ops.clear_error_status(&dsi_ctrl->hw,
					0xf0000);
	}

	/* DSI FIFO UNDERFLOW error */
	if (error & 0xf00000) {
		if (dsi_ctrl->hw.ops.clear_error_status)
			dsi_ctrl->hw.ops.clear_error_status(&dsi_ctrl->hw,
					0xf00000);
	}

	/* DSI PLL UNLOCK error */
	if (error & BIT(8))
		if (dsi_ctrl->hw.ops.clear_error_status)
			dsi_ctrl->hw.ops.clear_error_status(&dsi_ctrl->hw,
					BIT(8));
}

/**
 * dsi_ctrl_isr - interrupt service routine for DSI CTRL component
 * @irq: Incoming IRQ number
 * @ptr: Pointer to user data structure (struct dsi_ctrl)
 * Returns: IRQ_HANDLED if no further action required
 */
static irqreturn_t dsi_ctrl_isr(int irq, void *ptr)
{
	struct dsi_ctrl *dsi_ctrl;
	struct dsi_event_cb_info cb_info;
	unsigned long flags;
	uint32_t cell_index, status, i;
	uint64_t errors;

	if (!ptr)
		return IRQ_NONE;
	dsi_ctrl = ptr;

	/* clear status interrupts */
	if (dsi_ctrl->hw.ops.get_interrupt_status)
		status = dsi_ctrl->hw.ops.get_interrupt_status(&dsi_ctrl->hw);
	else
		status = 0x0;

	if (dsi_ctrl->hw.ops.clear_interrupt_status)
		dsi_ctrl->hw.ops.clear_interrupt_status(&dsi_ctrl->hw, status);

	spin_lock_irqsave(&dsi_ctrl->irq_info.irq_lock, flags);
	cell_index = dsi_ctrl->cell_index;
	spin_unlock_irqrestore(&dsi_ctrl->irq_info.irq_lock, flags);

	/* clear error interrupts */
	if (dsi_ctrl->hw.ops.get_error_status)
		errors = dsi_ctrl->hw.ops.get_error_status(&dsi_ctrl->hw);
	else
		errors = 0x0;

	if (errors) {
		/* handle DSI error recovery */
		dsi_ctrl_handle_error_status(dsi_ctrl, errors);
		if (dsi_ctrl->hw.ops.clear_error_status)
			dsi_ctrl->hw.ops.clear_error_status(&dsi_ctrl->hw,
							errors);
	}

	if (status & DSI_CMD_MODE_DMA_DONE) {
		dsi_ctrl_disable_status_interrupt(dsi_ctrl,
					DSI_SINT_CMD_MODE_DMA_DONE);
		complete_all(&dsi_ctrl->irq_info.cmd_dma_done);
	}

	if (status & DSI_CMD_FRAME_DONE) {
		dsi_ctrl_disable_status_interrupt(dsi_ctrl,
					DSI_SINT_CMD_FRAME_DONE);
		complete_all(&dsi_ctrl->irq_info.cmd_frame_done);
	}

	if (status & DSI_VIDEO_MODE_FRAME_DONE) {
		dsi_ctrl_disable_status_interrupt(dsi_ctrl,
					DSI_SINT_VIDEO_MODE_FRAME_DONE);
		complete_all(&dsi_ctrl->irq_info.vid_frame_done);
	}

	if (status & DSI_BTA_DONE) {
		dsi_ctrl_disable_status_interrupt(dsi_ctrl,
					DSI_SINT_BTA_DONE);
		complete_all(&dsi_ctrl->irq_info.bta_done);
	}

	for (i = 0; status && i < DSI_STATUS_INTERRUPT_COUNT; ++i) {
		if (status & 0x1) {
			spin_lock_irqsave(&dsi_ctrl->irq_info.irq_lock, flags);
			cb_info = dsi_ctrl->irq_info.irq_stat_cb[i];
			spin_unlock_irqrestore(
					&dsi_ctrl->irq_info.irq_lock, flags);

			if (cb_info.event_cb)
				(void)cb_info.event_cb(cb_info.event_usr_ptr,
						cb_info.event_idx,
						cell_index, irq, 0, 0, 0);
		}
		status >>= 1;
	}

	return IRQ_HANDLED;
}

/**
 * _dsi_ctrl_setup_isr - register ISR handler
 * @dsi_ctrl: Pointer to associated dsi_ctrl structure
 * Returns: Zero on success
 */
static int dsi_ctrl_setup_isr(struct dsi_ctrl *dsi_ctrl)
{
	int irq_num, rc;

	if (!dsi_ctrl)
		return -EINVAL;
	if (dsi_ctrl->irq_info.irq_num != -1)
		return 0;

	init_completion(&dsi_ctrl->irq_info.cmd_dma_done);
	init_completion(&dsi_ctrl->irq_info.vid_frame_done);
	init_completion(&dsi_ctrl->irq_info.cmd_frame_done);
	init_completion(&dsi_ctrl->irq_info.bta_done);

	irq_num = platform_get_irq(dsi_ctrl->pdev, 0);
	if (irq_num < 0) {
		pr_err("[DSI_%d] Failed to get IRQ number, %d\n",
				dsi_ctrl->cell_index, irq_num);
		rc = irq_num;
	} else {
		rc = devm_request_threaded_irq(&dsi_ctrl->pdev->dev, irq_num,
				dsi_ctrl_isr, NULL, 0, "dsi_ctrl", dsi_ctrl);
		if (rc) {
			pr_err("[DSI_%d] Failed to request IRQ, %d\n",
					dsi_ctrl->cell_index, rc);
		} else {
			dsi_ctrl->irq_info.irq_num = irq_num;
			disable_irq_nosync(irq_num);

			pr_info("[DSI_%d] IRQ %d registered\n",
					dsi_ctrl->cell_index, irq_num);
		}
	}
	return rc;
}

/**
 * _dsi_ctrl_destroy_isr - unregister ISR handler
 * @dsi_ctrl: Pointer to associated dsi_ctrl structure
 */
static void _dsi_ctrl_destroy_isr(struct dsi_ctrl *dsi_ctrl)
{
	if (!dsi_ctrl || !dsi_ctrl->pdev || dsi_ctrl->irq_info.irq_num < 0)
		return;

	if (dsi_ctrl->irq_info.irq_num != -1) {
		devm_free_irq(&dsi_ctrl->pdev->dev,
				dsi_ctrl->irq_info.irq_num, dsi_ctrl);
		dsi_ctrl->irq_info.irq_num = -1;
	}
}

void dsi_ctrl_enable_status_interrupt(struct dsi_ctrl *dsi_ctrl,
		uint32_t intr_idx, struct dsi_event_cb_info *event_info)
{
	unsigned long flags;

	if (!dsi_ctrl || dsi_ctrl->irq_info.irq_num == -1 ||
			intr_idx >= DSI_STATUS_INTERRUPT_COUNT)
		return;

	spin_lock_irqsave(&dsi_ctrl->irq_info.irq_lock, flags);

	if (dsi_ctrl->irq_info.irq_stat_refcount[intr_idx] == 0) {
		/* enable irq on first request */
		if (dsi_ctrl->irq_info.irq_stat_mask == 0)
			enable_irq(dsi_ctrl->irq_info.irq_num);

		/* update hardware mask */
		dsi_ctrl->irq_info.irq_stat_mask |= BIT(intr_idx);
		dsi_ctrl->hw.ops.enable_status_interrupts(&dsi_ctrl->hw,
				dsi_ctrl->irq_info.irq_stat_mask);
	}
	++(dsi_ctrl->irq_info.irq_stat_refcount[intr_idx]);

	if (event_info)
		dsi_ctrl->irq_info.irq_stat_cb[intr_idx] = *event_info;

	spin_unlock_irqrestore(&dsi_ctrl->irq_info.irq_lock, flags);
}

void dsi_ctrl_disable_status_interrupt(struct dsi_ctrl *dsi_ctrl,
		uint32_t intr_idx)
{
	unsigned long flags;

	if (!dsi_ctrl || dsi_ctrl->irq_info.irq_num == -1 ||
			intr_idx >= DSI_STATUS_INTERRUPT_COUNT)
		return;

	spin_lock_irqsave(&dsi_ctrl->irq_info.irq_lock, flags);

	if (dsi_ctrl->irq_info.irq_stat_refcount[intr_idx])
		if (--(dsi_ctrl->irq_info.irq_stat_refcount[intr_idx]) == 0) {
			dsi_ctrl->irq_info.irq_stat_mask &= ~BIT(intr_idx);
			dsi_ctrl->hw.ops.enable_status_interrupts(&dsi_ctrl->hw,
					dsi_ctrl->irq_info.irq_stat_mask);

			/* don't need irq if no lines are enabled */
			if (dsi_ctrl->irq_info.irq_stat_mask == 0)
				disable_irq_nosync(dsi_ctrl->irq_info.irq_num);
		}

	spin_unlock_irqrestore(&dsi_ctrl->irq_info.irq_lock, flags);
}

/**
 * dsi_ctrl_host_init() - Initialize DSI host hardware.
 * @dsi_ctrl:        DSI controller handle.
@@ -1729,7 +1970,7 @@ int dsi_ctrl_host_init(struct dsi_ctrl *dsi_ctrl)
					  &dsi_ctrl->host_config.video_timing);
	}


	dsi_ctrl_setup_isr(dsi_ctrl);

	dsi_ctrl->hw.ops.enable_status_interrupts(&dsi_ctrl->hw, 0x0);
	dsi_ctrl->hw.ops.enable_error_interrupts(&dsi_ctrl->hw, 0x0);
@@ -1777,6 +2018,8 @@ int dsi_ctrl_host_deinit(struct dsi_ctrl *dsi_ctrl)

	mutex_lock(&dsi_ctrl->ctrl_lock);

	_dsi_ctrl_destroy_isr(dsi_ctrl);

	rc = dsi_ctrl_check_state(dsi_ctrl, DSI_CTRL_OP_HOST_INIT, 0x0);
	if (rc) {
		pr_err("[DSI_%d] Controller state check failed, rc=%d\n",
@@ -1933,7 +2176,7 @@ int dsi_ctrl_cmd_transfer(struct dsi_ctrl *dsi_ctrl,
 */
int dsi_ctrl_cmd_tx_trigger(struct dsi_ctrl *dsi_ctrl, u32 flags)
{
	int rc = 0;
	int rc = 0, ret = 0;
	u32 status = 0;
	u32 mask = (DSI_CMD_MODE_DMA_DONE);

@@ -1944,28 +2187,44 @@ int dsi_ctrl_cmd_tx_trigger(struct dsi_ctrl *dsi_ctrl, u32 flags)

	mutex_lock(&dsi_ctrl->ctrl_lock);

	reinit_completion(&dsi_ctrl->int_info.cmd_dma_done);

	if (!(flags & DSI_CTRL_CMD_BROADCAST_MASTER))
		dsi_ctrl->hw.ops.trigger_command_dma(&dsi_ctrl->hw);

	if ((flags & DSI_CTRL_CMD_BROADCAST) &&
		(flags & DSI_CTRL_CMD_BROADCAST_MASTER)) {
		u32 retry = 10;
		dsi_ctrl_enable_status_interrupt(dsi_ctrl,
					DSI_SINT_CMD_MODE_DMA_DONE, NULL);
		reinit_completion(&dsi_ctrl->irq_info.cmd_dma_done);

		while ((status == 0) && (retry > 0)) {
			udelay(1000);
		/* trigger command */
		dsi_ctrl->hw.ops.trigger_command_dma(&dsi_ctrl->hw);

		ret = wait_for_completion_timeout(
				&dsi_ctrl->irq_info.cmd_dma_done,
				msecs_to_jiffies(DSI_CTRL_TX_TO_MS));

		if (ret == 0) {
			status = dsi_ctrl->hw.ops.get_interrupt_status(
								&dsi_ctrl->hw);
			status &= mask;
			retry--;
			dsi_ctrl->hw.ops.clear_interrupt_status(&dsi_ctrl->hw,
			if (status & mask) {
				status |= (DSI_CMD_MODE_DMA_DONE |
						DSI_BTA_DONE);
				dsi_ctrl->hw.ops.clear_interrupt_status(
								&dsi_ctrl->hw,
								status);
		}
		pr_debug("INT STATUS = %x, retry = %d\n", status, retry);
		if (retry == 0)
				dsi_ctrl_disable_status_interrupt(dsi_ctrl,
						DSI_SINT_CMD_MODE_DMA_DONE);
				complete_all(&dsi_ctrl->irq_info.cmd_dma_done);
				pr_warn("dma_tx done but irq not triggered\n");
			} else {
				rc = -ETIMEDOUT;
				dsi_ctrl_disable_status_interrupt(dsi_ctrl,
						DSI_SINT_CMD_MODE_DMA_DONE);
				pr_err("[DSI_%d]Command transfer failed\n",
						dsi_ctrl->cell_index);
			}
		}
	}

	mutex_unlock(&dsi_ctrl->ctrl_lock);
	return rc;
+31 −20
Original line number Diff line number Diff line
@@ -138,33 +138,26 @@ struct dsi_ctrl_state_info {

/**
 * struct dsi_ctrl_interrupts - define interrupt information
 * @irq:                   IRQ id for the DSI controller.
 * @intr_lock:             Spinlock to protect access to interrupt registers.
 * @interrupt_status:      Status interrupts which need to be serviced.
 * @error_status:          Error interurpts which need to be serviced.
 * @interrupts_enabled:    Status interrupts which are enabled.
 * @errors_enabled:        Error interrupts which are enabled.
 * @irq_lock:            Spinlock for ISR handler.
 * @irq_num:             Linux interrupt number associated with device.
 * @irq_stat_mask:       Hardware mask of currently enabled interrupts.
 * @irq_stat_refcount:   Number of times each interrupt has been requested.
 * @irq_stat_cb:         Status IRQ callback definitions.
 * @cmd_dma_done:          Completion signal for DSI_CMD_MODE_DMA_DONE interrupt
 * @vid_frame_done:        Completion signal for DSI_VIDEO_MODE_FRAME_DONE int.
 * @cmd_frame_done:        Completion signal for DSI_CMD_FRAME_DONE interrupt.
 * @interrupt_done_work:   Work item for servicing status interrupts.
 * @error_status_work:     Work item for servicing error interrupts.
 */
struct dsi_ctrl_interrupts {
	u32 irq;
	spinlock_t intr_lock; /* protects access to interrupt registers */
	u32 interrupt_status;
	u64 error_status;

	u32 interrupts_enabled;
	u64 errors_enabled;
	spinlock_t irq_lock;
	int irq_num;
	uint32_t irq_stat_mask;
	int irq_stat_refcount[DSI_STATUS_INTERRUPT_COUNT];
	struct dsi_event_cb_info irq_stat_cb[DSI_STATUS_INTERRUPT_COUNT];

	struct completion cmd_dma_done;
	struct completion vid_frame_done;
	struct completion cmd_frame_done;

	struct work_struct interrupt_done_work;
	struct work_struct error_status_work;
	struct completion bta_done;
};

/**
@@ -180,7 +173,7 @@ struct dsi_ctrl_interrupts {
 * @hw:                  DSI controller hardware object.
 * @current_state:       Current driver and hardware state.
 * @clk_cb:		 Callback for DSI clock control.
 * @int_info:            Interrupt information.
 * @irq_info:            Interrupt information.
 * @clk_info:            Clock information.
 * @clk_freq:            DSi Link clock frequency information.
 * @pwr_info:            Power information.
@@ -212,7 +205,8 @@ struct dsi_ctrl {
	struct dsi_ctrl_state_info current_state;
	struct clk_ctrl_cb clk_cb;

	struct dsi_ctrl_interrupts int_info;
	struct dsi_ctrl_interrupts irq_info;

	/* Clock and power states */
	struct dsi_ctrl_clk_info clk_info;
	struct link_clk_freq clk_freq;
@@ -559,6 +553,23 @@ int dsi_ctrl_set_clamp_state(struct dsi_ctrl *dsi_Ctrl,
int dsi_ctrl_set_clock_source(struct dsi_ctrl *dsi_ctrl,
			      struct dsi_clk_link_set *source_clks);

/**
 * dsi_ctrl_enable_status_interrupt() - enable status interrupts
 * @dsi_ctrl:        DSI controller handle.
 * @intr_idx:        Index interrupt to disable.
 * @event_info:      Pointer to event callback definition
 */
void dsi_ctrl_enable_status_interrupt(struct dsi_ctrl *dsi_ctrl,
		uint32_t intr_idx, struct dsi_event_cb_info *event_info);

/**
 * dsi_ctrl_disable_status_interrupt() - disable status interrupts
 * @dsi_ctrl:        DSI controller handle.
 * @intr_idx:        Index interrupt to disable.
 */
void dsi_ctrl_disable_status_interrupt(
		struct dsi_ctrl *dsi_ctrl, uint32_t intr_idx);

/**
 * dsi_ctrl_drv_register() - register platform driver for dsi controller
 */
+145 −43
Original line number Diff line number Diff line
@@ -9,7 +9,6 @@
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#ifndef _DSI_CTRL_HW_H_
@@ -83,6 +82,36 @@ enum dsi_test_pattern {
	DSI_TEST_PATTERN_MAX
};

/**
 * enum dsi_status_int_index - index of interrupts generated by DSI controller
 * @DSI_SINT_CMD_MODE_DMA_DONE:        Command mode DMA packets are sent out.
 * @DSI_SINT_CMD_STREAM0_FRAME_DONE:   A frame of cmd mode stream0 is sent out.
 * @DSI_SINT_CMD_STREAM1_FRAME_DONE:   A frame of cmd mode stream1 is sent out.
 * @DSI_SINT_CMD_STREAM2_FRAME_DONE:   A frame of cmd mode stream2 is sent out.
 * @DSI_SINT_VIDEO_MODE_FRAME_DONE:    A frame of video mode stream is sent out.
 * @DSI_SINT_BTA_DONE:                 A BTA is completed.
 * @DSI_SINT_CMD_FRAME_DONE:           A frame of selected cmd mode stream is
 *                                     sent out by MDP.
 * @DSI_SINT_DYN_REFRESH_DONE:         The dynamic refresh operation completed.
 * @DSI_SINT_DESKEW_DONE:              The deskew calibration operation done.
 * @DSI_SINT_DYN_BLANK_DMA_DONE:       The dynamic blankin DMA operation has
 *                                     completed.
 */
enum dsi_status_int_index {
	DSI_SINT_CMD_MODE_DMA_DONE = 0,
	DSI_SINT_CMD_STREAM0_FRAME_DONE = 1,
	DSI_SINT_CMD_STREAM1_FRAME_DONE = 2,
	DSI_SINT_CMD_STREAM2_FRAME_DONE = 3,
	DSI_SINT_VIDEO_MODE_FRAME_DONE = 4,
	DSI_SINT_BTA_DONE = 5,
	DSI_SINT_CMD_FRAME_DONE = 6,
	DSI_SINT_DYN_REFRESH_DONE = 7,
	DSI_SINT_DESKEW_DONE = 8,
	DSI_SINT_DYN_BLANK_DMA_DONE = 9,

	DSI_STATUS_INTERRUPT_COUNT
};

/**
 * enum dsi_status_int_type - status interrupts generated by DSI controller
 * @DSI_CMD_MODE_DMA_DONE:        Command mode DMA packets are sent out.
@@ -99,16 +128,89 @@ enum dsi_test_pattern {
 *                                completed.
 */
enum dsi_status_int_type {
	DSI_CMD_MODE_DMA_DONE = BIT(0),
	DSI_CMD_STREAM0_FRAME_DONE = BIT(1),
	DSI_CMD_STREAM1_FRAME_DONE = BIT(2),
	DSI_CMD_STREAM2_FRAME_DONE = BIT(3),
	DSI_VIDEO_MODE_FRAME_DONE = BIT(4),
	DSI_BTA_DONE = BIT(5),
	DSI_CMD_FRAME_DONE = BIT(6),
	DSI_DYN_REFRESH_DONE = BIT(7),
	DSI_DESKEW_DONE = BIT(8),
	DSI_DYN_BLANK_DMA_DONE = BIT(9)
	DSI_CMD_MODE_DMA_DONE = BIT(DSI_SINT_CMD_MODE_DMA_DONE),
	DSI_CMD_STREAM0_FRAME_DONE = BIT(DSI_SINT_CMD_STREAM0_FRAME_DONE),
	DSI_CMD_STREAM1_FRAME_DONE = BIT(DSI_SINT_CMD_STREAM1_FRAME_DONE),
	DSI_CMD_STREAM2_FRAME_DONE = BIT(DSI_SINT_CMD_STREAM2_FRAME_DONE),
	DSI_VIDEO_MODE_FRAME_DONE = BIT(DSI_SINT_VIDEO_MODE_FRAME_DONE),
	DSI_BTA_DONE = BIT(DSI_SINT_BTA_DONE),
	DSI_CMD_FRAME_DONE = BIT(DSI_SINT_CMD_FRAME_DONE),
	DSI_DYN_REFRESH_DONE = BIT(DSI_SINT_DYN_REFRESH_DONE),
	DSI_DESKEW_DONE = BIT(DSI_SINT_DESKEW_DONE),
	DSI_DYN_BLANK_DMA_DONE = BIT(DSI_SINT_DYN_BLANK_DMA_DONE)
};

/**
 * enum dsi_error_int_index - index of error interrupts from DSI controller
 * @DSI_EINT_RDBK_SINGLE_ECC_ERR:        Single bit ECC error in read packet.
 * @DSI_EINT_RDBK_MULTI_ECC_ERR:         Multi bit ECC error in read packet.
 * @DSI_EINT_RDBK_CRC_ERR:               CRC error in read packet.
 * @DSI_EINT_RDBK_INCOMPLETE_PKT:        Incomplete read packet.
 * @DSI_EINT_PERIPH_ERROR_PKT:           Error packet returned from peripheral,
 * @DSI_EINT_LP_RX_TIMEOUT:              Low power reverse transmission timeout.
 * @DSI_EINT_HS_TX_TIMEOUT:              High speed fwd transmission timeout.
 * @DSI_EINT_BTA_TIMEOUT:                BTA timeout.
 * @DSI_EINT_PLL_UNLOCK:                 PLL has unlocked.
 * @DSI_EINT_DLN0_ESC_ENTRY_ERR:         Incorrect LP Rx escape entry.
 * @DSI_EINT_DLN0_ESC_SYNC_ERR:          LP Rx data is not byte aligned.
 * @DSI_EINT_DLN0_LP_CONTROL_ERR:        Incorrect LP Rx state sequence.
 * @DSI_EINT_PENDING_HS_TX_TIMEOUT:      Pending High-speed transfer timeout.
 * @DSI_EINT_INTERLEAVE_OP_CONTENTION:   Interleave operation contention.
 * @DSI_EINT_CMD_DMA_FIFO_UNDERFLOW:     Command mode DMA FIFO underflow.
 * @DSI_EINT_CMD_MDP_FIFO_UNDERFLOW:     Command MDP FIFO underflow (failed to
 *                                       receive one complete line from MDP).
 * @DSI_EINT_DLN0_HS_FIFO_OVERFLOW:      High speed FIFO data lane 0 overflows.
 * @DSI_EINT_DLN1_HS_FIFO_OVERFLOW:      High speed FIFO data lane 1 overflows.
 * @DSI_EINT_DLN2_HS_FIFO_OVERFLOW:      High speed FIFO data lane 2 overflows.
 * @DSI_EINT_DLN3_HS_FIFO_OVERFLOW:      High speed FIFO data lane 3 overflows.
 * @DSI_EINT_DLN0_HS_FIFO_UNDERFLOW:     High speed FIFO data lane 0 underflows.
 * @DSI_EINT_DLN1_HS_FIFO_UNDERFLOW:     High speed FIFO data lane 1 underflows.
 * @DSI_EINT_DLN2_HS_FIFO_UNDERFLOW:     High speed FIFO data lane 2 underflows.
 * @DSI_EINT_DLN3_HS_FIFO_UNDERFLOW:     High speed FIFO data lane 3 undeflows.
 * @DSI_EINT_DLN0_LP0_CONTENTION:        PHY level contention while lane 0 low.
 * @DSI_EINT_DLN1_LP0_CONTENTION:        PHY level contention while lane 1 low.
 * @DSI_EINT_DLN2_LP0_CONTENTION:        PHY level contention while lane 2 low.
 * @DSI_EINT_DLN3_LP0_CONTENTION:        PHY level contention while lane 3 low.
 * @DSI_EINT_DLN0_LP1_CONTENTION:        PHY level contention while lane 0 high.
 * @DSI_EINT_DLN1_LP1_CONTENTION:        PHY level contention while lane 1 high.
 * @DSI_EINT_DLN2_LP1_CONTENTION:        PHY level contention while lane 2 high.
 * @DSI_EINT_DLN3_LP1_CONTENTION:        PHY level contention while lane 3 high.
 */
enum dsi_error_int_index {
	DSI_EINT_RDBK_SINGLE_ECC_ERR = 0,
	DSI_EINT_RDBK_MULTI_ECC_ERR = 1,
	DSI_EINT_RDBK_CRC_ERR = 2,
	DSI_EINT_RDBK_INCOMPLETE_PKT = 3,
	DSI_EINT_PERIPH_ERROR_PKT = 4,
	DSI_EINT_LP_RX_TIMEOUT = 5,
	DSI_EINT_HS_TX_TIMEOUT = 6,
	DSI_EINT_BTA_TIMEOUT = 7,
	DSI_EINT_PLL_UNLOCK = 8,
	DSI_EINT_DLN0_ESC_ENTRY_ERR = 9,
	DSI_EINT_DLN0_ESC_SYNC_ERR = 10,
	DSI_EINT_DLN0_LP_CONTROL_ERR = 11,
	DSI_EINT_PENDING_HS_TX_TIMEOUT = 12,
	DSI_EINT_INTERLEAVE_OP_CONTENTION = 13,
	DSI_EINT_CMD_DMA_FIFO_UNDERFLOW = 14,
	DSI_EINT_CMD_MDP_FIFO_UNDERFLOW = 15,
	DSI_EINT_DLN0_HS_FIFO_OVERFLOW = 16,
	DSI_EINT_DLN1_HS_FIFO_OVERFLOW = 17,
	DSI_EINT_DLN2_HS_FIFO_OVERFLOW = 18,
	DSI_EINT_DLN3_HS_FIFO_OVERFLOW = 19,
	DSI_EINT_DLN0_HS_FIFO_UNDERFLOW = 20,
	DSI_EINT_DLN1_HS_FIFO_UNDERFLOW = 21,
	DSI_EINT_DLN2_HS_FIFO_UNDERFLOW = 22,
	DSI_EINT_DLN3_HS_FIFO_UNDERFLOW = 23,
	DSI_EINT_DLN0_LP0_CONTENTION = 24,
	DSI_EINT_DLN1_LP0_CONTENTION = 25,
	DSI_EINT_DLN2_LP0_CONTENTION = 26,
	DSI_EINT_DLN3_LP0_CONTENTION = 27,
	DSI_EINT_DLN0_LP1_CONTENTION = 28,
	DSI_EINT_DLN1_LP1_CONTENTION = 29,
	DSI_EINT_DLN2_LP1_CONTENTION = 30,
	DSI_EINT_DLN3_LP1_CONTENTION = 31,

	DSI_ERROR_INTERRUPT_COUNT
};

/**
@@ -148,38 +250,38 @@ enum dsi_status_int_type {
 * @DSI_DLN3_LP1_CONTENTION:        PHY level contention while lane 3 is high.
 */
enum dsi_error_int_type {
	DSI_RDBK_SINGLE_ECC_ERR = BIT(0),
	DSI_RDBK_MULTI_ECC_ERR = BIT(1),
	DSI_RDBK_CRC_ERR = BIT(2),
	DSI_RDBK_INCOMPLETE_PKT = BIT(3),
	DSI_PERIPH_ERROR_PKT = BIT(4),
	DSI_LP_RX_TIMEOUT = BIT(5),
	DSI_HS_TX_TIMEOUT = BIT(6),
	DSI_BTA_TIMEOUT = BIT(7),
	DSI_PLL_UNLOCK = BIT(8),
	DSI_DLN0_ESC_ENTRY_ERR = BIT(9),
	DSI_DLN0_ESC_SYNC_ERR = BIT(10),
	DSI_DLN0_LP_CONTROL_ERR = BIT(11),
	DSI_PENDING_HS_TX_TIMEOUT = BIT(12),
	DSI_INTERLEAVE_OP_CONTENTION = BIT(13),
	DSI_CMD_DMA_FIFO_UNDERFLOW = BIT(14),
	DSI_CMD_MDP_FIFO_UNDERFLOW = BIT(15),
	DSI_DLN0_HS_FIFO_OVERFLOW = BIT(16),
	DSI_DLN1_HS_FIFO_OVERFLOW = BIT(17),
	DSI_DLN2_HS_FIFO_OVERFLOW = BIT(18),
	DSI_DLN3_HS_FIFO_OVERFLOW = BIT(19),
	DSI_DLN0_HS_FIFO_UNDERFLOW = BIT(20),
	DSI_DLN1_HS_FIFO_UNDERFLOW = BIT(21),
	DSI_DLN2_HS_FIFO_UNDERFLOW = BIT(22),
	DSI_DLN3_HS_FIFO_UNDERFLOW = BIT(23),
	DSI_DLN0_LP0_CONTENTION = BIT(24),
	DSI_DLN1_LP0_CONTENTION = BIT(25),
	DSI_DLN2_LP0_CONTENTION = BIT(26),
	DSI_DLN3_LP0_CONTENTION = BIT(27),
	DSI_DLN0_LP1_CONTENTION = BIT(28),
	DSI_DLN1_LP1_CONTENTION = BIT(29),
	DSI_DLN2_LP1_CONTENTION = BIT(30),
	DSI_DLN3_LP1_CONTENTION = BIT(31),
	DSI_RDBK_SINGLE_ECC_ERR = BIT(DSI_EINT_RDBK_SINGLE_ECC_ERR),
	DSI_RDBK_MULTI_ECC_ERR = BIT(DSI_EINT_RDBK_MULTI_ECC_ERR),
	DSI_RDBK_CRC_ERR = BIT(DSI_EINT_RDBK_CRC_ERR),
	DSI_RDBK_INCOMPLETE_PKT = BIT(DSI_EINT_RDBK_INCOMPLETE_PKT),
	DSI_PERIPH_ERROR_PKT = BIT(DSI_EINT_PERIPH_ERROR_PKT),
	DSI_LP_RX_TIMEOUT = BIT(DSI_EINT_LP_RX_TIMEOUT),
	DSI_HS_TX_TIMEOUT = BIT(DSI_EINT_HS_TX_TIMEOUT),
	DSI_BTA_TIMEOUT = BIT(DSI_EINT_BTA_TIMEOUT),
	DSI_PLL_UNLOCK = BIT(DSI_EINT_PLL_UNLOCK),
	DSI_DLN0_ESC_ENTRY_ERR = BIT(DSI_EINT_DLN0_ESC_ENTRY_ERR),
	DSI_DLN0_ESC_SYNC_ERR = BIT(DSI_EINT_DLN0_ESC_SYNC_ERR),
	DSI_DLN0_LP_CONTROL_ERR = BIT(DSI_EINT_DLN0_LP_CONTROL_ERR),
	DSI_PENDING_HS_TX_TIMEOUT = BIT(DSI_EINT_PENDING_HS_TX_TIMEOUT),
	DSI_INTERLEAVE_OP_CONTENTION = BIT(DSI_EINT_INTERLEAVE_OP_CONTENTION),
	DSI_CMD_DMA_FIFO_UNDERFLOW = BIT(DSI_EINT_CMD_DMA_FIFO_UNDERFLOW),
	DSI_CMD_MDP_FIFO_UNDERFLOW = BIT(DSI_EINT_CMD_MDP_FIFO_UNDERFLOW),
	DSI_DLN0_HS_FIFO_OVERFLOW = BIT(DSI_EINT_DLN0_HS_FIFO_OVERFLOW),
	DSI_DLN1_HS_FIFO_OVERFLOW = BIT(DSI_EINT_DLN1_HS_FIFO_OVERFLOW),
	DSI_DLN2_HS_FIFO_OVERFLOW = BIT(DSI_EINT_DLN2_HS_FIFO_OVERFLOW),
	DSI_DLN3_HS_FIFO_OVERFLOW = BIT(DSI_EINT_DLN3_HS_FIFO_OVERFLOW),
	DSI_DLN0_HS_FIFO_UNDERFLOW = BIT(DSI_EINT_DLN0_HS_FIFO_UNDERFLOW),
	DSI_DLN1_HS_FIFO_UNDERFLOW = BIT(DSI_EINT_DLN1_HS_FIFO_UNDERFLOW),
	DSI_DLN2_HS_FIFO_UNDERFLOW = BIT(DSI_EINT_DLN2_HS_FIFO_UNDERFLOW),
	DSI_DLN3_HS_FIFO_UNDERFLOW = BIT(DSI_EINT_DLN3_HS_FIFO_UNDERFLOW),
	DSI_DLN0_LP0_CONTENTION = BIT(DSI_EINT_DLN0_LP0_CONTENTION),
	DSI_DLN1_LP0_CONTENTION = BIT(DSI_EINT_DLN1_LP0_CONTENTION),
	DSI_DLN2_LP0_CONTENTION = BIT(DSI_EINT_DLN2_LP0_CONTENTION),
	DSI_DLN3_LP0_CONTENTION = BIT(DSI_EINT_DLN3_LP0_CONTENTION),
	DSI_DLN0_LP1_CONTENTION = BIT(DSI_EINT_DLN0_LP1_CONTENTION),
	DSI_DLN1_LP1_CONTENTION = BIT(DSI_EINT_DLN1_LP1_CONTENTION),
	DSI_DLN2_LP1_CONTENTION = BIT(DSI_EINT_DLN2_LP1_CONTENTION),
	DSI_DLN3_LP1_CONTENTION = BIT(DSI_EINT_DLN3_LP1_CONTENTION),
};

/**
+2 −0

File changed.

Preview size limit exceeded, changes collapsed.

+9 −1

File changed.

Preview size limit exceeded, changes collapsed.

Loading