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

Commit fe03524b authored by Lloyd Atkinson's avatar Lloyd Atkinson Committed by Krishna Srinivas Kundurthi
Browse files

drm/msm/sde: programmable pre-fetch support for video encoders



Add support in encoder for programming early fetch in the
vertical front porch.

Change-Id: I60fcf4a4e6aea80292b590ee14506579123f372d
Signed-off-by: default avatarLloyd Atkinson <latkinso@codeaurora.org>
Signed-off-by: default avatarKrishna Srinivas Kundurthi <kskund@codeaurora.org>
parent a142ec80
Loading
Loading
Loading
Loading
+89 −28
Original line number Diff line number Diff line
@@ -101,37 +101,46 @@ static void bs_set(struct sde_encoder_virt *sde_enc, int idx)
void sde_encoder_get_hw_resources(struct drm_encoder *drm_enc,
				  struct sde_encoder_hw_resources *hw_res)
{
	struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
	struct sde_encoder_virt *sde_enc = NULL;
	int i = 0;

	DBG("");

	if (!hw_res) {
	if (!hw_res || !drm_enc) {
		DRM_ERROR("Invalid pointer");
		return;
	}

	sde_enc = to_sde_encoder_virt(drm_enc);

	/* Query resources used by phys encs, expected to be without overlap */
	memset(hw_res, 0, sizeof(*hw_res));
	for (i = 0; i < sde_enc->num_phys_encs; i++) {
		struct sde_encoder_phys *phys = sde_enc->phys_encs[i];

		if (phys)
		if (phys && phys->phys_ops.get_hw_resources)
			phys->phys_ops.get_hw_resources(phys, hw_res);
	}
}

static void sde_encoder_destroy(struct drm_encoder *drm_enc)
{
	struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
	struct sde_encoder_virt *sde_enc = NULL;
	int i = 0;

	DBG("");

	if (!drm_enc) {
		DRM_ERROR("Invalid pointer");
		return;
	}

	sde_enc = to_sde_encoder_virt(drm_enc);

	for (i = 0; i < ARRAY_SIZE(sde_enc->phys_encs); i++) {
		struct sde_encoder_phys *phys = sde_enc->phys_encs[i];

		if (phys) {
		if (phys && phys->phys_ops.destroy) {
			phys->phys_ops.destroy(phys);
			--sde_enc->num_phys_encs;
			sde_enc->phys_encs[i] = NULL;
@@ -152,70 +161,103 @@ static bool sde_encoder_virt_mode_fixup(struct drm_encoder *drm_enc,
					const struct drm_display_mode *mode,
					struct drm_display_mode *adjusted_mode)
{
	struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
	struct sde_encoder_virt *sde_enc = NULL;
	int i = 0;
	bool ret = true;

	DBG("");

	if (!drm_enc) {
		DRM_ERROR("Invalid pointer");
		return false;
	}

	sde_enc = to_sde_encoder_virt(drm_enc);

	for (i = 0; i < sde_enc->num_phys_encs; i++) {
		struct sde_encoder_phys *phys = sde_enc->phys_encs[i];

		if (phys) {
			phys->phys_ops.mode_fixup(phys, mode, adjusted_mode);
			if (memcmp(mode, adjusted_mode, sizeof(*mode)) != 0) {
				DRM_ERROR("adjusted modes not supported\n");
				return false;
		if (phys && phys->phys_ops.mode_fixup) {
			ret =
			    phys->phys_ops.mode_fixup(phys, mode,
						      adjusted_mode);
			if (!ret) {
				DBG("Mode unsupported by phys_enc %d", i);
				break;
			}

			if (sde_enc->num_phys_encs > 1) {
				DBG("ModeFix only checking 1 phys_enc");
				break;
			}
		}
	}

	return true;
	return ret;
}

static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
				      struct drm_display_mode *mode,
				      struct drm_display_mode *adjusted_mode)
{
	struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
	struct sde_encoder_virt *sde_enc = NULL;
	int i = 0;

	DBG("");

	if (!drm_enc) {
		DRM_ERROR("Invalid pointer");
		return;
	}

	sde_enc = to_sde_encoder_virt(drm_enc);

	for (i = 0; i < sde_enc->num_phys_encs; i++) {
		struct sde_encoder_phys *phys = sde_enc->phys_encs[i];

		if (phys) {
		if (phys && phys->phys_ops.mode_set)
			phys->phys_ops.mode_set(phys, mode, adjusted_mode);
			if (memcmp(mode, adjusted_mode, sizeof(*mode)) != 0)
				DRM_ERROR("adjusted modes not supported\n");
		}
	}
}

static void sde_encoder_virt_enable(struct drm_encoder *drm_enc)
{
	struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
	struct sde_encoder_virt *sde_enc = NULL;
	int i = 0;

	DBG("");

	if (!drm_enc) {
		DRM_ERROR("Invalid pointer");
		return;
	}

	sde_enc = to_sde_encoder_virt(drm_enc);

	bs_set(sde_enc, 1);

	for (i = 0; i < sde_enc->num_phys_encs; i++) {
		struct sde_encoder_phys *phys = sde_enc->phys_encs[i];

		if (phys)
		if (phys && phys->phys_ops.enable)
			phys->phys_ops.enable(phys);
	}
}

static void sde_encoder_virt_disable(struct drm_encoder *drm_enc)
{
	struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
	struct sde_encoder_virt *sde_enc = NULL;
	int i = 0;

	DBG("");

	if (!drm_enc) {
		DRM_ERROR("Invalid pointer");
		return;
	}

	sde_enc = to_sde_encoder_virt(drm_enc);

	for (i = 0; i < sde_enc->num_phys_encs; i++) {
		struct sde_encoder_phys *phys = sde_enc->phys_encs[i];

@@ -256,11 +298,18 @@ static enum sde_intf sde_encoder_get_intf(struct sde_mdss_cfg *catalog,

static void sde_encoder_vblank_callback(struct drm_encoder *drm_enc)
{
	struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
	struct sde_encoder_virt *sde_enc = NULL;
	unsigned long lock_flags;

	DBG("");

	if (!drm_enc) {
		DRM_ERROR("Invalid pointer");
		return;
	}

	sde_enc = to_sde_encoder_virt(drm_enc);

	spin_lock_irqsave(&sde_enc->spin_lock, lock_flags);
	if (sde_enc->kms_vblank_callback)
		sde_enc->kms_vblank_callback(sde_enc->kms_vblank_callback_data);
@@ -286,7 +335,8 @@ static int sde_encoder_virt_add_phys_vid_enc(struct sde_encoder_virt *sde_enc,
		};
		struct sde_encoder_phys *enc =
		    sde_encoder_phys_vid_init(sde_kms, intf_idx, ctl_idx,
				    &sde_enc->base, parent_ops);
					      &sde_enc->base,
					      parent_ops);
		if (IS_ERR(enc))
			ret = PTR_ERR(enc);

@@ -304,6 +354,7 @@ static int sde_encoder_setup_hdmi(struct sde_encoder_virt *sde_enc,
{
	int ret = 0;
	enum sde_intf intf_idx = INTF_MAX;
	enum sde_ctl ctl_idx = CTL_2;

	DBG("");

@@ -314,8 +365,7 @@ static int sde_encoder_setup_hdmi(struct sde_encoder_virt *sde_enc,
	if (!ret)
		ret =
		    sde_encoder_virt_add_phys_vid_enc(sde_enc, sde_kms,
						      intf_idx,
						      CTL_2);
						      intf_idx, ctl_idx);

	return ret;
}
@@ -343,7 +393,8 @@ static int sde_encoder_setup_dsi(struct sde_encoder_virt *sde_enc,
		enum sde_ctl ctl_idx = CTL_0;

		intf_idx = sde_encoder_get_intf(sde_kms->catalog,
				INTF_DSI, dsi_info->h_tile_ids[i]);
						INTF_DSI,
						dsi_info->h_tile_ids[i]);
		if (intf_idx == INTF_MAX) {
			DBG("Error: could not get the interface id");
			ret = -EINVAL;
@@ -511,11 +562,21 @@ void sde_encoder_register_vblank_callback(struct drm_encoder *drm_enc,
 */
void sde_encoders_init(struct drm_device *dev)
{
	struct msm_drm_private *priv = dev->dev_private;
	struct msm_drm_private *priv = NULL;
	int ret = 0;

	DBG("");

	if (!dev || !dev->dev_private) {
		DRM_ERROR("Invalid pointer");
		return;
	}

	priv = dev->dev_private;
	if (!priv->kms) {
		DRM_ERROR("Invalid pointer");
		return;
	}
	/* Start num_encoders at 0, probe functions will increment */
	priv->num_encoders = 0;
	ret = sde_encoder_probe_dsi(dev);
+204 −76
Original line number Diff line number Diff line
@@ -20,23 +20,185 @@
#include "sde_encoder_phys.h"
#include "sde_mdp_formats.h"


#define to_sde_encoder_phys_vid(x) \
	container_of(x, struct sde_encoder_phys_vid, base)

static bool sde_encoder_phys_vid_mode_fixup(struct sde_encoder_phys *drm_enc,
static void drm_mode_to_intf_timing_params(
		const struct sde_encoder_phys *phys_enc,
		const struct drm_display_mode *mode,
					    struct drm_display_mode
					    *adjusted_mode)
		struct intf_timing_params *timing)
{
	memset(timing, 0, sizeof(*timing));
	/*
	 * https://www.kernel.org/doc/htmldocs/drm/ch02s05.html
	 *  Active Region      Front Porch   Sync   Back Porch
	 * <-----------------><------------><-----><----------->
	 * <- [hv]display --->
	 * <--------- [hv]sync_start ------>
	 * <----------------- [hv]sync_end ------->
	 * <---------------------------- [hv]total ------------->
	 */
	timing->width = mode->hdisplay;	/* active width */
	timing->height = mode->vdisplay;	/* active height */
	timing->xres = timing->width;
	timing->yres = timing->height;
	timing->h_back_porch = mode->htotal - mode->hsync_end;
	timing->h_front_porch = mode->hsync_start - mode->hdisplay;
	timing->v_back_porch = mode->vtotal - mode->vsync_end;
	timing->v_front_porch = mode->vsync_start - mode->vdisplay;
	timing->hsync_pulse_width = mode->hsync_end - mode->hsync_start;
	timing->vsync_pulse_width = mode->vsync_end - mode->vsync_start;
	timing->hsync_polarity = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0;
	timing->vsync_polarity = (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0;
	timing->border_clr = 0;
	timing->underflow_clr = 0xff;
	timing->hsync_skew = mode->hskew;

	/* DSI controller cannot handle active-low sync signals. */
	if (phys_enc->hw_intf->cap->type == INTF_DSI) {
		timing->hsync_polarity = 0;
		timing->vsync_polarity = 0;
	}

	/*
	 * For edp only:
	 * DISPLAY_V_START = (VBP * HCYCLE) + HBP
	 * DISPLAY_V_END = (VBP + VACTIVE) * HCYCLE - 1 - HFP
	 */
	/*
	 * if (vid_enc->hw->cap->type == INTF_EDP) {
	 * display_v_start += mode->htotal - mode->hsync_start;
	 * display_v_end -= mode->hsync_start - mode->hdisplay;
	 * }
	 */
}

static inline u32 get_horizontal_total(const struct intf_timing_params *timing)
{
	u32 active = timing->xres;
	u32 inactive =
	    timing->h_back_porch + timing->h_front_porch +
	    timing->hsync_pulse_width;
	return active + inactive;
}

static inline u32 get_vertical_total(const struct intf_timing_params *timing)
{
	u32 active = timing->yres;
	u32 inactive =
	    timing->v_back_porch + timing->v_front_porch +
	    timing->vsync_pulse_width;
	return active + inactive;
}

/*
 * programmable_fetch_get_num_lines:
 *	Number of fetch lines in vertical front porch
 * @timing: Pointer to the intf timing information for the requested mode
 *
 * Returns the number of fetch lines in vertical front porch at which mdp
 * can start fetching the next frame.
 *
 * Number of needed prefetch lines is anything that cannot be absorbed in the
 * start of frame time (back porch + vsync pulse width).
 *
 * Some panels have very large VFP, however we only need a total number of
 * lines based on the chip worst case latencies.
 */
static u32 programmable_fetch_get_num_lines(
		struct sde_encoder_phys *phys_enc,
		const struct intf_timing_params *timing)
{
	u32 worst_case_needed_lines =
	    phys_enc->hw_intf->cap->prog_fetch_lines_worst_case;
	u32 start_of_frame_lines =
	    timing->v_back_porch + timing->vsync_pulse_width;
	u32 needed_vfp_lines = worst_case_needed_lines - start_of_frame_lines;
	u32 actual_vfp_lines = 0;

	/* Fetch must be outside active lines, otherwise undefined. */

	if (start_of_frame_lines >= worst_case_needed_lines) {
		DBG("Programmable fetch is not needed due to large vbp+vsw");
		actual_vfp_lines = 0;
	} else if (timing->v_front_porch < needed_vfp_lines) {
		/* Warn fetch needed, but not enough porch in panel config */
		pr_warn_once
		    ("low vbp+vfp may lead to perf issues in some cases\n");
		DBG("Less vfp than fetch requires, using entire vfp");
		actual_vfp_lines = timing->v_front_porch;
	} else {
		DBG("Room in vfp for needed prefetch");
		actual_vfp_lines = needed_vfp_lines;
	}

	DBG("v_front_porch %u v_back_porch %u vsync_pulse_width %u",
	    timing->v_front_porch, timing->v_back_porch,
	    timing->vsync_pulse_width);
	DBG("wc_lines %u needed_vfp_lines %u actual_vfp_lines %u",
	    worst_case_needed_lines, needed_vfp_lines, actual_vfp_lines);

	return actual_vfp_lines;
}

/*
 * programmable_fetch_config: Programs HW to prefetch lines by offsetting
 *	the start of fetch into the vertical front porch for cases where the
 *	vsync pulse width and vertical back porch time is insufficient
 *
 *	Gets # of lines to pre-fetch, then calculate VSYNC counter value.
 *	HW layer requires VSYNC counter of first pixel of tgt VFP line.
 *
 * @timing: Pointer to the intf timing information for the requested mode
 */
static void programmable_fetch_config(struct sde_encoder_phys *phys_enc,
				      const struct intf_timing_params *timing)
{
	struct intf_prog_fetch f = { 0 };
	u32 vfp_fetch_lines = 0;
	u32 horiz_total = 0;
	u32 vert_total = 0;
	u32 vfp_fetch_start_vsync_counter = 0;
	unsigned long lock_flags;

	if (WARN_ON_ONCE(!phys_enc->hw_intf->ops.setup_prg_fetch))
		return;

	vfp_fetch_lines = programmable_fetch_get_num_lines(phys_enc, timing);
	if (vfp_fetch_lines) {
		vert_total = get_vertical_total(timing);
		horiz_total = get_horizontal_total(timing);
		vfp_fetch_start_vsync_counter =
		    (vert_total - vfp_fetch_lines) * horiz_total + 1;
		f.enable = 1;
		f.fetch_start = vfp_fetch_start_vsync_counter;
	}

	DBG("vfp_fetch_lines %u vfp_fetch_start_vsync_counter %u",
	    vfp_fetch_lines, vfp_fetch_start_vsync_counter);

	spin_lock_irqsave(&phys_enc->spin_lock, lock_flags);
	phys_enc->hw_intf->ops.setup_prg_fetch(phys_enc->hw_intf, &f);
	spin_unlock_irqrestore(&phys_enc->spin_lock, lock_flags);
}

static bool sde_encoder_phys_vid_mode_fixup(
		struct sde_encoder_phys *phys_enc,
		const struct drm_display_mode *mode,
		struct drm_display_mode *adjusted_mode)
{
	DBG("");

	/*
	 * Modifying mode has consequences when the mode comes back to us
	 */
	return true;
}

static void sde_encoder_phys_vid_mode_set(struct sde_encoder_phys *phys_enc,
static void sde_encoder_phys_vid_mode_set(
		struct sde_encoder_phys *phys_enc,
		struct drm_display_mode *mode,
					  struct drm_display_mode
					  *adjusted_mode)
		struct drm_display_mode *adjusted_mode)
{
	mode = adjusted_mode;
	phys_enc->cached_mode = *adjusted_mode;
@@ -48,73 +210,33 @@ static void sde_encoder_phys_vid_mode_set(struct sde_encoder_phys *phys_enc,
	    mode->type, mode->flags);
}

static void sde_encoder_phys_vid_setup_timing_engine(struct sde_encoder_phys
						     *phys_enc)
static void sde_encoder_phys_vid_setup_timing_engine(
		struct sde_encoder_phys *phys_enc)
{
	struct drm_display_mode *mode = &phys_enc->cached_mode;
	struct intf_timing_params p = { 0 };
	uint32_t hsync_polarity = 0;
	uint32_t vsync_polarity = 0;
	struct sde_mdp_format_params *sde_fmt_params = NULL;
	u32 fmt_fourcc = DRM_FORMAT_RGB888;
	u32 fmt_mod = 0;
	unsigned long lock_flags;
	struct sde_hw_intf_cfg intf_cfg = { 0 };

	if (WARN_ON(!phys_enc->hw_intf->ops.setup_timing_gen))
		return;

	if (WARN_ON(!phys_enc->hw_ctl->ops.setup_intf_cfg))
		return;

	DBG("enable mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
	    mode->base.id, mode->name, mode->vrefresh, mode->clock,
	    mode->hdisplay, mode->hsync_start, mode->hsync_end, mode->htotal,
	    mode->vdisplay, mode->vsync_start, mode->vsync_end, mode->vtotal,
	    mode->type, mode->flags);

	/* DSI controller cannot handle active-low sync signals. */
	if (phys_enc->hw_intf->cap->type != INTF_DSI) {
		if (mode->flags & DRM_MODE_FLAG_NHSYNC)
			hsync_polarity = 1;
		if (mode->flags & DRM_MODE_FLAG_NVSYNC)
			vsync_polarity = 1;
	}

	/*
	 * For edp only:
	 * DISPLAY_V_START = (VBP * HCYCLE) + HBP
	 * DISPLAY_V_END = (VBP + VACTIVE) * HCYCLE - 1 - HFP
	 */
	/*
	 * if (vid_enc->hw->cap->type == INTF_EDP) {
	 * display_v_start += mode->htotal - mode->hsync_start;
	 * display_v_end -= mode->hsync_start - mode->hdisplay;
	 * }
	 */

	/*
	 * https://www.kernel.org/doc/htmldocs/drm/ch02s05.html
	 *  Active Region            Front Porch       Sync        Back Porch
	 * <---------------------><----------------><---------><-------------->
	 * <--- [hv]display ----->
	 * <----------- [hv]sync_start ------------>
	 * <------------------- [hv]sync_end ----------------->
	 * <------------------------------ [hv]total ------------------------->
	 */
	drm_mode_to_intf_timing_params(phys_enc, mode, &p);

	sde_fmt_params = sde_mdp_get_format_params(fmt_fourcc, fmt_mod);

	p.width = mode->hdisplay;	/* active width */
	p.height = mode->vdisplay;	/* active height */
	p.xres = p.width;		/* Display panel width */
	p.yres = p.height;		/* Display panel height */
	p.h_back_porch = mode->htotal - mode->hsync_end;
	p.h_front_porch = mode->hsync_start - mode->hdisplay;
	p.v_back_porch = mode->vtotal - mode->vsync_end;
	p.v_front_porch = mode->vsync_start - mode->vdisplay;
	p.hsync_pulse_width = mode->hsync_end - mode->hsync_start;
	p.vsync_pulse_width = mode->vsync_end - mode->vsync_start;
	p.hsync_polarity = hsync_polarity;
	p.vsync_polarity = vsync_polarity;
	p.border_clr = 0;
	p.underflow_clr = 0xff;
	p.hsync_skew = mode->hskew;

	intf_cfg.intf = phys_enc->hw_intf->idx;
	intf_cfg.wb = SDE_NONE;

@@ -123,10 +245,12 @@ static void sde_encoder_phys_vid_setup_timing_engine(struct sde_encoder_phys
			sde_fmt_params);
	phys_enc->hw_ctl->ops.setup_intf_cfg(phys_enc->hw_ctl, &intf_cfg);
	spin_unlock_irqrestore(&phys_enc->spin_lock, lock_flags);

	programmable_fetch_config(phys_enc, &p);
}

static void sde_encoder_phys_vid_wait_for_vblank(struct sde_encoder_phys_vid
						 *vid_enc)
static void sde_encoder_phys_vid_wait_for_vblank(
		struct sde_encoder_phys_vid *vid_enc)
{
	DBG("");
	mdp_irq_wait(vid_enc->base.mdp_kms, vid_enc->vblank_irq.irqmask);
@@ -139,9 +263,7 @@ static void sde_encoder_phys_vid_vblank_irq(struct mdp_irq *irq,
	    container_of(irq, struct sde_encoder_phys_vid,
			 vblank_irq);
	struct sde_encoder_phys *phys_enc = &vid_enc->base;
	struct intf_status status = { 0 };

	phys_enc->hw_intf->ops.get_status(phys_enc->hw_intf, &status);
	phys_enc->parent_ops.handle_vblank_virt(phys_enc->parent);
}

@@ -156,6 +278,9 @@ static void sde_encoder_phys_vid_enable(struct sde_encoder_phys *phys_enc)
	if (WARN_ON(phys_enc->enabled))
		return;

	if (WARN_ON(!phys_enc->hw_intf->ops.enable_timing))
		return;

	sde_encoder_phys_vid_setup_timing_engine(phys_enc);

	spin_lock_irqsave(&phys_enc->spin_lock, lock_flags);
@@ -180,6 +305,9 @@ static void sde_encoder_phys_vid_disable(struct sde_encoder_phys *phys_enc)
	if (WARN_ON(!phys_enc->enabled))
		return;

	if (WARN_ON(!phys_enc->hw_intf->ops.enable_timing))
		return;

	spin_lock_irqsave(&phys_enc->spin_lock, lock_flags);
	phys_enc->hw_intf->ops.enable_timing(phys_enc->hw_intf, 0);
	spin_unlock_irqrestore(&phys_enc->spin_lock, lock_flags);
@@ -206,10 +334,9 @@ static void sde_encoder_phys_vid_destroy(struct sde_encoder_phys *phys_enc)
	kfree(vid_enc);
}

static void sde_encoder_phys_vid_get_hw_resources(struct sde_encoder_phys
						  *phys_enc, struct
						  sde_encoder_hw_resources
						  *hw_res)
static void sde_encoder_phys_vid_get_hw_resources(
		struct sde_encoder_phys *phys_enc,
		struct sde_encoder_hw_resources *hw_res)
{
	DBG("");
	hw_res->intfs[phys_enc->hw_intf->idx] = true;
@@ -225,15 +352,16 @@ static void sde_encoder_phys_vid_init_cbs(struct sde_encoder_phys_ops *ops)
	ops->get_hw_resources = sde_encoder_phys_vid_get_hw_resources;
}

struct sde_encoder_phys *sde_encoder_phys_vid_init(struct sde_kms *sde_kms,
struct sde_encoder_phys *sde_encoder_phys_vid_init(
		struct sde_kms *sde_kms,
		enum sde_intf intf_idx,
		enum sde_ctl ctl_idx,
		struct drm_encoder *parent,
					      struct sde_encoder_virt_ops
					      parent_ops)
		struct sde_encoder_virt_ops parent_ops)
{
	struct sde_encoder_phys *phys_enc = NULL;
	struct sde_encoder_phys_vid *vid_enc = NULL;
	u32 irq_mask = 0x8000000;
	int ret = 0;

	DBG("");
@@ -264,7 +392,7 @@ struct sde_encoder_phys *sde_encoder_phys_vid_init(struct sde_kms *sde_kms,
	phys_enc->parent_ops = parent_ops;
	phys_enc->mdp_kms = &sde_kms->base;
	vid_enc->vblank_irq.irq = sde_encoder_phys_vid_vblank_irq;
	vid_enc->vblank_irq.irqmask = 0x8000000;
	vid_enc->vblank_irq.irqmask = irq_mask;
	spin_lock_init(&phys_enc->spin_lock);

	DBG("Created sde_encoder_phys_vid for intf %d", phys_enc->hw_intf->idx);
+2 −0
Original line number Diff line number Diff line
@@ -372,11 +372,13 @@ struct sde_cdm_cfg {
 * @features           bit mask identifying sub-blocks/features
 * @type:              Interface type(DSI, DP, HDMI)
 * @controller_id:     Controller Instance ID in case of multiple of intf type
 * @prog_fetch_lines_worst_case	Worst case latency num lines needed to prefetch
 */
struct sde_intf_cfg  {
	SDE_HW_BLK_INFO;
	u32 type;   /* interface type*/
	u32 controller_id;
	u32 prog_fetch_lines_worst_case;
};

/**
+8 −4
Original line number Diff line number Diff line
@@ -244,13 +244,17 @@ static inline int set_cfg_1xx_init(struct sde_mdss_cfg *cfg)
		.intf_count = 4,
		.intf = {
			{.id = INTF_0, .base = 0x0006B000,
				.type = INTF_NONE, .controller_id = 0},
				.type = INTF_NONE, .controller_id = 0,
				.prog_fetch_lines_worst_case = 21},
			{.id = INTF_1, .base = 0x0006B800,
				.type = INTF_DSI, .controller_id = 0},
				.type = INTF_DSI, .controller_id = 0,
				.prog_fetch_lines_worst_case = 21},
			{.id = INTF_2, .base = 0x0006C000,
				.type = INTF_DSI, .controller_id = 1},
				.type = INTF_DSI, .controller_id = 1,
				.prog_fetch_lines_worst_case = 21},
			{.id = INTF_3, .base = 0x0006C800,
				.type = INTF_HDMI, .controller_id = 0},
				.type = INTF_HDMI, .controller_id = 0,
				.prog_fetch_lines_worst_case = 21},
		},
		.wb_count = 3,
		.wb = {