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

Commit 07529f8a 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/dp: retry failed AUX transactions"

parents 80bd186b 2e9914b0
Loading
Loading
Loading
Loading
+50 −2
Original line number Original line Diff line number Diff line
@@ -25,7 +25,46 @@ DP Controller: Required properties:
- qcom,aux-en-gpio:			Specifies the aux-channel enable gpio.
- qcom,aux-en-gpio:			Specifies the aux-channel enable gpio.
- qcom,aux-sel-gpio:		Specifies the aux-channel select gpio.
- qcom,aux-sel-gpio:		Specifies the aux-channel select gpio.
- qcom,usbplug-cc-gpio:		Specifies the usbplug orientation gpio.
- qcom,usbplug-cc-gpio:		Specifies the usbplug orientation gpio.
- qcom,aux-cfg-settings:	An array that specifies the DP AUX configuration settings.
- qcom,aux-cfg0-settings:		Specifies the DP AUX configuration 0 settings. The first
					entry in this array corresponds to the register offset
					within DP AUX, while the remaining entries indicate the
					programmable values.
- qcom,aux-cfg1-settings:		Specifies the DP AUX configuration 1 settings. The first
					entry in this array corresponds to the register offset
					within DP AUX, while the remaining entries indicate the
					programmable values.
- qcom,aux-cfg2-settings:		Specifies the DP AUX configuration 2 settings. The first
					entry in this array corresponds to the register offset
					within DP AUX, while the remaining entries indicate the
					programmable values.
- qcom,aux-cfg3-settings:		Specifies the DP AUX configuration 3 settings. The first
					entry in this array corresponds to the register offset
					within DP AUX, while the remaining entries indicate the
					programmable values.
- qcom,aux-cfg4-settings:		Specifies the DP AUX configuration 4 settings. The first
					entry in this array corresponds to the register offset
					within DP AUX, while the remaining entries indicate the
					programmable values.
- qcom,aux-cfg5-settings:		Specifies the DP AUX configuration 5 settings. The first
					entry in this array corresponds to the register offset
					within DP AUX, while the remaining entries indicate the
					programmable values.
- qcom,aux-cfg6-settings:		Specifies the DP AUX configuration 6 settings. The first
					entry in this array corresponds to the register offset
					within DP AUX, while the remaining entries indicate the
					programmable values.
- qcom,aux-cfg7-settings:		Specifies the DP AUX configuration 7 settings. The first
					entry in this array corresponds to the register offset
					within DP AUX, while the remaining entries indicate the
					programmable values.
- qcom,aux-cfg8-settings:		Specifies the DP AUX configuration 8 settings. The first
					entry in this array corresponds to the register offset
					within DP AUX, while the remaining entries indicate the
					programmable values.
- qcom,aux-cfg9-settings:		Specifies the DP AUX configuration 9 settings. The first
					entry in this array corresponds to the register offset
					within DP AUX, while the remaining entries indicate the
					programmable values.
