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

Commit d94dd51a 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/sde: update programming sequence for VIG IGC" into msm-4.14

parents 69cbbcb4 f82bb939
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -328,8 +328,9 @@ int sde_connector_get_dither_cfg(struct drm_connector *conn,
	struct sde_connector *c_conn = NULL;
	struct sde_connector_state *c_state = NULL;
	size_t dither_sz = 0;
	u32 *p = (u32 *)cfg;

	if (!conn || !state || !(*cfg))
	if (!conn || !state || !p)
		return -EINVAL;

	c_conn = to_sde_connector(conn);
+58 −30
Original line number Diff line number Diff line
@@ -68,6 +68,8 @@
#define DMA_1D_LUT_IGC_LEN 128
#define DMA_1D_LUT_GC_LEN 128
#define DMA_1D_LUT_IGC_DITHER_OFF 0x408
#define VIG_1D_LUT_IGC_LEN 128
#define VIG_IGC_DATA_MASK (BIT(10) - 1)

#define QSEED3_DE_OFFSET 0x24
#define QSEED3_COEF_LUT_OFF                    0x100
@@ -1824,9 +1826,10 @@ static void vig_igcv5_off(struct sde_hw_pipe *ctx, void *cfg)
void reg_dmav1_setup_vig_igcv5(struct sde_hw_pipe *ctx, void *cfg)
{
	int rc;
	u32 i = 0, reg = 0, index = 0;
	u32 i = 0, j = 0, reg = 0, index = 0;
	u32 offset = 0;
	u32 data[3] = {0};
	u32 lut_sel = 0, lut_enable = 0;
	u32 *data = NULL, *data_ptr = NULL;
	struct drm_msm_igc_lut *igc_lut;
	struct sde_hw_cp_cfg *hw_cfg = cfg;
	struct sde_hw_reg_dma_ops *dma_ops;
@@ -1864,44 +1867,64 @@ void reg_dmav1_setup_vig_igcv5(struct sde_hw_pipe *ctx, void *cfg)
		return;
	}

	data = kzalloc(VIG_1D_LUT_IGC_LEN * sizeof(u32), GFP_KERNEL);
	if (!data)
		return;

	reg = SDE_REG_READ(&ctx->hw, igc_base);
	lut_enable = (reg >> 8) & BIT(0);
	lut_sel = (reg >> 9) & BIT(0);
	/* select LUT table (0 or 1) when 1D LUT is in active mode */
	if (lut_enable)
		lut_sel = (~lut_sel) && BIT(0);

	for (i = 0; i < IGC_TBL_NUM; i++) {
		/* write 0 to the index register */
		index = 0;
		REG_DMA_SETUP_OPS(dma_write_cfg, igc_base + 0x1B0,
			&index, sizeof(index), REG_SINGLE_WRITE, 0, 0, 0);
		rc = dma_ops->setup_payload(&dma_write_cfg);
		if (rc) {
			DRM_ERROR("VIG IGC index write failed ret %d\n", rc);
			goto exit;
		}

		offset = igc_base + 0x1B4 + i * sizeof(u32);
		data_ptr = igc_lut->c0 + (ARRAY_SIZE(igc_lut->c0) * i);
		for (j = 0; j < VIG_1D_LUT_IGC_LEN; j++)
			data[j] = (data_ptr[2 * j] & VIG_IGC_DATA_MASK) |
				(data_ptr[2 * j + 1] & VIG_IGC_DATA_MASK) << 16;

	/* writing to color2_LUT will auto trigger an index update */
	offset = igc_base + 0x1B4;
	for (i = 0; i < IGC_TBL_LEN; i += 2) {
		data[0] = igc_lut->c0[i] | (igc_lut->c0[i + 1] << 16);
		data[1] = igc_lut->c1[i] | (igc_lut->c1[i + 1] << 16);
		data[2] = igc_lut->c2[i] | (igc_lut->c2[i + 1] << 16);
		REG_DMA_SETUP_OPS(dma_write_cfg, offset, data,
			sizeof(data), REG_BLK_WRITE_INC, 3, 0, 0);
				VIG_1D_LUT_IGC_LEN * sizeof(u32),
				REG_BLK_WRITE_INC, 0, 0, 0);
		rc = dma_ops->setup_payload(&dma_write_cfg);
		if (rc) {
			DRM_ERROR("lut write failed ret %d\n", rc);
			return;
			goto exit;
		}
	}
	if (igc_lut->flags & IGC_DITHER_ENABLE) {
		reg = igc_lut->strength & IGC_DITHER_DATA_MASK;
		reg |= BIT(4);
	} else {
		reg = 0;
	}
	REG_DMA_SETUP_OPS(dma_write_cfg, igc_base + 0x1C0,
			&reg, sizeof(reg), REG_SINGLE_WRITE, 0, 0, 0);
	rc = dma_ops->setup_payload(&dma_write_cfg);
	if (rc) {
		DRM_ERROR("dither strength failed ret %d\n", rc);
			return;
		}
		goto exit;
	}

	reg = BIT(8);
	reg = BIT(8) | (lut_sel << 9);
	REG_DMA_SETUP_OPS(dma_write_cfg, igc_base, &reg, sizeof(reg),
		REG_SINGLE_MODIFY, 0, 0, REG_DMA_VIG_IGC_OP_MASK);
	rc = dma_ops->setup_payload(&dma_write_cfg);
	if (rc) {
		DRM_ERROR("setting opcode failed ret %d\n", rc);
		return;
		goto exit;
	}

	REG_DMA_SETUP_KICKOFF(kick_off, hw_cfg->ctl, sspp_buf[IGC][ctx->idx],
@@ -1909,6 +1932,8 @@ void reg_dmav1_setup_vig_igcv5(struct sde_hw_pipe *ctx, void *cfg)
	rc = dma_ops->kick_off(&kick_off);
	if (rc)
		DRM_ERROR("failed to kick off ret %d\n", rc);
exit:
	kfree(data);
}

