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

Commit 34b32d77 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "disp: msm: dsi: disallow backlight update during panel mode switch"

parents 56d95ba3 38425972
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -192,6 +192,14 @@ static void dsi_catalog_phy_2_0_init(struct dsi_phy_hw *phy)
		dsi_phy_hw_calculate_timing_params;
	phy->ops.phy_timing_val = dsi_phy_hw_timing_val_v2_0;
	phy->ops.clamp_ctrl = dsi_phy_hw_v2_0_clamp_ctrl;
	phy->ops.dyn_refresh_ops.dyn_refresh_config =
		dsi_phy_hw_v2_0_dyn_refresh_config;
	phy->ops.dyn_refresh_ops.dyn_refresh_pipe_delay =
		dsi_phy_hw_v2_0_dyn_refresh_pipe_delay;
	phy->ops.dyn_refresh_ops.dyn_refresh_helper =
		dsi_phy_hw_v2_0_dyn_refresh_helper;
	phy->ops.dyn_refresh_ops.cache_phy_timings =
		dsi_phy_hw_v2_0_cache_phy_timings;
}

/**
+8 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
 */

#ifndef _DSI_CATALOG_H_
@@ -80,6 +80,13 @@ void dsi_phy_hw_v2_0_idle_off(struct dsi_phy_hw *phy);
int dsi_phy_hw_timing_val_v2_0(struct dsi_phy_per_lane_cfgs *timing_cfg,
		u32 *timing_val, u32 size);
void dsi_phy_hw_v2_0_clamp_ctrl(struct dsi_phy_hw *phy, bool enable);
void dsi_phy_hw_v2_0_dyn_refresh_helper(struct dsi_phy_hw *phy, u32 offset);
void dsi_phy_hw_v2_0_dyn_refresh_config(struct dsi_phy_hw *phy,
		struct dsi_phy_cfg *cfg, bool is_master);
void dsi_phy_hw_v2_0_dyn_refresh_pipe_delay(struct dsi_phy_hw *phy,
		struct dsi_dyn_clk_delay *delay);
int dsi_phy_hw_v2_0_cache_phy_timings(struct dsi_phy_per_lane_cfgs *timings,
		u32 *dst, u32 size);