- qcom,max-pclk-frequency-khz:	An integer specifying the max. pixel clock in KHz supported by Display Port.
- qcom,max-pclk-frequency-khz:	An integer specifying the max. pixel clock in KHz supported by Display Port.
- qcom,dp-usbpd-detection:	Phandle for the PMI regulator node for USB PHY PD detection.
- qcom,dp-usbpd-detection:	Phandle for the PMI regulator node for USB PHY PD detection.
- qcom,<type>-supply-entries:		A node that lists the elements of the supply used by the a particular "type" of DSI module. The module "types"
- qcom,<type>-supply-entries:		A node that lists the elements of the supply used by the a particular "type" of DSI module. The module "types"
@@ -93,7 +132,16 @@ Example:


		qcom,dp-usbpd-detection = <&pmi8998_pdphy>;
		qcom,dp-usbpd-detection = <&pmi8998_pdphy>;


		qcom,aux-cfg-settings = [00 13 04 00 0a 26 0a 03 bb 03];
		qcom,aux-cfg0-settings = [1c 00];
		qcom,aux-cfg1-settings = [20 13 23 1d];
		qcom,aux-cfg2-settings = [24 00];
		qcom,aux-cfg3-settings = [28 00];
		qcom,aux-cfg4-settings = [2c 0a];
		qcom,aux-cfg5-settings = [30 26];
		qcom,aux-cfg6-settings = [34 0a];
		qcom,aux-cfg7-settings = [38 03];
		qcom,aux-cfg8-settings = [3c bb];
		qcom,aux-cfg9-settings = [40 03];
		qcom,max-pclk-frequency-khz = <593470>;
		qcom,max-pclk-frequency-khz = <593470>;
		pinctrl-names = "mdss_dp_active", "mdss_dp_sleep";
		pinctrl-names = "mdss_dp_active", "mdss_dp_sleep";
		pinctrl-0 = <&sde_dp_aux_active &sde_dp_usbplug_cc_active>;
		pinctrl-0 = <&sde_dp_aux_active &sde_dp_usbplug_cc_active>;
+11 −1
Original line number Original line Diff line number Diff line
@@ -411,7 +411,17 @@


		qcom,dp-usbpd-detection = <&pmi8998_pdphy>;
		qcom,dp-usbpd-detection = <&pmi8998_pdphy>;


		qcom,aux-cfg-settings = [00 13 04 00 0a 26 0a 03 bb 03];
		qcom,aux-cfg0-settings = [20 00];
		qcom,aux-cfg1-settings = [24 13 23 1d];
		qcom,aux-cfg2-settings = [28 24];
		qcom,aux-cfg3-settings = [2c 00];
		qcom,aux-cfg4-settings = [30 0a];
		qcom,aux-cfg5-settings = [34 26];
		qcom,aux-cfg6-settings = [38 0a];
		qcom,aux-cfg7-settings = [3c 03];
		qcom,aux-cfg8-settings = [40 bb];
		qcom,aux-cfg9-settings = [44 03];

		qcom,max-pclk-frequency-khz = <576000>;
		qcom,max-pclk-frequency-khz = <576000>;


		qcom,core-supply-entries {
		qcom,core-supply-entries {
+47 −7
Original line number Original line Diff line number Diff line
@@ -28,11 +28,13 @@ struct dp_aux_private {
	struct device *dev;
	struct device *dev;
	struct dp_aux dp_aux;
	struct dp_aux dp_aux;
	struct dp_catalog_aux *catalog;
	struct dp_catalog_aux *catalog;
	struct dp_aux_cfg *cfg;


	struct mutex mutex;
	struct mutex mutex;
	struct completion comp;
	struct completion comp;


	u32 aux_error_num;
	u32 aux_error_num;
	u32 retry_cnt;
	bool cmd_busy;
	bool cmd_busy;
	bool native;
	bool native;
	bool read;
	bool read;
@@ -127,7 +129,7 @@ static int dp_aux_cmd_fifo_tx(struct dp_aux_private *aux,


	timeout = wait_for_completion_timeout(&aux->comp, aux_timeout_ms);
	timeout = wait_for_completion_timeout(&aux->comp, aux_timeout_ms);
	if (!timeout) {
	if (!timeout) {
		pr_err("aux write timeout\n");
		pr_err("aux %s timeout\n", (aux->read ? "read" : "write"));
		return -ETIMEDOUT;
		return -ETIMEDOUT;
	}
	}


@@ -232,6 +234,22 @@ static void dp_aux_isr(struct dp_aux *dp_aux)
		dp_aux_i2c_handler(aux);
		dp_aux_i2c_handler(aux);
}
}


static void dp_aux_reconfig(struct dp_aux *dp_aux)
{
	struct dp_aux_private *aux;

	if (!dp_aux) {
		pr_err("invalid input\n");
		return;
	}

	aux = container_of(dp_aux, struct dp_aux_private, dp_aux);

	aux->catalog->update_aux_cfg(aux->catalog,
			aux->cfg, PHY_AUX_CFG1);
	aux->catalog->reset(aux->catalog);
}

/*
/*
 * This function does the real job to process an AUX transaction.
 * This function does the real job to process an AUX transaction.
 * It will call aux_reset() function to reset the AUX channel,
 * It will call aux_reset() function to reset the AUX channel,
@@ -243,6 +261,7 @@ static ssize_t dp_aux_transfer(struct drm_dp_aux *drm_aux,
	ssize_t ret;
	ssize_t ret;
	int const aux_cmd_native_max = 16;
	int const aux_cmd_native_max = 16;
	int const aux_cmd_i2c_max = 128;
	int const aux_cmd_i2c_max = 128;
	int const retry_count = 5;
	struct dp_aux_private *aux = container_of(drm_aux,
	struct dp_aux_private *aux = container_of(drm_aux,
		struct dp_aux_private, drm_aux);
		struct dp_aux_private, drm_aux);


@@ -270,8 +289,14 @@ static ssize_t dp_aux_transfer(struct drm_dp_aux *drm_aux,
	}
	}


	ret = dp_aux_cmd_fifo_tx(aux, msg);
	ret = dp_aux_cmd_fifo_tx(aux, msg);
	if (ret < 0) {
	if ((ret < 0) && aux->native) {
		aux->catalog->reset(aux->catalog); /* reset aux */
		aux->retry_cnt++;
		if (!(aux->retry_cnt % retry_count))
			aux->catalog->update_aux_cfg(aux->catalog,
				aux->cfg, PHY_AUX_CFG1);
		aux->catalog->reset(aux->catalog);
		goto unlock_exit;
	} else if (ret < 0) {
		goto unlock_exit;
		goto unlock_exit;
	}
	}