static void dma_igcv5_off(struct sde_hw_pipe *ctx, void *cfg,
@@ -2011,7 +2036,8 @@ void reg_dmav1_setup_dma_igcv5(struct sde_hw_pipe *ctx, void *cfg,
	}

	for (i = 0; i < DMA_1D_LUT_IGC_LEN; i++)
		data[i] = igc_lut->c0[2 * i] | (igc_lut->c0[2 * i + 1] << 16);
		data[i] = (igc_lut->c0[2 * i] & IGC_DATA_MASK) |
			((igc_lut->c0[2 * i + 1] & IGC_DATA_MASK) << 16);

	if (idx == SDE_SSPP_RECT_SOLO || idx == SDE_SSPP_RECT_0) {
		igc_base = ctx->cap->sblk->igc_blk[0].base -
@@ -2036,6 +2062,9 @@ void reg_dmav1_setup_dma_igcv5(struct sde_hw_pipe *ctx, void *cfg,
	if (igc_lut->flags & IGC_DITHER_ENABLE) {
		reg = igc_lut->strength & IGC_DITHER_DATA_MASK;
		reg |= BIT(4);
	} else {
		reg = 0;
	}
	REG_DMA_SETUP_OPS(dma_write_cfg, igc_dither_off, &reg,
			sizeof(reg), REG_SINGLE_WRITE, 0, 0, 0);
	rc = dma_ops->setup_payload(&dma_write_cfg);
@@ -2043,7 +2072,6 @@ void reg_dmav1_setup_dma_igcv5(struct sde_hw_pipe *ctx, void *cfg,
		DRM_ERROR("failed to set dither strength %d\n", rc);
		goto igc_exit;
	}
	}

	reg = BIT(1);
	REG_DMA_SETUP_OPS(dma_write_cfg, igc_opmode_off, &reg, sizeof(reg),