/* Definitions for 10nm PHY hardware driver */
void dsi_phy_hw_v3_0_regulator_enable(struct dsi_phy_hw *phy,
+5 −1
Original line number Diff line number Diff line
@@ -106,11 +106,13 @@ struct dsi_link_lp_clk_info {
/**
 * struct link_clk_freq - Clock frequency information for Link clocks
 * @byte_clk_rate:   Frequency of DSI byte_clk in KHz.
 * @byte_intf_clk_rate:   Frequency of DSI byte_intf_clk in KHz.
 * @pixel_clk_rate:  Frequency of DSI pixel_clk in KHz.
 * @esc_clk_rate:    Frequency of DSI escape clock in KHz.
 */
struct link_clk_freq {
	u32 byte_clk_rate;
	u32 byte_intf_clk_rate;
	u32 pix_clk_rate;
	u32 esc_clk_rate;
};
@@ -292,10 +294,12 @@ int dsi_clk_set_pixel_clk_rate(void *client, u64 pixel_clk, u32 index);
 * dsi_clk_set_byte_clk_rate() - set frequency for byte clock
 * @client:       DSI clock client pointer.
 * @byte_clk: Pixel clock rate in Hz.
 * @byte_intf_clk: Byte interface clock rate in Hz.
 * @index:      Index of the DSI controller.
 * return: error code in case of failure or 0 for success.
 */
int dsi_clk_set_byte_clk_rate(void *client, u64 byte_clk, u32 index);
int dsi_clk_set_byte_clk_rate(void *client, u64 byte_clk,
				u64 byte_intf_clk, u32 index);

/**
 * dsi_clk_update_parent() - update parent clocks for specified clock
+8 −7
Original line number Diff line number Diff line
@@ -130,15 +130,16 @@ int dsi_clk_set_pixel_clk_rate(void *client, u64 pixel_clk, u32 index)
 * dsi_clk_set_byte_clk_rate() - set frequency for byte clock
 * @client:	DSI clock client pointer.
 * @byte_clk:	Byte clock rate in Hz.
 * @byte_intf_clk:	Byte interface clock rate in Hz.
 * @index:	Index of the DSI controller.
 * return: error code in case of failure or 0 for success.
 */
int dsi_clk_set_byte_clk_rate(void *client, u64 byte_clk, u32 index)
int dsi_clk_set_byte_clk_rate(void *client, u64 byte_clk,
					u64 byte_intf_clk, u32 index)
{
	int rc = 0;
	struct dsi_clk_client_info *c = client;
	struct dsi_clk_mngr *mngr;
	u64 byte_intf_rate;

	mngr = c->mngr;
	rc = clk_set_rate(mngr->link_clks[index].hs_clks.byte_clk, byte_clk);
@@ -148,12 +149,14 @@ int dsi_clk_set_byte_clk_rate(void *client, u64 byte_clk, u32 index)
		mngr->link_clks[index].freq.byte_clk_rate = byte_clk;

	if (mngr->link_clks[index].hs_clks.byte_intf_clk) {
		byte_intf_rate = mngr->link_clks[index].freq.byte_clk_rate / 2;
		rc = clk_set_rate(mngr->link_clks[index].hs_clks.byte_intf_clk,
				  byte_intf_rate);
				  byte_intf_clk);
		if (rc)
			DSI_ERR("failed to set clk rate for byte intf clk=%d\n",
			       rc);
		else
			mngr->link_clks[index].freq.byte_intf_clk_rate =
								byte_intf_clk;
	}

	return rc;
@@ -344,12 +347,10 @@ static int dsi_link_hs_clk_set_rate(struct dsi_link_hs_clk_info *link_hs_clks,

	/*
	 * If byte_intf_clk is present, set rate for that too.
	 * For DPHY: byte_intf_clk_rate = byte_clk_rate / 2
	 * todo: this needs to be revisited when support for CPHY is added
	 */
	if (link_hs_clks->byte_intf_clk) {
		rc = clk_set_rate(link_hs_clks->byte_intf_clk,
			(l_clks->freq.byte_clk_rate / 2));
				l_clks->freq.byte_intf_clk_rate);
		if (rc) {
			DSI_ERR("set_rate failed for byte_intf_clk rc = %d\n",
				rc);
+34 −43
Original line number Diff line number Diff line
@@ -269,10 +269,6 @@ dsi_ctrl_get_aspace(struct dsi_ctrl *dsi_ctrl,

static void dsi_ctrl_flush_cmd_dma_queue(struct dsi_ctrl *dsi_ctrl)
{
	u32 status;
	u32 mask = DSI_CMD_MODE_DMA_DONE;
	struct dsi_ctrl_hw_ops dsi_hw_ops = dsi_ctrl->hw.ops;

	/*
	 * If a command is triggered right after another command,
	 * check if the previous command transfer is completed. If
@@ -281,21 +277,8 @@ static void dsi_ctrl_flush_cmd_dma_queue(struct dsi_ctrl *dsi_ctrl)
	 * completed before triggering the next command by
	 * flushing the workqueue.
	 */
	status = dsi_hw_ops.get_interrupt_status(&dsi_ctrl->hw);
	if (atomic_read(&dsi_ctrl->dma_irq_trig)) {
		cancel_work_sync(&dsi_ctrl->dma_cmd_wait);
	} else if (status & mask) {
		atomic_set(&dsi_ctrl->dma_irq_trig, 1);
		status |= (DSI_CMD_MODE_DMA_DONE | DSI_BTA_DONE);
		dsi_hw_ops.clear_interrupt_status(
						&dsi_ctrl->hw,
						status);
		dsi_ctrl_disable_status_interrupt(dsi_ctrl,
				DSI_SINT_CMD_MODE_DMA_DONE);
		complete_all(&dsi_ctrl->irq_info.cmd_dma_done);
		cancel_work_sync(&dsi_ctrl->dma_cmd_wait);
		DSI_CTRL_DEBUG(dsi_ctrl,
				"dma_tx done but irq not yet triggered\n");
	} else {
		flush_workqueue(dsi_ctrl->dma_cmd_workq);
	}
@@ -319,24 +302,11 @@ static void dsi_ctrl_dma_cmd_wait_for_done(struct work_struct *work)
	 */
	if (atomic_read(&dsi_ctrl->dma_irq_trig))
		goto done;
	/*
	 * If IRQ wasn't triggered check interrupt status register for
	 * transfer done before waiting.
	 */
	status = dsi_hw_ops.get_interrupt_status(&dsi_ctrl->hw);
	if (status & mask) {
		status |= (DSI_CMD_MODE_DMA_DONE | DSI_BTA_DONE);
		dsi_hw_ops.clear_interrupt_status(&dsi_ctrl->hw,
				status);
		dsi_ctrl_disable_status_interrupt(dsi_ctrl,
				DSI_SINT_CMD_MODE_DMA_DONE);
		goto done;
	}

	ret = wait_for_completion_timeout(
			&dsi_ctrl->irq_info.cmd_dma_done,
			msecs_to_jiffies(DSI_CTRL_TX_TO_MS));
	if (ret == 0) {
	if (ret == 0 && !atomic_read(&dsi_ctrl->dma_irq_trig)) {
		status = dsi_hw_ops.get_interrupt_status(&dsi_ctrl->hw);
		if (status & mask) {
			status |= (DSI_CMD_MODE_DMA_DONE | DSI_BTA_DONE);
@@ -877,9 +847,9 @@ static int dsi_ctrl_update_link_freqs(struct dsi_ctrl *dsi_ctrl,
{
	int rc = 0;
	u32 num_of_lanes = 0;
	u32 bpp, frame_time_us;
	u32 bpp, frame_time_us, byte_intf_clk_div;
	u64 h_period, v_period, bit_rate, pclk_rate, bit_rate_per_lane,
	    byte_clk_rate;
	    byte_clk_rate, byte_intf_clk_rate;
	struct dsi_host_common_cfg *host_cfg = &config->common_config;
	struct dsi_split_link_config *split_link = &host_cfg->split_link;
	struct dsi_mode_info *timing = &config->video_timing;
@@ -924,14 +894,20 @@ static int dsi_ctrl_update_link_freqs(struct dsi_ctrl *dsi_ctrl,
	do_div(pclk_rate, bpp);
	byte_clk_rate = bit_rate_per_lane;
	do_div(byte_clk_rate, 8);
	byte_intf_clk_rate = byte_clk_rate;
	byte_intf_clk_div = host_cfg->byte_intf_clk_div;
	do_div(byte_intf_clk_rate, byte_intf_clk_div);

	DSI_CTRL_DEBUG(dsi_ctrl, "bit_clk_rate = %llu, bit_clk_rate_per_lane = %llu\n",
		 bit_rate, bit_rate_per_lane);
	DSI_CTRL_DEBUG(dsi_ctrl, "byte_clk_rate = %llu, pclk_rate = %llu\n",
		  byte_clk_rate, pclk_rate);
	DSI_CTRL_DEBUG(dsi_ctrl, "byte_clk_rate = %llu, byte_intf_clk = %llu\n",
		  byte_clk_rate, byte_intf_clk_rate);
	DSI_CTRL_DEBUG(dsi_ctrl, "pclk_rate = %llu\n", pclk_rate);

	dsi_ctrl->clk_freq.byte_clk_rate = byte_clk_rate;
	dsi_ctrl->clk_freq.pix_clk_rate = pclk_rate;
	dsi_ctrl->clk_freq.esc_clk_rate = config->esc_clk_rate_hz;
	dsi_ctrl->clk_freq.byte_intf_clk_rate = byte_intf_clk_rate;
	config->bit_clk_rate_hz = dsi_ctrl->clk_freq.byte_clk_rate * 8;

	rc = dsi_clk_set_link_frequencies(clk_handle, dsi_ctrl->clk_freq,
@@ -1268,23 +1244,33 @@ static void dsi_kickoff_msg_tx(struct dsi_ctrl *dsi_ctrl,
		 * result in smmu write faults with DSI as client.
		 */
		if (flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) {
			if (dsi_ctrl->version < DSI_CTRL_VERSION_2_4)
				dsi_hw_ops.soft_reset(&dsi_ctrl->hw);
			dsi_ctrl->cmd_len = 0;
		}
	}
}

static u32 dsi_ctrl_validate_msg_flags(const struct mipi_dsi_msg *msg,
static u32 dsi_ctrl_validate_msg_flags(struct dsi_ctrl *dsi_ctrl,
				const struct mipi_dsi_msg *msg,
				u32 flags)
{
	/*
	 * ASYNC command wait mode is not supported for FIFO commands.
	 * Waiting after a command is transferred cannot be guaranteed
	 * if DSI_CTRL_CMD_ASYNC_WAIT flag is set.
	 * ASYNC command wait mode is not supported for
	 *    - commands sent using DSI FIFO memory
	 *    - DSI read commands
	 *    - DCS commands sent in non-embedded mode
	 *    - whenever an explicit wait time is specificed for the command
	 *      since the wait time cannot be guaranteed in async mode
	 *    - video mode panels
	 */
	if ((flags & DSI_CTRL_CMD_FIFO_STORE) ||
			msg->wait_ms)
		flags & DSI_CTRL_CMD_READ ||
		flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE ||
		msg->wait_ms ||
		(dsi_ctrl->host_config.panel_mode == DSI_OP_VIDEO_MODE))
		flags &= ~DSI_CTRL_CMD_ASYNC_WAIT;

	return flags;
}

@@ -1313,7 +1299,7 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl,
		goto error;
	}

	flags = dsi_ctrl_validate_msg_flags(msg, flags);
	flags = dsi_ctrl_validate_msg_flags(dsi_ctrl, msg, flags);

	if (dsi_ctrl->dma_wait_queued)
		dsi_ctrl_flush_cmd_dma_queue(dsi_ctrl);
@@ -2692,6 +2678,10 @@ void dsi_ctrl_enable_status_interrupt(struct dsi_ctrl *dsi_ctrl,
		dsi_ctrl->hw.ops.enable_status_interrupts(&dsi_ctrl->hw,
				dsi_ctrl->irq_info.irq_stat_mask);
	}

	if (intr_idx == DSI_SINT_CMD_MODE_DMA_DONE)
		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)
@@ -3196,6 +3186,7 @@ int dsi_ctrl_cmd_tx_trigger(struct dsi_ctrl *dsi_ctrl, u32 flags)
					BIT(DSI_FIFO_OVERFLOW), false);

		if (flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) {
			if (dsi_ctrl->version < DSI_CTRL_VERSION_2_4)
				dsi_hw_ops.soft_reset(&dsi_ctrl->hw);
			dsi_ctrl->cmd_len = 0;
		}
Loading