diff --git a/Documentation/devicetree/bindings/display/msm/hdmi.txt b/Documentation/devicetree/bindings/display/msm/hdmi.txt index 0ad1e4257553..a0615ac9d73e 100644 --- a/Documentation/devicetree/bindings/display/msm/hdmi.txt +++ b/Documentation/devicetree/bindings/display/msm/hdmi.txt @@ -22,6 +22,7 @@ Required properties: Optional properties: - qcom,hdmi-tx-mux-en-gpio: hdmi mux enable pin +- qcom,hdmi-tx-hpd5v-gpio: hdmi 5v boost pin - qcom,hdmi-tx-mux-sel-gpio: hdmi mux select pin - power-domains: reference to the power domain(s), if available. - pinctrl-names: the pin control state names; should contain "default" diff --git a/arch/arm/boot/dts/qcom/msm8998-sde.dtsi b/arch/arm/boot/dts/qcom/msm8998-sde.dtsi index 93274f391ac1..6db6ec2c3e92 100644 --- a/arch/arm/boot/dts/qcom/msm8998-sde.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-sde.dtsi @@ -176,13 +176,16 @@ qcom,hdmi-tx-ddc-clk-gpio = <&tlmm 32 0>; qcom,hdmi-tx-ddc-data-gpio = <&tlmm 33 0>; qcom,hdmi-tx-hpd-gpio = <&tlmm 34 0>; + qcom,hdmi-tx-hpd5v-gpio = <&tlmm 133 0>; pinctrl-names = "default", "sleep"; pinctrl-0 = <&mdss_hdmi_hpd_active &mdss_hdmi_ddc_active - &mdss_hdmi_cec_active>; + &mdss_hdmi_cec_active + &mdss_hdmi_5v_active>; pinctrl-1 = <&mdss_hdmi_hpd_suspend &mdss_hdmi_ddc_suspend - &mdss_hdmi_cec_suspend>; + &mdss_hdmi_cec_suspend + &mdss_hdmi_5v_suspend>; hpd-gdsc-supply = <&gdsc_mdss>; qcom,supply-names = "hpd-gdsc"; qcom,min-voltage-level = <0>; diff --git a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c index fb893b653c6a..6a020b3d8886 100644 --- a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c +++ b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c @@ -183,6 +183,17 @@ static int _sde_hdmi_gpio_config(struct hdmi *hdmi, bool on) goto error_hpd_gpio; } gpio_direction_output(config->hpd_gpio, 1); + if (config->hpd5v_gpio != -1) { + ret = gpio_request(config->hpd5v_gpio, "HDMI_HPD_5V"); + if (ret) { + SDE_ERROR("'%s'(%d) gpio_request failed: %d\n", + "HDMI_HPD_5V", + config->hpd5v_gpio, + ret); + goto error_hpd5v_gpio; + } + gpio_set_value_cansleep(config->hpd5v_gpio, 1); + } if (config->mux_en_gpio != -1) { ret = gpio_request(config->mux_en_gpio, "HDMI_MUX_EN"); @@ -254,6 +265,8 @@ error_sel_gpio: if (config->mux_en_gpio != -1) gpio_free(config->mux_en_gpio); error_en_gpio: + gpio_free(config->hpd5v_gpio); +error_hpd5v_gpio: gpio_free(config->hpd_gpio); error_hpd_gpio: if (config->ddc_data_gpio != -1) @@ -318,16 +331,19 @@ static int _sde_hdmi_hpd_enable(struct sde_hdmi *sde_hdmi) hdmi_write(hdmi, REG_HDMI_USEC_REFTIMER, 0x0001001b); - /* enable HPD events: */ - hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL, - HDMI_HPD_INT_CTRL_INT_CONNECT | - HDMI_HPD_INT_CTRL_INT_EN); - /* set timeout to 4.1ms (max) for hardware debounce */ spin_lock_irqsave(&hdmi->reg_lock, flags); hpd_ctrl = hdmi_read(hdmi, REG_HDMI_HPD_CTRL); hpd_ctrl |= HDMI_HPD_CTRL_TIMEOUT(0x1fff); + hdmi_write(hdmi, REG_HDMI_HPD_CTRL, + HDMI_HPD_CTRL_ENABLE | hpd_ctrl); + + /* enable HPD events: */ + hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL, + HDMI_HPD_INT_CTRL_INT_CONNECT | + HDMI_HPD_INT_CTRL_INT_EN); + /* Toggle HPD circuit to trigger HPD sense */ hdmi_write(hdmi, REG_HDMI_HPD_CTRL, ~HDMI_HPD_CTRL_ENABLE & hpd_ctrl); @@ -402,7 +418,6 @@ static void _sde_hdmi_connector_irq(struct sde_hdmi *sde_hdmi) (hpd_int_status & HDMI_HPD_INT_STATUS_INT)) { sde_hdmi->connected = !!(hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED); - /* ack & disable (temporarily) HPD events: */ hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL, HDMI_HPD_INT_CTRL_INT_ACK); @@ -430,7 +445,6 @@ static irqreturn_t _sde_hdmi_irq(int irq, void *dev_id) return IRQ_NONE; } hdmi = sde_hdmi->ctrl.ctrl; - /* Process HPD: */ _sde_hdmi_connector_irq(sde_hdmi); @@ -463,7 +477,6 @@ int sde_hdmi_get_info(struct msm_display_info *info, info->intf_type = DRM_MODE_CONNECTOR_HDMIA; info->num_of_h_tiles = 1; info->h_tile_instance[0] = 0; - info->is_connected = true; if (hdmi_display->non_pluggable) { info->capabilities = MSM_DISPLAY_CAP_VID_MODE; hdmi_display->connected = true; @@ -1089,7 +1102,7 @@ int sde_hdmi_drm_init(struct sde_hdmi *display, struct drm_encoder *enc) } rc = devm_request_irq(&pdev->dev, hdmi->irq, - _sde_hdmi_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + _sde_hdmi_irq, IRQF_TRIGGER_HIGH, "sde_hdmi_isr", display); if (rc < 0) { SDE_ERROR("failed to request IRQ%u: %d\n", diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index 723ec887252b..7915562057d6 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -474,7 +474,7 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) hdmi_cfg->mux_en_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-mux-en"); hdmi_cfg->mux_sel_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-mux-sel"); hdmi_cfg->mux_lpm_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-mux-lpm"); - + hdmi_cfg->hpd5v_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-hpd5v"); #else static struct hdmi_platform_config config = {}; static const char *hpd_clk_names[] = { diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h index 5ee7a0feda07..9ce8ff513210 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.h +++ b/drivers/gpu/drm/msm/hdmi/hdmi.h @@ -110,7 +110,9 @@ struct hdmi_platform_config { int pwr_clk_cnt; /* gpio's: */ - int ddc_clk_gpio, ddc_data_gpio, hpd_gpio, mux_en_gpio, mux_sel_gpio; + int ddc_clk_gpio, ddc_data_gpio; + int hpd_gpio, mux_en_gpio; + int mux_sel_gpio, hpd5v_gpio; int mux_lpm_gpio; };