@@ -289,6 +314,7 @@ static ssize_t dp_aux_transfer(struct drm_dp_aux *drm_aux,


	/* Return requested size for success or retry */
	/* Return requested size for success or retry */
	ret = msg->size;
	ret = msg->size;
	aux->retry_cnt = 0;


unlock_exit:
unlock_exit:
	aux->cmd_busy = false;
	aux->cmd_busy = false;
@@ -296,11 +322,19 @@ static ssize_t dp_aux_transfer(struct drm_dp_aux *drm_aux,
	return ret;
	return ret;
}
}


static void dp_aux_init(struct dp_aux *dp_aux, u32 *aux_cfg)
static void dp_aux_reset_phy_config_indices(struct dp_aux_cfg *aux_cfg)
{
	int i = 0;

	for (i = 0; i < PHY_AUX_CFG_MAX; i++)
		aux_cfg[i].current_index = 0;
}

static void dp_aux_init(struct dp_aux *dp_aux, struct dp_aux_cfg *aux_cfg)
{
{
	struct dp_aux_private *aux;
	struct dp_aux_private *aux;


	if (!dp_aux) {
	if (!dp_aux || !aux_cfg) {
		pr_err("invalid input\n");
		pr_err("invalid input\n");
		return;
		return;
	}
	}
@@ -309,6 +343,8 @@ static void dp_aux_init(struct dp_aux *dp_aux, u32 *aux_cfg)


	aux->catalog->reset(aux->catalog);
	aux->catalog->reset(aux->catalog);
	aux->catalog->enable(aux->catalog, true);
	aux->catalog->enable(aux->catalog, true);
	aux->retry_cnt = 0;
	dp_aux_reset_phy_config_indices(aux_cfg);
	aux->catalog->setup(aux->catalog, aux_cfg);
	aux->catalog->setup(aux->catalog, aux_cfg);
}
}


@@ -365,13 +401,14 @@ static void dp_aux_deregister(struct dp_aux *dp_aux)
	drm_dp_aux_unregister(&aux->drm_aux);
	drm_dp_aux_unregister(&aux->drm_aux);
}
}


