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

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

Merge "drm/msm/dsi-staging: Add ULPS support for platforms with legacy dsi phy"

parents 3fa09972 35e85887
Loading
Loading
Loading
Loading
+8 −6
Original line number Diff line number Diff line
@@ -75,12 +75,12 @@ static void dsi_catalog_cmn_init(struct dsi_ctrl_hw *ctrl,
	switch (version) {
	case DSI_CTRL_VERSION_1_4:
		ctrl->ops.setup_lane_map = dsi_ctrl_hw_14_setup_lane_map;
		ctrl->ops.ulps_ops.ulps_request = dsi_ctrl_hw_14_ulps_request;
		ctrl->ops.ulps_ops.ulps_exit = dsi_ctrl_hw_14_ulps_exit;
		ctrl->ops.ulps_ops.ulps_request = dsi_ctrl_hw_cmn_ulps_request;
		ctrl->ops.ulps_ops.ulps_exit = dsi_ctrl_hw_cmn_ulps_exit;
		ctrl->ops.wait_for_lane_idle =
			dsi_ctrl_hw_14_wait_for_lane_idle;
		ctrl->ops.ulps_ops.get_lanes_in_ulps =
			dsi_ctrl_hw_14_get_lanes_in_ulps;
			dsi_ctrl_hw_cmn_get_lanes_in_ulps;
		ctrl->ops.clamp_enable = dsi_ctrl_hw_14_clamp_enable;
		ctrl->ops.clamp_disable = dsi_ctrl_hw_14_clamp_disable;
		ctrl->ops.reg_dump_to_buffer =
@@ -117,9 +117,10 @@ static void dsi_catalog_cmn_init(struct dsi_ctrl_hw *ctrl,
			dsi_ctrl_hw_20_wait_for_lane_idle;
		ctrl->ops.reg_dump_to_buffer =
			dsi_ctrl_hw_20_reg_dump_to_buffer;
		ctrl->ops.ulps_ops.ulps_request = NULL;
		ctrl->ops.ulps_ops.ulps_exit = NULL;
		ctrl->ops.ulps_ops.get_lanes_in_ulps = NULL;
		ctrl->ops.ulps_ops.ulps_request = dsi_ctrl_hw_cmn_ulps_request;
		ctrl->ops.ulps_ops.ulps_exit = dsi_ctrl_hw_cmn_ulps_exit;
		ctrl->ops.ulps_ops.get_lanes_in_ulps =
			dsi_ctrl_hw_cmn_get_lanes_in_ulps;
		ctrl->ops.clamp_enable = NULL;
		ctrl->ops.clamp_disable = NULL;
		ctrl->ops.schedule_dma_cmd = dsi_ctrl_hw_22_schedule_dma_cmd;
@@ -197,6 +198,7 @@ static void dsi_catalog_phy_2_0_init(struct dsi_phy_hw *phy)
	phy->ops.calculate_timing_params =
		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;
}

/**
+4 −3
Original line number Diff line number Diff line
@@ -86,6 +86,7 @@ void dsi_phy_hw_v2_0_idle_on(struct dsi_phy_hw *phy, struct dsi_phy_cfg *cfg);
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);

/* Definitions for 10nm PHY hardware driver */
void dsi_phy_hw_v3_0_regulator_enable(struct dsi_phy_hw *phy,
@@ -214,9 +215,9 @@ int dsi_ctrl_hw_cmn_wait_for_cmd_mode_mdp_idle(struct dsi_ctrl_hw *ctrl);
int dsi_ctrl_hw_14_wait_for_lane_idle(struct dsi_ctrl_hw *ctrl, u32 lanes);
void dsi_ctrl_hw_14_setup_lane_map(struct dsi_ctrl_hw *ctrl,
		       struct dsi_lane_map *lane_map);
void dsi_ctrl_hw_14_ulps_request(struct dsi_ctrl_hw *ctrl, u32 lanes);
void dsi_ctrl_hw_14_ulps_exit(struct dsi_ctrl_hw *ctrl, u32 lanes);
u32 dsi_ctrl_hw_14_get_lanes_in_ulps(struct dsi_ctrl_hw *ctrl);
void dsi_ctrl_hw_cmn_ulps_request(struct dsi_ctrl_hw *ctrl, u32 lanes);
void dsi_ctrl_hw_cmn_ulps_exit(struct dsi_ctrl_hw *ctrl, u32 lanes);
u32 dsi_ctrl_hw_cmn_get_lanes_in_ulps(struct dsi_ctrl_hw *ctrl);

void dsi_ctrl_hw_14_clamp_enable(struct dsi_ctrl_hw *ctrl,
				 u32 lanes,
+17 −9
Original line number Diff line number Diff line
/*
 * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
 * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -108,12 +108,14 @@ int dsi_ctrl_hw_14_wait_for_lane_idle(struct dsi_ctrl_hw *ctrl, u32 lanes)
 * Caller should check if lanes are in ULPS mode by calling
 * get_lanes_in_ulps() operation.
 */
void dsi_ctrl_hw_14_ulps_request(struct dsi_ctrl_hw *ctrl, u32 lanes)
void dsi_ctrl_hw_cmn_ulps_request(struct dsi_ctrl_hw *ctrl, u32 lanes)
{
	u32 reg = 0;

	reg = DSI_R32(ctrl, DSI_LANE_CTRL);

	if (lanes & DSI_CLOCK_LANE)
		reg = BIT(4);
		reg |= BIT(4);
	if (lanes & DSI_DATA_LANE_0)
		reg |= BIT(0);
	if (lanes & DSI_DATA_LANE_1)
@@ -143,12 +145,16 @@ void dsi_ctrl_hw_14_ulps_request(struct dsi_ctrl_hw *ctrl, u32 lanes)
 * Caller should check if lanes are in active mode by calling
 * get_lanes_in_ulps() operation.
 */
void dsi_ctrl_hw_14_ulps_exit(struct dsi_ctrl_hw *ctrl, u32 lanes)
void dsi_ctrl_hw_cmn_ulps_exit(struct dsi_ctrl_hw *ctrl, u32 lanes)
{
	u32 reg = 0;
	u32 prev_reg = 0;

	prev_reg = DSI_R32(ctrl, DSI_LANE_CTRL);
	prev_reg &= BIT(24);

	if (lanes & DSI_CLOCK_LANE)
		reg = BIT(12);
		reg |= BIT(12);
	if (lanes & DSI_DATA_LANE_0)
		reg |= BIT(8);
	if (lanes & DSI_DATA_LANE_1)
@@ -162,7 +168,7 @@ void dsi_ctrl_hw_14_ulps_exit(struct dsi_ctrl_hw *ctrl, u32 lanes)
	 * ULPS Exit Request
	 * Hardware requirement is to wait for at least 1ms
	 */
	DSI_W32(ctrl, DSI_LANE_CTRL, reg);
	DSI_W32(ctrl, DSI_LANE_CTRL, reg | prev_reg);
	usleep_range(1000, 1010);
	/*
	 * Sometimes when exiting ULPS, it is possible that some DSI
@@ -170,8 +176,10 @@ void dsi_ctrl_hw_14_ulps_exit(struct dsi_ctrl_hw *ctrl, u32 lanes)
	 * commands not going through. To avoid this, force the lanes
	 * to be in stop state.
	 */
	DSI_W32(ctrl, DSI_LANE_CTRL, reg << 8);
	DSI_W32(ctrl, DSI_LANE_CTRL, 0x0);
	DSI_W32(ctrl, DSI_LANE_CTRL, (reg << 8) | prev_reg);
	wmb(); /* ensure lanes are put to stop state */
	DSI_W32(ctrl, DSI_LANE_CTRL, 0x0 | prev_reg);
	wmb(); /* ensure lanes are put to stop state */

	pr_debug("[DSI_%d] ULPS exit request for lanes=0x%x\n",
		 ctrl->index, lanes);
@@ -186,7 +194,7 @@ void dsi_ctrl_hw_14_ulps_exit(struct dsi_ctrl_hw *ctrl, u32 lanes)
 *
 * Return: List of lanes in ULPS state.
 */
u32 dsi_ctrl_hw_14_get_lanes_in_ulps(struct dsi_ctrl_hw *ctrl)
u32 dsi_ctrl_hw_cmn_get_lanes_in_ulps(struct dsi_ctrl_hw *ctrl)
{
	u32 reg = 0;
	u32 lanes = 0;
+42 −23
Original line number Diff line number Diff line
@@ -1625,7 +1625,6 @@ static int dsi_display_is_ulps_req_valid(struct dsi_display *display,
		bool enable)
{
	/* TODO: make checks based on cont. splash */
	int splash_enabled = false;

	pr_debug("checking ulps req validity\n");

@@ -1659,7 +1658,7 @@ static int dsi_display_is_ulps_req_valid(struct dsi_display *display,
	 * boot animation since it is expected that the clocks would be turned
	 * right back on.
	 */
	if (enable && splash_enabled)
	if (enable && display->is_cont_splash_enabled)
		return false;

	return true;
@@ -1694,40 +1693,60 @@ static int dsi_display_set_ulps(struct dsi_display *display, bool enable)
	}

	m_ctrl = &display->ctrl[display->cmd_master_idx];

	rc = dsi_ctrl_set_ulps(m_ctrl->ctrl, enable);
	if (rc) {
		pr_err("Ulps controller state change(%d) failed\n", enable);
		return rc;
	}
	/*
	 * ULPS entry-exit can be either through the DSI controller or
	 * the DSI PHY depending on hardware variation. For some chipsets,
	 * both controller version and phy version ulps entry-exit ops can
	 * be present. To handle such cases, send ulps request through PHY,
	 * if ulps request is handled in PHY, then no need to send request
	 * through controller.
	 */

	rc = dsi_phy_set_ulps(m_ctrl->phy, &display->config, enable,
			display->clamp_enabled);
	if (rc) {

	if (rc == DSI_PHY_ULPS_ERROR) {
		pr_err("Ulps PHY state change(%d) failed\n", enable);
		return rc;
		return -EINVAL;
	}

	else if (rc == DSI_PHY_ULPS_HANDLED) {
		display_for_each_ctrl(i, display) {
			ctrl = &display->ctrl[i];
			if (!ctrl->ctrl || (ctrl == m_ctrl))
				continue;

		rc = dsi_ctrl_set_ulps(ctrl->ctrl, enable);
			rc = dsi_phy_set_ulps(ctrl->phy, &display->config,
					enable, display->clamp_enabled);
			if (rc == DSI_PHY_ULPS_ERROR) {
				pr_err("Ulps PHY state change(%d) failed\n",
						enable);
				return -EINVAL;
			}
		}
	}

	else if (rc == DSI_PHY_ULPS_NOT_HANDLED) {
		rc = dsi_ctrl_set_ulps(m_ctrl->ctrl, enable);
		if (rc) {
			pr_err("Ulps controller state change(%d) failed\n",
					enable);
			return rc;
		}
		display_for_each_ctrl(i, display) {
			ctrl = &display->ctrl[i];
			if (!ctrl->ctrl || (ctrl == m_ctrl))
				continue;

		rc = dsi_phy_set_ulps(ctrl->phy, &display->config, enable,
					display->clamp_enabled);
			rc = dsi_ctrl_set_ulps(ctrl->ctrl, enable);
			if (rc) {
			pr_err("Ulps PHY state change(%d) failed\n", enable);
				pr_err("Ulps controller state change(%d) failed\n",
						enable);
				return rc;
			}

		}
	}

	display->ulps_enabled = enable;
	return 0;
}
+9 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -33,6 +33,14 @@
		writel_relaxed((val), (dsi_hw)->mmss_misc_base + (off)); \
	} while (0)

#define DSI_MISC_R32(dsi_hw, off) \
	readl_relaxed((dsi_hw)->phy_clamp_base + (off))
#define DSI_MISC_W32(dsi_hw, off, val) \
	do {\
		pr_debug("[DSI_%d][%s] - [0x%08x]\n", \
			(dsi_hw)->index, #off, val); \
		writel_relaxed((val), (dsi_hw)->phy_clamp_base + (off)); \
	} while (0)
#define DSI_DISP_CC_R32(dsi_hw, off) \
	readl_relaxed((dsi_hw)->disp_cc_base + (off))
#define DSI_DISP_CC_W32(dsi_hw, off, val) \
Loading