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

Commit 1c374c48 authored by Sandeep Panda's avatar Sandeep Panda Committed by Steve Cohen
Browse files

drm/msm/dsi-staging: enable DSI command DMA scheduling



From HW version 2.2 onwards DSI controller supports scheduling
of DMA command transfer feature, where SW can program on which
vertical blanking line command trigger should happen. This change
adds support for the same in video mode panels.

Change-Id: Idfd52d20d594ff14b9ccc2e4f40e5abd67c457ee
Signed-off-by: default avatarSandeep Panda <spanda@codeaurora.org>
parent d01ea4bf
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ static void dsi_catalog_cmn_init(struct dsi_ctrl_hw *ctrl,
		ctrl->ops.clamp_disable = dsi_ctrl_hw_14_clamp_disable;
		ctrl->ops.reg_dump_to_buffer =
			dsi_ctrl_hw_14_reg_dump_to_buffer;
		ctrl->ops.schedule_dma_cmd = NULL;
		break;
	case DSI_CTRL_VERSION_2_0:
		ctrl->ops.setup_lane_map = dsi_ctrl_hw_20_setup_lane_map;
@@ -88,6 +89,7 @@ static void dsi_catalog_cmn_init(struct dsi_ctrl_hw *ctrl,
		ctrl->ops.ulps_ops.get_lanes_in_ulps = NULL;
		ctrl->ops.clamp_enable = NULL;
		ctrl->ops.clamp_disable = NULL;
		ctrl->ops.schedule_dma_cmd = NULL;
		break;
	case DSI_CTRL_VERSION_2_2:
		ctrl->ops.phy_reset_config = dsi_ctrl_hw_22_phy_reset_config;
@@ -101,6 +103,7 @@ static void dsi_catalog_cmn_init(struct dsi_ctrl_hw *ctrl,
		ctrl->ops.ulps_ops.get_lanes_in_ulps = NULL;
		ctrl->ops.clamp_enable = NULL;
		ctrl->ops.clamp_disable = NULL;
		ctrl->ops.schedule_dma_cmd = dsi_ctrl_hw_22_schedule_dma_cmd;
		break;
	default:
		break;
+1 −0
Original line number Diff line number Diff line
@@ -176,6 +176,7 @@ u32 dsi_ctrl_hw_cmn_get_cmd_read_data(struct dsi_ctrl_hw *ctrl,
				     u32 rx_byte,
				     u32 pkt_size, u32 *hw_read_cnt);
void dsi_ctrl_hw_cmn_clear_rdbk_reg(struct dsi_ctrl_hw *ctrl);
void dsi_ctrl_hw_22_schedule_dma_cmd(struct dsi_ctrl_hw *ctrl, int line_on);

/* Definitions specific to 1.4 DSI controller hardware */
int dsi_ctrl_hw_14_wait_for_lane_idle(struct dsi_ctrl_hw *ctrl, u32 lanes);
+23 −2
Original line number Diff line number Diff line
@@ -905,7 +905,15 @@ static void dsi_ctrl_wait_for_video_done(struct dsi_ctrl *dsi_ctrl)
	u32 v_total = 0, v_blank = 0, sleep_ms = 0, fps = 0, ret;
	struct dsi_mode_info *timing;

	if (dsi_ctrl->host_config.panel_mode != DSI_OP_VIDEO_MODE)
	/**
	 * No need to wait if the panel is not video mode or
	 * if DSI controller supports command DMA scheduling or
	 * if we are sending init commands.
	 */
	if ((dsi_ctrl->host_config.panel_mode != DSI_OP_VIDEO_MODE) ||
		(dsi_ctrl->version >= DSI_CTRL_VERSION_2_2) ||
		(dsi_ctrl->current_state.vid_engine_state !=
					DSI_CTRL_ENGINE_ON))
		return;

	dsi_ctrl->hw.ops.clear_interrupt_status(&dsi_ctrl->hw,
@@ -943,8 +951,9 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl,
	u32 hw_flags = 0;
	u32 length = 0;
	u8 *buffer = NULL;
	u32 cnt = 0;
	u32 cnt = 0, line_no = 0x1;
	u8 *cmdbuf;
	struct dsi_mode_info *timing;

	rc = mipi_dsi_create_packet(&packet, msg);
	if (rc) {
@@ -999,6 +1008,17 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl,
				  true : false;
	}

	timing = &(dsi_ctrl->host_config.video_timing);
	if (timing)
		line_no += timing->v_back_porch + timing->v_sync_width +
				timing->v_active;
	if ((dsi_ctrl->host_config.panel_mode == DSI_OP_VIDEO_MODE) &&
		dsi_ctrl->hw.ops.schedule_dma_cmd &&
		(dsi_ctrl->current_state.vid_engine_state ==
					DSI_CTRL_ENGINE_ON))
		dsi_ctrl->hw.ops.schedule_dma_cmd(&dsi_ctrl->hw,
				line_no);

	hw_flags |= (flags & DSI_CTRL_CMD_DEFER_TRIGGER) ?
			DSI_CTRL_HW_CMD_WAIT_FOR_TRIGGER : 0;

@@ -2505,6 +2525,7 @@ int dsi_ctrl_cmd_tx_trigger(struct dsi_ctrl *dsi_ctrl, u32 flags)

	if ((flags & DSI_CTRL_CMD_BROADCAST) &&
		(flags & DSI_CTRL_CMD_BROADCAST_MASTER)) {
		dsi_ctrl_wait_for_video_done(dsi_ctrl);
		dsi_ctrl_enable_status_interrupt(dsi_ctrl,
					DSI_SINT_CMD_MODE_DMA_DONE, NULL);
		reinit_completion(&dsi_ctrl->irq_info.cmd_dma_done);
+8 −0
Original line number Diff line number Diff line
@@ -721,6 +721,14 @@ struct dsi_ctrl_hw_ops {
	 * @ctrl:         Pointer to the controller host hardware.
	 */
	void (*clear_rdbk_register)(struct dsi_ctrl_hw *ctrl);

	/** schedule_dma_cmd() - Schdeule DMA command transfer on a
	 *                       particular blanking line.
	 * @ctrl:         Pointer to the controller host hardware.
	 * @line_no:      Blanking line number on whihch DMA command
	 *                needs to be sent.
	 */
	void (*schedule_dma_cmd)(struct dsi_ctrl_hw *ctrl, int line_no);
};

/*
+20 −0
Original line number Diff line number Diff line
@@ -17,10 +17,14 @@
#include "dsi_ctrl_hw.h"
#include "dsi_ctrl_reg.h"
#include "dsi_hw.h"
#include "dsi_catalog.h"

/* Equivalent to register DISP_CC_MISC_CMD */
#define DISP_CC_CLAMP_REG_OFF 0x00

/* register to configure DMA scheduling */
#define DSI_DMA_SCHEDULE_CTRL 0x100

/**
 * dsi_ctrl_hw_22_phy_reset_config() - to configure clamp control during ulps
 * @ctrl:          Pointer to the controller host hardware.
@@ -40,3 +44,19 @@ void dsi_ctrl_hw_22_phy_reset_config(struct dsi_ctrl_hw *ctrl,
		reg |= BIT(ctrl->index);
	DSI_DISP_CC_W32(ctrl, DISP_CC_CLAMP_REG_OFF, reg);
}

/**
 * dsi_ctrl_hw_22_schedule_dma_cmd() - to schedule DMA command transfer
 * @ctrl:         Pointer to the controller host hardware.
 * @line_no:      Line number at which command needs to be sent.
 */
void dsi_ctrl_hw_22_schedule_dma_cmd(struct dsi_ctrl_hw *ctrl, int line_no)
{
	u32 reg = 0;

	reg = DSI_R32(ctrl, DSI_DMA_SCHEDULE_CTRL);
	reg |= BIT(28);
	reg |= (line_no & 0xffff);

	DSI_W32(ctrl, DSI_DMA_SCHEDULE_CTRL, reg);
}