struct dp_aux *dp_aux_get(struct device *dev, struct dp_catalog_aux *catalog)
struct dp_aux *dp_aux_get(struct device *dev, struct dp_catalog_aux *catalog,
		struct dp_aux_cfg *aux_cfg)
{
{
	int rc = 0;
	int rc = 0;
	struct dp_aux_private *aux;
	struct dp_aux_private *aux;
	struct dp_aux *dp_aux;
	struct dp_aux *dp_aux;


	if (!catalog) {
	if (!catalog || !aux_cfg) {
		pr_err("invalid input\n");
		pr_err("invalid input\n");
		rc = -ENODEV;
		rc = -ENODEV;
		goto error;
		goto error;
@@ -389,13 +426,16 @@ struct dp_aux *dp_aux_get(struct device *dev, struct dp_catalog_aux *catalog)


	aux->dev = dev;
	aux->dev = dev;
	aux->catalog = catalog;
	aux->catalog = catalog;
	aux->cfg = aux_cfg;
	dp_aux = &aux->dp_aux;
	dp_aux = &aux->dp_aux;
	aux->retry_cnt = 0;


	dp_aux->isr     = dp_aux_isr;
	dp_aux->isr     = dp_aux_isr;
	dp_aux->init    = dp_aux_init;
	dp_aux->init    = dp_aux_init;
	dp_aux->deinit  = dp_aux_deinit;
	dp_aux->deinit  = dp_aux_deinit;
	dp_aux->drm_aux_register = dp_aux_register;
	dp_aux->drm_aux_register = dp_aux_register;
	dp_aux->drm_aux_deregister = dp_aux_deregister;
	dp_aux->drm_aux_deregister = dp_aux_deregister;
	dp_aux->reconfig = dp_aux_reconfig;


	return dp_aux;
	return dp_aux;
error:
error:
+4 −2
Original line number Original line Diff line number Diff line
@@ -32,11 +32,13 @@ struct dp_aux {
	int (*drm_aux_register)(struct dp_aux *aux);
	int (*drm_aux_register)(struct dp_aux *aux);
	void (*drm_aux_deregister)(struct dp_aux *aux);
	void (*drm_aux_deregister)(struct dp_aux *aux);
	void (*isr)(struct dp_aux *aux);
	void (*isr)(struct dp_aux *aux);
	void (*init)(struct dp_aux *aux, u32 *aux_cfg);
	void (*init)(struct dp_aux *aux, struct dp_aux_cfg *aux_cfg);
	void (*deinit)(struct dp_aux *aux);
	void (*deinit)(struct dp_aux *aux);
	void (*reconfig)(struct dp_aux *aux);
};
};


struct dp_aux *dp_aux_get(struct device *dev, struct dp_catalog_aux *catalog);
struct dp_aux *dp_aux_get(struct device *dev, struct dp_catalog_aux *catalog,
		struct dp_aux_cfg *aux_cfg);
void dp_aux_put(struct dp_aux *aux);
void dp_aux_put(struct dp_aux *aux);


#endif /*__DP_AUX_H_*/
#endif /*__DP_AUX_H_*/
+36 −12
Original line number Original line Diff line number Diff line
@@ -175,11 +175,37 @@ static void dp_catalog_aux_enable(struct dp_catalog_aux *aux, bool enable)
	dp_write(base + DP_AUX_CTRL, aux_ctrl);
	dp_write(base + DP_AUX_CTRL, aux_ctrl);
}
}


static void dp_catalog_aux_setup(struct dp_catalog_aux *aux, u32 *aux_cfg)
static void dp_catalog_aux_update_cfg(struct dp_catalog_aux *aux,
		struct dp_aux_cfg *cfg, enum dp_phy_aux_config_type type)
{
{
	struct dp_catalog_private *catalog;
	struct dp_catalog_private *catalog;
	u32 new_index = 0, current_index = 0;


	if (!aux || !aux_cfg) {
	if (!aux || !cfg || (type >= PHY_AUX_CFG_MAX)) {
		pr_err("invalid input\n");
		return;
	}

	dp_catalog_get_priv(aux);

	current_index = cfg[type].current_index;
	new_index = (current_index + 1) % cfg[type].cfg_cnt;
	pr_debug("Updating %s from 0x%08x to 0x%08x\n",
		dp_phy_aux_config_type_to_string(type),
	cfg[type].lut[current_index], cfg[type].lut[new_index]);

	dp_write(catalog->io->phy_io.base + cfg[type].offset,
			cfg[type].lut[new_index]);
	cfg[type].current_index = new_index;
}

static void dp_catalog_aux_setup(struct dp_catalog_aux *aux,
		struct dp_aux_cfg *cfg)
{
	struct dp_catalog_private *catalog;
	int i = 0;

	if (!aux || !cfg) {
		pr_err("invalid input\n");
		pr_err("invalid input\n");
		return;
		return;
	}
	}
@@ -195,16 +221,13 @@ static void dp_catalog_aux_setup(struct dp_catalog_aux *aux, u32 *aux_cfg)
		QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x3f);
		QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x3f);


