Loading Documentation/devicetree/bindings/drm/msm/sde-dp.txt +50 −2 Original line number Original line Diff line number Diff line Loading @@ -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" Loading Loading @@ -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>; Loading arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi +11 −1 Original line number Original line Diff line number Diff line Loading @@ -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 { Loading drivers/gpu/drm/msm/dp/dp_aux.c +47 −7 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } } Loading Loading @@ -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, Loading @@ -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); Loading Loading @@ -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; } } Loading @@ -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; Loading @@ -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; } } Loading @@ -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); } } Loading Loading @@ -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; Loading @@ -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: Loading drivers/gpu/drm/msm/dp/dp_aux.h +4 −2 Original line number Original line Diff line number Diff line Loading @@ -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_*/ drivers/gpu/drm/msm/dp/dp_catalog.c +36 −12 Original line number Original line Diff line number Diff line Loading @@ -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; } } Loading @@ -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); } } Loading Loading @@ -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 Loading
Documentation/devicetree/bindings/drm/msm/sde-dp.txt +50 −2 Original line number Original line Diff line number Diff line Loading @@ -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" Loading Loading @@ -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>; Loading
arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi +11 −1 Original line number Original line Diff line number Diff line Loading @@ -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 { Loading
drivers/gpu/drm/msm/dp/dp_aux.c +47 −7 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } } Loading Loading @@ -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, Loading @@ -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); Loading Loading @@ -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; } } Loading @@ -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; Loading @@ -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; } } Loading @@ -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); } } Loading Loading @@ -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; Loading @@ -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: Loading
drivers/gpu/drm/msm/dp/dp_aux.h +4 −2 Original line number Original line Diff line number Diff line Loading @@ -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_*/
drivers/gpu/drm/msm/dp/dp_catalog.c +36 −12 Original line number Original line Diff line number Diff line Loading @@ -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; } } Loading @@ -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); } } Loading Loading @@ -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