	/* DP AUX CFG register programming */
	/* DP AUX CFG register programming */
	dp_write(catalog->io->phy_io.base + DP_PHY_AUX_CFG0, aux_cfg[0]);
	for (i = 0; i < PHY_AUX_CFG_MAX; i++) {
	dp_write(catalog->io->phy_io.base + DP_PHY_AUX_CFG1, aux_cfg[1]);
		pr_debug("%s: offset=0x%08x, value=0x%08x\n",
	dp_write(catalog->io->phy_io.base + DP_PHY_AUX_CFG2, aux_cfg[2]);
			dp_phy_aux_config_type_to_string(i),
	dp_write(catalog->io->phy_io.base + DP_PHY_AUX_CFG3, aux_cfg[3]);
			cfg[i].offset, cfg[i].lut[cfg[i].current_index]);
	dp_write(catalog->io->phy_io.base + DP_PHY_AUX_CFG4, aux_cfg[4]);
		dp_write(catalog->io->phy_io.base + cfg[i].offset,
	dp_write(catalog->io->phy_io.base + DP_PHY_AUX_CFG5, aux_cfg[5]);
			cfg[i].lut[cfg[i].current_index]);
	dp_write(catalog->io->phy_io.base + DP_PHY_AUX_CFG6, aux_cfg[6]);
	}
	dp_write(catalog->io->phy_io.base + DP_PHY_AUX_CFG7, aux_cfg[7]);
	dp_write(catalog->io->phy_io.base + DP_PHY_AUX_CFG8, aux_cfg[8]);
	dp_write(catalog->io->phy_io.base + DP_PHY_AUX_CFG9, aux_cfg[9]);


	dp_write(catalog->io->phy_io.base + DP_PHY_AUX_INTERRUPT_MASK, 0x1F);
	dp_write(catalog->io->phy_io.base + DP_PHY_AUX_INTERRUPT_MASK, 0x1F);
}
}
@@ -723,6 +746,7 @@ struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_io *io)
		.write_data    = dp_catalog_aux_write_data,
		.write_data    = dp_catalog_aux_write_data,
		.write_trans   = dp_catalog_aux_write_trans,
		.write_trans   = dp_catalog_aux_write_trans,
		.reset         = dp_catalog_aux_reset,
		.reset         = dp_catalog_aux_reset,
		.update_aux_cfg = dp_catalog_aux_update_cfg,
		.enable        = dp_catalog_aux_enable,
		.enable        = dp_catalog_aux_enable,
		.setup         = dp_catalog_aux_setup,
		.setup         = dp_catalog_aux_setup,
		.get_irq       = dp_catalog_aux_get_irq,
		.get_irq       = dp_catalog_aux_get_irq,
Loading