summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/fb/mdss-dsi.txt172
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi.c251
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi.h89
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi_host.c31
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi_panel.c7
-rw-r--r--drivers/video/fbdev/msm/msm_mdss_io_8974.c274
6 files changed, 484 insertions, 340 deletions
diff --git a/Documentation/devicetree/bindings/fb/mdss-dsi.txt b/Documentation/devicetree/bindings/fb/mdss-dsi.txt
index 2c520a7f72e0..0e23a0f607f8 100644
--- a/Documentation/devicetree/bindings/fb/mdss-dsi.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-dsi.txt
@@ -11,6 +11,30 @@ Required properties:
"hw-config" = "split_dsi"
- ranges: The standard property which specifies the child address
space, parent address space and the length.
+- vdda-supply: Phandle for vreg regulator device node.
+
+Optional properties:
+- vcca-supply: Phandle for vcca regulator device node.
+- qcom,<type>-supply-entries: A node that lists the elements of the supply used by the
+ a particular "type" of DSI modulee. The module "types"
+ can be "core", "ctrl", and "phy". Within the same type,
+ there can be more than one instance of this binding,
+ in which case the entry would be appended with the
+ supply entry index.
+ e.g. qcom,ctrl-supply-entry@0
+ -- qcom,supply-name: name of the supply (vdd/vdda/vddio)
+ -- qcom,supply-min-voltage: minimum voltage level (uV)
+ -- qcom,supply-max-voltage: maximum voltage level (uV)
+ -- qcom,supply-enable-load: load drawn (uA) from enabled supply
+ -- qcom,supply-disable-load: load drawn (uA) from disabled supply
+ -- qcom,supply-pre-on-sleep: time to sleep (ms) before turning on
+ -- qcom,supply-post-on-sleep: time to sleep (ms) after turning on
+ -- qcom,supply-pre-off-sleep: time to sleep (ms) before turning off
+ -- qcom,supply-post-off-sleep: time to sleep (ms) after turning off
+- qcom,mmss-ulp-clamp-ctrl-offset: Specifies the offset for dsi ulps clamp control register.
+- qcom,mmss-phyreset-ctrl-offset: Specifies the offset for dsi phy reset control register.
+- qcom,timing-db-mode: Boolean specifies dsi timing mode registers are supported or not.
+- qcom,dsi-clk-ln-recovery: Boolean which enables the clk lane recovery
mdss-dsi-ctrl is a dsi controller device which is treated as a subnode of the mdss-dsi device.
@@ -22,10 +46,10 @@ Required properties:
- reg-names: A list of strings that map in order to the list of regs.
"dsi_ctrl" - MDSS DSI controller register region
"dsi_phy" - MDSS DSI PHY register region
+ "dsi_phy_regulator" - MDSS DSI PHY REGULATOR region
"mmss_misc_phys" - Register region for MMSS DSI clamps
- vdd-supply: Phandle for vdd regulator device node.
- vddio-supply: Phandle for vdd-io regulator device node.
-- vdda-supply: Phandle for vreg regulator device node.
- qcom,mdss-fb-map: pHandle that specifies the framebuffer to which the
interface is mapped.
- qcom,mdss-mdp: pHandle that specifies the mdss-mdp device.
@@ -35,33 +59,13 @@ Required properties:
strengthCtrl settings. It use 10 bytes for 8996 pll.
- qcom,platform-lane-config: An array of length 45 or 20 that specifies the PHY
lane configuration settings. It use 20 bytes for 8996 pll.
+- qcom,platform-bist-ctrl: An array of length 6 that specifies the PHY
+ BIST ctrl settings.
- qcom,dsi-pref-prim-pan: phandle that specifies the primary panel to be used
with the controller.
Optional properties:
- label: A string used to describe the controller used.
-
-- reg-names: A list of strings that map in order to the list of regs.
- "dsi_phy_regulator" - MDSS DSI PHY REGULATOR region
-- qcom,platform-bist-ctrl: An array of length 6 that specifies the PHY
- BIST ctrl settings.
-- vcca-supply: Phandle for vcca regulator device node.
-- qcom,<type>-supply-entries: A node that lists the elements of the supply used by the
- a particular "type" of DSI modulee. The module "types"
- can be "core", "ctrl", and "phy". Within the same type,
- there can be more than one instance of this binding,
- in which case the entry would be appended with the
- supply entry index.
- e.g. qcom,ctrl-supply-entry@0
- -- qcom,supply-name: name of the supply (vdd/vdda/vddio)
- -- qcom,supply-min-voltage: minimum voltage level (uV)
- -- qcom,supply-max-voltage: maximum voltage level (uV)
- -- qcom,supply-enable-load: load drawn (uA) from enabled supply
- -- qcom,supply-disable-load: load drawn (uA) from disabled supply
- -- qcom,supply-pre-on-sleep: time to sleep (ms) before turning on
- -- qcom,supply-post-on-sleep: time to sleep (ms) after turning on
- -- qcom,supply-pre-off-sleep: time to sleep (ms) before turning off
- -- qcom,supply-post-off-sleep: time to sleep (ms) after turning off
- qcom,platform-enable-gpio: Specifies the panel lcd/display enable gpio.
- qcom,platform-reset-gpio: Specifies the panel reset gpio.
- qcom,platform-te-gpio: Specifies the gpio used for TE.
@@ -74,11 +78,7 @@ Optional properties:
controller. These pin configurations are installed in the pinctrl
device node. Refer to pinctrl-bindings.txt
- qcom,regulator-ldo-mode: Boolean to enable ldo mode for the dsi phy regulator
-- qcom,mmss-ulp-clamp-ctrl-offset: Specifies the offset for dsi ulps clamp control register.
-- qcom,mmss-phyreset-ctrl-offset: Specifies the offset for dsi phy reset control register.
- qcom,dsi-irq-line: Boolean specifies if DSI has a different irq line than mdp.
-- qcom,timing-db-mode: Boolean specifies dsi timing mode registers are supported or not.
-- qcom,dsi-clk-ln-recovery: Boolean which enables the clk lane recovery
- qcom,lane-map: Specifies the data lane swap configuration.
"lane_map_0123" = <0 1 2 3> (default value)
"lane_map_3012" = <3 0 1 2>
@@ -95,11 +95,70 @@ Example:
hw-config = "single_dsi";
#address-cells = <1>;
#size-cells = <1>;
+ vdda-supply = <&pm8226_l4>;
+ vcca-supply = <&pm8226_l28>;
reg = <0x1a98000 0x1a98000 0x25c
0x1a98500 0x1a98500 0x280
0x1a98780 0x1a98780 0x30
0x193e000 0x193e000 0x30>;
+ qcom,timing-db-mode;
+ qcom,dsi-clk-ln-recovery;
+
+ qcom,core-supply-entries {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,core-supply-entry@0 {
+ reg = <0>;
+ qcom,supply-name = "gdsc";
+ qcom,supply-min-voltage = <0>;
+ qcom,supply-max-voltage = <0>;
+ qcom,supply-enable-load = <0>;
+ qcom,supply-disable-load = <0>;
+ qcom,supply-pre-on-sleep = <0>;
+ qcom,supply-post-on-sleep = <0>;
+ qcom,supply-pre-off-sleep = <0>;
+ qcom,supply-post-off-sleep = <0>;
+ };
+ };
+
+ qcom,phy-supply-entries {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,phy-supply-entry@0 {
+ reg = <0>;
+ qcom,supply-name = "vddio";
+ qcom,supply-min-voltage = <1800000>;
+ qcom,supply-max-voltage = <1800000>;
+ qcom,supply-enable-load = <100000>;
+ qcom,supply-disable-load = <100>;
+ qcom,supply-pre-on-sleep = <0>;
+ qcom,supply-post-on-sleep = <20>;
+ qcom,supply-pre-off-sleep = <0>;
+ qcom,supply-post-off-sleep = <0>;
+ };
+ };
+
+ qcom,ctrl-supply-entries {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,ctrl-supply-entry@0 {
+ reg = <0>;
+ qcom,supply-name = "vdda";
+ qcom,supply-min-voltage = <1200000>;
+ qcom,supply-max-voltage = <1200000>;
+ qcom,supply-enable-load = <100000>;
+ qcom,supply-disable-load = <100>;
+ qcom,supply-pre-on-sleep = <0>;
+ qcom,supply-post-on-sleep = <20>;
+ qcom,supply-pre-off-sleep = <0>;
+ qcom,supply-post-off-sleep = <0>;
+ };
+ };
+
mdss_dsi0: mdss_dsi_ctrl0@fd922800 {
compatible = "qcom,mdss-dsi-ctrl";
label = "MDSS DSI CTRL->0";
@@ -113,8 +172,6 @@ Example:
vdd-supply = <&pm8226_l15>;
vddio-supply = <&pm8226_l8>;
- vdda-supply = <&pm8226_l4>;
- vcca-supply = <&pm8226_l28>;
qcom,mdss-fb-map = <&mdss_fb0>;
qcom,mdss-mdp = <&mdss_mdp>;
@@ -142,63 +199,6 @@ Example:
qcom,platform-bklight-en-gpio = <&msmgpio 86 0>;
qcom,platform-mode-gpio = <&msmgpio 7 0>;
qcom,dsi-irq-line;
- qcom,timing-db-mode;
- qcom,dsi-clk-ln-recovery;
qcom,lane-map = "lane_map_3012";
-
- qcom,core-supply-entries {
- #address-cells = <1>;
- #size-cells = <0>;
-
- qcom,core-supply-entry@0 {
- reg = <0>;
- qcom,supply-name = "gdsc";
- qcom,supply-min-voltage = <0>;
- qcom,supply-max-voltage = <0>;
- qcom,supply-enable-load = <0>;
- qcom,supply-disable-load = <0>;
- qcom,supply-pre-on-sleep = <0>;
- qcom,supply-post-on-sleep = <0>;
- qcom,supply-pre-off-sleep = <0>;
- qcom,supply-post-off-sleep = <0>;
- };
- };
-
- qcom,phy-supply-entries {
- #address-cells = <1>;
- #size-cells = <0>;
-
- qcom,phy-supply-entry@0 {
- reg = <0>;
- qcom,supply-name = "vddio";
- qcom,supply-min-voltage = <1800000>;
- qcom,supply-max-voltage = <1800000>;
- qcom,supply-enable-load = <100000>;
- qcom,supply-disable-load = <100>;
- qcom,supply-pre-on-sleep = <0>;
- qcom,supply-post-on-sleep = <20>;
- qcom,supply-pre-off-sleep = <0>;
- qcom,supply-post-off-sleep = <0>;
- };
- };
-
- qcom,ctrl-supply-entries {
- #address-cells = <1>;
- #size-cells = <0>;
-
- qcom,ctrl-supply-entry@0 {
- reg = <0>;
- qcom,supply-name = "vdda";
- qcom,supply-min-voltage = <1200000>;
- qcom,supply-max-voltage = <1200000>;
- qcom,supply-enable-load = <100000>;
- qcom,supply-disable-load = <100>;
- qcom,supply-pre-on-sleep = <0>;
- qcom,supply-post-on-sleep = <20>;
- qcom,supply-pre-off-sleep = <0>;
- qcom,supply-post-off-sleep = <0>;
- };
- };
-
};
};
diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c
index aa7d870fd4a7..8f04dc4786d7 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.c
+++ b/drivers/video/fbdev/msm/mdss_dsi.c
@@ -48,31 +48,29 @@ static struct mdss_dsi_ctrl_pdata *mdss_dsi_get_ctrl(u32 ctrl_id)
return mdss_dsi_res->ctrl_pdata[ctrl_id];
}
-static int mdss_dsi_regulator_init(struct platform_device *pdev)
+static int mdss_dsi_regulator_init(struct platform_device *pdev,
+ struct dsi_shared_data *sdata)
{
- int rc = 0;
-
- struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
- int i = 0;
+ int rc = 0, i = 0, j = 0;
- if (!pdev) {
+ if (!pdev || !sdata) {
pr_err("%s: invalid input\n", __func__);
return -EINVAL;
}
- ctrl_pdata = platform_get_drvdata(pdev);
- if (!ctrl_pdata) {
- pr_err("%s: invalid driver data\n", __func__);
- return -EINVAL;
- }
-
- for (i = 0; !rc && (i < DSI_MAX_PM); i++) {
+ for (i = DSI_CORE_PM; !rc && (i < DSI_MAX_PM); i++) {
rc = msm_dss_config_vreg(&pdev->dev,
- ctrl_pdata->power_data[i].vreg_config,
- ctrl_pdata->power_data[i].num_vreg, 1);
- if (rc)
+ sdata->power_data[i].vreg_config,
+ sdata->power_data[i].num_vreg, 1);
+ if (rc) {
pr_err("%s: failed to init vregs for %s\n",
__func__, __mdss_dsi_pm_name(i));
+ for (j = i-1; j >= DSI_CORE_PM; j--) {
+ msm_dss_config_vreg(&pdev->dev,
+ sdata->power_data[j].vreg_config,
+ sdata->power_data[j].num_vreg, 0);
+ }
+ }
}
return rc;
@@ -102,8 +100,8 @@ static int mdss_dsi_panel_power_off(struct mdss_panel_data *pdata)
pr_debug("reset disable: pinctrl not enabled\n");
ret = msm_dss_enable_vreg(
- ctrl_pdata->power_data[DSI_PANEL_PM].vreg_config,
- ctrl_pdata->power_data[DSI_PANEL_PM].num_vreg, 0);
+ ctrl_pdata->panel_power_data.vreg_config,
+ ctrl_pdata->panel_power_data.num_vreg, 0);
if (ret)
pr_err("%s: failed to disable vregs for %s\n",
__func__, __mdss_dsi_pm_name(DSI_PANEL_PM));
@@ -126,8 +124,8 @@ static int mdss_dsi_panel_power_on(struct mdss_panel_data *pdata)
panel_data);
ret = msm_dss_enable_vreg(
- ctrl_pdata->power_data[DSI_PANEL_PM].vreg_config,
- ctrl_pdata->power_data[DSI_PANEL_PM].num_vreg, 1);
+ ctrl_pdata->panel_power_data.vreg_config,
+ ctrl_pdata->panel_power_data.num_vreg, 1);
if (ret) {
pr_err("%s: failed to enable vregs for %s\n",
__func__, __mdss_dsi_pm_name(DSI_PANEL_PM));
@@ -1138,6 +1136,13 @@ static int mdss_dsi_pinctrl_set_state(
if (IS_ERR_OR_NULL(ctrl_pdata->pin_res.pinctrl))
return PTR_ERR(ctrl_pdata->pin_res.pinctrl);
+ if (mdss_dsi_is_right_ctrl(ctrl_pdata) &&
+ mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data)) {
+ pr_debug("%s:%d, right ctrl pinctrl config not needed\n",
+ __func__, __LINE__);
+ return 0;
+ }
+
pin_state = active ? ctrl_pdata->pin_res.gpio_state_active
: ctrl_pdata->pin_res.gpio_state_suspend;
if (!IS_ERR_OR_NULL(pin_state)) {
@@ -1412,7 +1417,7 @@ static void __mdss_dsi_update_video_mode_total(struct mdss_panel_data *pdata,
}
ctrl_rev = MIPI_INP(ctrl_pdata->ctrl_base);
/* Flush DSI TIMING registers for 8916/8939 */
- if (ctrl_pdata->timing_db_mode)
+ if (ctrl_pdata->shared_data->timing_db_mode)
MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x1e4, 0x1);
ctrl_pdata->panel_data.panel_info.mipi.frame_rate = new_fps;
@@ -1615,7 +1620,7 @@ static int mdss_dsi_dfps_config(struct mdss_panel_data *pdata, int new_fps)
* reguest.
*/
pinfo = &pdata->panel_info;
- if (pinfo->is_split_display) {
+ if (mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data)) {
if (mdss_dsi_is_right_ctrl(ctrl_pdata)) {
pr_debug("%s DFPS already updated.\n", __func__);
return rc;
@@ -2060,7 +2065,7 @@ static struct device_node *mdss_dsi_config_panel(struct platform_device *pdev)
static int mdss_dsi_ctrl_probe(struct platform_device *pdev)
{
- int rc = 0, i = 0;
+ int rc = 0;
u32 index;
struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
struct device_node *dsi_pan_node = NULL;
@@ -2113,19 +2118,6 @@ static int mdss_dsi_ctrl_probe(struct platform_device *pdev)
if (rc)
pr_warn("%s: failed to get pin resources\n", __func__);
- /* Parse the regulator information */
- for (i = 0; i < DSI_MAX_PM; i++) {
- if (DSI_PANEL_PM == i)
- continue;
- rc = mdss_dsi_get_dt_vreg_data(&pdev->dev, pdev->dev.of_node,
- &ctrl_pdata->power_data[i], i);
- if (rc) {
- DEV_ERR("%s: '%s' get_dt_vreg_data failed.rc=%d\n",
- __func__, __mdss_dsi_pm_name(i), rc);
- goto error_vreg;
- }
- }
-
if (index == 0)
ctrl_pdata->panel_data.panel_info.pdest = DISPLAY_1;
else
@@ -2134,13 +2126,11 @@ static int mdss_dsi_ctrl_probe(struct platform_device *pdev)
dsi_pan_node = mdss_dsi_config_panel(pdev);
if (!dsi_pan_node) {
pr_err("%s: panel configuration failed\n", __func__);
- i--;
- rc = -EINVAL;
- goto error_vreg;
+ return -EINVAL;
}
- if ((mdss_dsi_res->hw_config != SPLIT_DSI) ||
- ((mdss_dsi_res->hw_config == SPLIT_DSI) &&
+ if (!mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data) ||
+ (mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data) &&
(ctrl_pdata->panel_data.panel_info.pdest == DISPLAY_1))) {
rc = mdss_panel_parse_bl_settings(dsi_pan_node, ctrl_pdata);
if (rc) {
@@ -2173,18 +2163,38 @@ static int mdss_dsi_ctrl_probe(struct platform_device *pdev)
error_pan_node:
of_node_put(dsi_pan_node);
- i--;
-error_vreg:
- for (; i >= 0; i--)
- mdss_dsi_put_dt_vreg_data(&pdev->dev,
- &ctrl_pdata->power_data[i]);
return rc;
}
+static int mdss_dsi_parse_dt_params(struct platform_device *pdev,
+ struct dsi_shared_data *sdata)
+{
+ int rc = 0;
+
+ rc = of_property_read_u32(pdev->dev.of_node,
+ "qcom,mmss-ulp-clamp-ctrl-offset",
+ &sdata->ulps_clamp_ctrl_off);
+ if (!rc) {
+ rc = of_property_read_u32(pdev->dev.of_node,
+ "qcom,mmss-phyreset-ctrl-offset",
+ &sdata->ulps_phyrst_ctrl_off);
+ }
+
+ sdata->timing_db_mode = of_property_read_bool(
+ pdev->dev.of_node, "qcom,timing-db-mode");
+
+ sdata->cmd_clk_ln_recovery_en =
+ of_property_read_bool(pdev->dev.of_node,
+ "qcom,dsi-clk-ln-recovery");
+
+ return 0;
+}
+
static void mdss_dsi_res_deinit(struct platform_device *pdev)
{
int i;
struct mdss_dsi_data *dsi_res = platform_get_drvdata(pdev);
+ struct dsi_shared_data *sdata;
if (!dsi_res) {
pr_err("%s: DSI root device drvdata not found\n", __func__);
@@ -2196,6 +2206,26 @@ static void mdss_dsi_res_deinit(struct platform_device *pdev)
devm_kfree(&pdev->dev, dsi_res->ctrl_pdata[i]);
}
+ sdata = dsi_res->shared_data;
+ if (!sdata)
+ goto res_release;
+
+ for (i = (DSI_MAX_PM - 1); i >= DSI_CORE_PM; i--) {
+ if (msm_dss_config_vreg(&pdev->dev,
+ sdata->power_data[i].vreg_config,
+ sdata->power_data[i].num_vreg, 1) < 0)
+ pr_err("%s: failed to de-init vregs for %s\n",
+ __func__, __mdss_dsi_pm_name(i));
+ mdss_dsi_put_dt_vreg_data(&pdev->dev,
+ &sdata->power_data[i]);
+ }
+
+ mdss_dsi_bus_clk_deinit(&pdev->dev, sdata);
+
+ if (sdata)
+ devm_kfree(&pdev->dev, sdata);
+
+res_release:
if (dsi_res)
devm_kfree(&pdev->dev, dsi_res);
@@ -2205,6 +2235,7 @@ static void mdss_dsi_res_deinit(struct platform_device *pdev)
static int mdss_dsi_res_init(struct platform_device *pdev)
{
int rc = 0, i;
+ struct dsi_shared_data *sdata;
mdss_dsi_res = platform_get_drvdata(pdev);
if (!mdss_dsi_res) {
@@ -2218,18 +2249,69 @@ static int mdss_dsi_res_init(struct platform_device *pdev)
goto mem_fail;
}
+ mdss_dsi_res->shared_data = devm_kzalloc(&pdev->dev,
+ sizeof(struct dsi_shared_data),
+ GFP_KERNEL);
+ pr_debug("%s Allocated shared_data=%p\n", __func__,
+ mdss_dsi_res->shared_data);
+ if (!mdss_dsi_res->shared_data) {
+ pr_err("%s Unable to alloc mem for shared_data\n",
+ __func__);
+ rc = -ENOMEM;
+ goto mem_fail;
+ }
+
+ sdata = mdss_dsi_res->shared_data;
+
+ rc = mdss_dsi_parse_dt_params(pdev, sdata);
+ if (rc) {
+ pr_err("%s: failed to parse mdss dsi DT params\n",
+ __func__);
+ goto mem_fail;
+ }
+
+ rc = mdss_dsi_bus_clk_init(pdev, sdata);
+ if (rc) {
+ pr_err("%s: failed to initialize DSI Bus clocks\n",
+ __func__);
+ goto mem_fail;
+ }
+
+ /* Parse the regulator information */
+ for (i = DSI_CORE_PM; i < DSI_MAX_PM; i++) {
+ rc = mdss_dsi_get_dt_vreg_data(&pdev->dev,
+ pdev->dev.of_node, &sdata->power_data[i], i);
+ if (rc) {
+ pr_err("%s: '%s' get_dt_vreg_data failed.rc=%d\n",
+ __func__, __mdss_dsi_pm_name(i), rc);
+ i--;
+ for (; i >= DSI_CORE_PM; i--)
+ mdss_dsi_put_dt_vreg_data(&pdev->dev,
+ &sdata->power_data[i]);
+ goto mem_fail;
+ }
+ }
+ rc = mdss_dsi_regulator_init(pdev, sdata);
+ if (rc) {
+ pr_err("%s: failed to init regulator, rc=%d\n",
+ __func__, rc);
+ goto mem_fail;
+ }
+
for (i = 0; i < DSI_CTRL_MAX; i++) {
mdss_dsi_res->ctrl_pdata[i] = devm_kzalloc(&pdev->dev,
sizeof(struct mdss_dsi_ctrl_pdata),
GFP_KERNEL);
- pr_debug("%s Allocated ctrl_pdata[%d]=%p\n",
- __func__, i, mdss_dsi_res->ctrl_pdata[i]);
if (!mdss_dsi_res->ctrl_pdata[i]) {
pr_err("%s Unable to alloc mem for ctrl=%d\n",
__func__, i);
rc = -ENOMEM;
goto mem_fail;
}
+ pr_debug("%s Allocated ctrl_pdata[%d]=%p\n",
+ __func__, i, mdss_dsi_res->ctrl_pdata[i]);
+ mdss_dsi_res->ctrl_pdata[i]->shared_data =
+ mdss_dsi_res->shared_data;
}
platform_set_drvdata(pdev, mdss_dsi_res);
@@ -2249,22 +2331,29 @@ static int mdss_dsi_parse_hw_cfg(struct platform_device *pdev)
{
const char *data;
struct mdss_dsi_data *dsi_res = platform_get_drvdata(pdev);
+ struct dsi_shared_data *sdata;
if (!dsi_res) {
pr_err("%s: DSI root device drvdata not found\n", __func__);
return -EINVAL;
}
- dsi_res->hw_config = SINGLE_DSI;
+ sdata = mdss_dsi_res->shared_data;
+ if (!sdata) {
+ pr_err("%s: DSI shared data not found\n", __func__);
+ return -EINVAL;
+ }
+
+ sdata->hw_config = SINGLE_DSI;
data = of_get_property(pdev->dev.of_node, "hw-config", NULL);
if (data) {
if (!strcmp(data, "dual_dsi"))
- dsi_res->hw_config = DUAL_DSI;
+ sdata->hw_config = DUAL_DSI;
else if (!strcmp(data, "split_dsi"))
- dsi_res->hw_config = SPLIT_DSI;
+ sdata->hw_config = SPLIT_DSI;
else if (!strcmp(data, "single_dsi"))
- dsi_res->hw_config = SINGLE_DSI;
+ sdata->hw_config = SINGLE_DSI;
else
pr_err("%s: Incorrect string for DSI config:%s. Setting default as SINGLE_DSI\n",
__func__, data);
@@ -2275,7 +2364,7 @@ static int mdss_dsi_parse_hw_cfg(struct platform_device *pdev)
}
pr_debug("%s: DSI h/w configuration is %d\n", __func__,
- dsi_res->hw_config);
+ sdata->hw_config);
return 0;
}
@@ -2346,22 +2435,18 @@ static int mdss_dsi_ctrl_remove(struct platform_device *pdev)
{
struct msm_fb_data_type *mfd;
struct mdss_dsi_ctrl_pdata *ctrl_pdata = platform_get_drvdata(pdev);
- int i = 0;
if (!ctrl_pdata) {
pr_err("%s: no driver data\n", __func__);
return -ENODEV;
}
- for (i = DSI_MAX_PM - 1; i >= 0; i--) {
- if (msm_dss_config_vreg(&pdev->dev,
- ctrl_pdata->power_data[i].vreg_config,
- ctrl_pdata->power_data[i].num_vreg, 1) < 0)
- pr_err("%s: failed to de-init vregs for %s\n",
- __func__, __mdss_dsi_pm_name(i));
- mdss_dsi_put_dt_vreg_data(&pdev->dev,
- &ctrl_pdata->power_data[i]);
- }
+ if (msm_dss_config_vreg(&pdev->dev,
+ ctrl_pdata->panel_power_data.vreg_config,
+ ctrl_pdata->panel_power_data.num_vreg, 1) < 0)
+ pr_err("%s: failed to de-init vregs for %s\n",
+ __func__, __mdss_dsi_pm_name(DSI_PANEL_PM));
+ mdss_dsi_put_dt_vreg_data(&pdev->dev, &ctrl_pdata->panel_power_data);
mfd = platform_get_drvdata(pdev);
msm_dss_iounmap(&ctrl_pdata->mmss_misc_io);
@@ -2500,7 +2585,7 @@ static void mdss_dsi_parse_lane_swap(struct device_node *np, char *dlane_swap)
static int mdss_dsi_parse_ctrl_params(struct platform_device *ctrl_pdev,
struct device_node *pan_node, struct mdss_dsi_ctrl_pdata *ctrl_pdata)
{
- int rc, i, len;
+ int i, len;
struct mdss_panel_info *pinfo = &(ctrl_pdata->panel_data.panel_info);
const char *data;
@@ -2552,26 +2637,11 @@ static int mdss_dsi_parse_ctrl_params(struct platform_device *ctrl_pdev,
pinfo->mipi.dsi_phy_db.lanecfg[i] = data[i];
}
- rc = of_property_read_u32(ctrl_pdev->dev.of_node,
- "qcom,mmss-ulp-clamp-ctrl-offset",
- &ctrl_pdata->ulps_clamp_ctrl_off);
- if (rc && pinfo->mipi.mode == DSI_CMD_MODE) {
- pr_err("%s: dsi clamp register settings missing\n",
- __func__);
- return -EINVAL;
- }
- rc = of_property_read_u32(ctrl_pdev->dev.of_node,
- "qcom,mmss-phyreset-ctrl-offset",
- &ctrl_pdata->ulps_phyrst_ctrl_off);
- if (rc && pinfo->mipi.mode == DSI_CMD_MODE)
- pr_debug("%s: dsi phyreset register settings missing\n",
- __func__);
-
ctrl_pdata->cmd_sync_wait_broadcast = of_property_read_bool(
pan_node, "qcom,cmd-sync-wait-broadcast");
if (ctrl_pdata->cmd_sync_wait_broadcast &&
- (mdss_dsi_res->hw_config == SPLIT_DSI) &&
+ mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data) &&
(pinfo->pdest == DISPLAY_2))
ctrl_pdata->cmd_sync_wait_trigger = true;
@@ -2579,12 +2649,6 @@ static int mdss_dsi_parse_ctrl_params(struct platform_device *ctrl_pdev,
ctrl_pdata->cmd_sync_wait_broadcast,
ctrl_pdata->cmd_sync_wait_trigger);
- ctrl_pdata->timing_db_mode = of_property_read_bool(
- ctrl_pdev->dev.of_node, "qcom,timing-db-mode");
-
- ctrl_pdata->cmd_clk_ln_recovery_en = of_property_read_bool(
- ctrl_pdev->dev.of_node, "qcom,dsi-clk-ln-recovery");
-
mdss_dsi_parse_lane_swap(ctrl_pdev->dev.of_node,
&(ctrl_pdata->dlane_swap));
@@ -2650,6 +2714,7 @@ int dsi_panel_device_register(struct platform_device *ctrl_pdev,
{
struct mipi_panel_info *mipi;
int rc;
+ struct dsi_shared_data *sdata;
struct mdss_panel_info *pinfo = &(ctrl_pdata->panel_data.panel_info);
struct resource *res;
u64 clk_rate;
@@ -2667,14 +2732,16 @@ int dsi_panel_device_register(struct platform_device *ctrl_pdev,
}
rc = mdss_dsi_get_dt_vreg_data(&ctrl_pdev->dev, pan_node,
- &ctrl_pdata->power_data[DSI_PANEL_PM], DSI_PANEL_PM);
+ &ctrl_pdata->panel_power_data, DSI_PANEL_PM);
if (rc) {
DEV_ERR("%s: '%s' get_dt_vreg_data failed.rc=%d\n",
__func__, __mdss_dsi_pm_name(DSI_PANEL_PM), rc);
return rc;
}
- rc = mdss_dsi_regulator_init(ctrl_pdev);
+ rc = msm_dss_config_vreg(&ctrl_pdev->dev,
+ ctrl_pdata->panel_power_data.vreg_config,
+ ctrl_pdata->panel_power_data.num_vreg, 1);
if (rc) {
pr_err("%s: failed to init regulator, rc=%d\n",
__func__, rc);
@@ -2698,7 +2765,7 @@ int dsi_panel_device_register(struct platform_device *ctrl_pdev,
return rc;
}
- if (mdss_dsi_clk_init(ctrl_pdev, ctrl_pdata)) {
+ if (mdss_dsi_link_clk_init(ctrl_pdev, ctrl_pdata)) {
pr_err("%s: unable to initialize Dsi ctrl clks\n", __func__);
return -EPERM;
}
@@ -2773,10 +2840,12 @@ int dsi_panel_device_register(struct platform_device *ctrl_pdev,
* This is needed for the DSI PHY to maintain ULPS state during
* suspend also.
*/
+ sdata = ctrl_pdata->shared_data;
+
if (pinfo->ulps_suspend_enabled) {
rc = msm_dss_enable_vreg(
- ctrl_pdata->power_data[DSI_CTRL_PM].vreg_config,
- ctrl_pdata->power_data[DSI_CTRL_PM].num_vreg, 1);
+ sdata->power_data[DSI_PHY_PM].vreg_config,
+ sdata->power_data[DSI_PHY_PM].num_vreg, 1);
if (rc) {
pr_err("%s: failed to enable vregs for DSI_CTRL_PM\n",
__func__);
diff --git a/drivers/video/fbdev/msm/mdss_dsi.h b/drivers/video/fbdev/msm/mdss_dsi.h
index a8076b6cac91..e6963c1426ae 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.h
+++ b/drivers/video/fbdev/msm/mdss_dsi.h
@@ -120,10 +120,11 @@ enum dsi_lane_map_type {
};
enum dsi_pm_type {
+ /* PANEL_PM not used as part of power_data in dsi_shared_data */
+ DSI_PANEL_PM,
DSI_CORE_PM,
DSI_CTRL_PM,
DSI_PHY_PM,
- DSI_PANEL_PM,
DSI_MAX_PM
};
@@ -210,12 +211,43 @@ enum {
DSI_CTRL_MAX,
};
-struct mdss_dsi_data {
+/*
+ * Common DSI properties for each controller. The DSI root probe will create the
+ * shared_data struct which should be accessible to each controller. The goal is
+ * to only access ctrl_pdata and ctrl_pdata->shared_data during the lifetime of
+ * each controller i.e. mdss_dsi_res should not be used directly.
+ */
+struct dsi_shared_data {
u32 hw_config; /* DSI setup configuration i.e. single/dual/split */
+ u32 hw_rev; /* DSI h/w revision */
+
+ /* DSI ULPS clamp register offsets */
+ u32 ulps_clamp_ctrl_off;
+ u32 ulps_phyrst_ctrl_off;
+
+ bool timing_db_mode;
+ bool cmd_clk_ln_recovery_en;
+
+ /* DSI bus clocks */
+ struct clk *mdp_core_clk;
+ struct clk *ahb_clk;
+ struct clk *axi_clk;
+ struct clk *mmss_misc_ahb_clk;
+
+ /* DSI core regulators */
+ struct dss_module_power power_data[DSI_MAX_PM];
+};
+
+struct mdss_dsi_data {
bool res_init;
struct platform_device *pdev;
/* List of controller specific struct data */
struct mdss_dsi_ctrl_pdata *ctrl_pdata[DSI_CTRL_MAX];
+ /*
+ * This structure should hold common data structures like
+ * mutex, clocks, regulator information, setup information
+ */
+ struct dsi_shared_data *shared_data;
};
/*
@@ -298,7 +330,6 @@ struct mdss_dsi_ctrl_pdata {
void (*switch_mode) (struct mdss_panel_data *pdata, int mode);
struct mdss_panel_data panel_data;
unsigned char *ctrl_base;
- u32 hw_rev;
struct dss_io_data ctrl_io;
struct dss_io_data mmss_misc_io;
struct dss_io_data phy_io;
@@ -306,10 +337,6 @@ struct mdss_dsi_ctrl_pdata {
u32 bus_clk_cnt;
u32 link_clk_cnt;
u32 flags;
- struct clk *mdp_core_clk;
- struct clk *ahb_clk;
- struct clk *axi_clk;
- struct clk *mmss_misc_ahb_clk;
struct clk *byte_clk;
struct clk *esc_clk;
struct clk *pixel_clk;
@@ -342,7 +369,6 @@ struct mdss_dsi_ctrl_pdata {
bool dcs_cmd_insert;
atomic_t te_irq_ready;
- bool cmd_clk_ln_recovery_en;
bool cmd_sync_wait_broadcast;
bool cmd_sync_wait_trigger;
@@ -352,7 +378,8 @@ struct mdss_dsi_ctrl_pdata {
u32 pclk_rate;
u32 byte_clk_rate;
bool refresh_clk_rate; /* flag to recalculate clk_rate */
- struct dss_module_power power_data[DSI_MAX_PM];
+ struct dss_module_power panel_power_data;
+ struct dss_module_power power_data[DSI_MAX_PM]; /* for 8x10 */
u32 dsi_irq_mask;
struct mdss_hw *dsi_hw;
struct mdss_intf_recovery *recovery;
@@ -385,12 +412,9 @@ struct mdss_dsi_ctrl_pdata {
struct regulator *ibb; /* vreg handle */
struct mutex clk_lane_mutex;
- u32 ulps_clamp_ctrl_off;
- u32 ulps_phyrst_ctrl_off;
bool ulps;
bool core_power;
bool mmss_clamp;
- bool timing_db_mode;
char dlane_swap; /* data lane swap */
struct dsi_buf tx_buf;
@@ -409,6 +433,7 @@ struct mdss_dsi_ctrl_pdata {
int horizontal_idle_cnt;
struct panel_horizontal_idle *line_idle;
struct mdss_util_intf *mdss_util;
+ struct dsi_shared_data *shared_data;
/* debugfs structure */
struct mdss_dsi_debugfs_info *debugfs_info;
@@ -454,14 +479,20 @@ void mdss_dsi_irq_handler_config(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
void mdss_dsi_set_tx_power_mode(int mode, struct mdss_panel_data *pdata);
int mdss_dsi_clk_div_config(struct mdss_panel_info *panel_info,
int frame_rate);
-int mdss_dsi_clk_init(struct platform_device *pdev,
+int mdss_dsi_link_clk_init(struct platform_device *pdev,
struct mdss_dsi_ctrl_pdata *ctrl_pdata);
+void mdss_dsi_link_clk_deinit(struct device *dev,
+ struct mdss_dsi_ctrl_pdata *ctrl_pdata);
+int mdss_dsi_bus_clk_init(struct platform_device *pdev,
+ struct dsi_shared_data *sdata);
+void mdss_dsi_bus_clk_deinit(struct device *dev,
+ struct dsi_shared_data *sdata);
int mdss_dsi_shadow_clk_init(struct platform_device *pdev,
struct mdss_dsi_ctrl_pdata *ctrl_pdata);
+void mdss_dsi_shadow_clk_deinit(struct device *dev,
+ struct mdss_dsi_ctrl_pdata *ctrl_pdata);
int mdss_dsi_pll_1_clk_init(struct platform_device *pdev,
struct mdss_dsi_ctrl_pdata *ctrl_pdata);
-void mdss_dsi_clk_deinit(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
-void mdss_dsi_shadow_clk_deinit(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
int mdss_dsi_enable_bus_clocks(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
void mdss_dsi_disable_bus_clocks(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
int mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable);
@@ -521,14 +552,24 @@ static inline const char *__mdss_dsi_pm_supply_node_name(
}
}
-static inline bool mdss_dsi_split_display_enabled(void)
+static inline u32 mdss_dsi_get_hw_config(struct dsi_shared_data *sdata)
{
- /*
- * currently the only supported mode is split display.
- * So, if both controllers are initialized, then assume that
- * split display mode is enabled.
- */
- return ctrl_list[DSI_CTRL_LEFT] && ctrl_list[DSI_CTRL_RIGHT];
+ return sdata->hw_config;
+}
+
+static inline bool mdss_dsi_is_hw_config_single(struct dsi_shared_data *sdata)
+{
+ return mdss_dsi_get_hw_config(sdata) == SINGLE_DSI;
+}
+
+static inline bool mdss_dsi_is_hw_config_split(struct dsi_shared_data *sdata)
+{
+ return mdss_dsi_get_hw_config(sdata) == SPLIT_DSI;
+}
+
+static inline bool mdss_dsi_is_hw_config_dual(struct dsi_shared_data *sdata)
+{
+ return mdss_dsi_get_hw_config(sdata) == DUAL_DSI;
}
static inline bool mdss_dsi_sync_wait_enable(struct mdss_dsi_ctrl_pdata *ctrl)
@@ -571,13 +612,13 @@ static inline struct mdss_dsi_ctrl_pdata *mdss_dsi_get_ctrl_by_index(int ndx)
static inline bool mdss_dsi_is_ctrl_clk_master(struct mdss_dsi_ctrl_pdata *ctrl)
{
- return mdss_dsi_split_display_enabled() &&
+ return mdss_dsi_is_hw_config_split(ctrl->shared_data) &&
(ctrl->ndx == DSI_CTRL_CLK_MASTER);
}
static inline bool mdss_dsi_is_ctrl_clk_slave(struct mdss_dsi_ctrl_pdata *ctrl)
{
- return mdss_dsi_split_display_enabled() &&
+ return mdss_dsi_is_hw_config_split(ctrl->shared_data) &&
(ctrl->ndx == DSI_CTRL_CLK_SLAVE);
}
diff --git a/drivers/video/fbdev/msm/mdss_dsi_host.c b/drivers/video/fbdev/msm/mdss_dsi_host.c
index 530d69d03a81..1f2257064866 100644
--- a/drivers/video/fbdev/msm/mdss_dsi_host.c
+++ b/drivers/video/fbdev/msm/mdss_dsi_host.c
@@ -260,17 +260,17 @@ void mdss_dsi_cmd_test_pattern(struct mdss_dsi_ctrl_pdata *ctrl)
void mdss_dsi_read_hw_revision(struct mdss_dsi_ctrl_pdata *ctrl)
{
/* clock must be on */
- ctrl->hw_rev = MIPI_INP(ctrl->ctrl_base);
+ ctrl->shared_data->hw_rev = MIPI_INP(ctrl->ctrl_base);
}
void mdss_dsi_get_hw_revision(struct mdss_dsi_ctrl_pdata *ctrl)
{
mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 1);
- ctrl->hw_rev = MIPI_INP(ctrl->ctrl_base);
+ ctrl->shared_data->hw_rev = MIPI_INP(ctrl->ctrl_base);
mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 0);
pr_debug("%s: ndx=%d hw_rev=%x\n", __func__,
- ctrl->ndx, ctrl->hw_rev);
+ ctrl->ndx, ctrl->shared_data->hw_rev);
}
void mdss_dsi_host_init(struct mdss_panel_data *pdata)
@@ -636,7 +636,7 @@ static void mdss_dsi_ctl_phy_reset(struct mdss_dsi_ctrl_pdata *ctrl)
pr_debug("%s: MDSS DSI CTRL and PHY reset. ctrl-num = %d\n",
__func__, ctrl->ndx);
- if (ctrl->panel_data.panel_info.is_split_display) {
+ if (mdss_dsi_is_hw_config_split(ctrl->shared_data)) {
pr_debug("%s: Split display enabled\n", __func__);
ctrl0 = mdss_dsi_get_ctrl_by_index(DSI_CTRL_0);
ctrl1 = mdss_dsi_get_ctrl_by_index(DSI_CTRL_1);
@@ -1106,7 +1106,7 @@ static void mdss_dsi_mode_setup(struct mdss_panel_data *pdata)
mipi = &pdata->panel_info.mipi;
if (pdata->panel_info.type == MIPI_VIDEO_PANEL) {
- if (ctrl_pdata->timing_db_mode)
+ if (ctrl_pdata->shared_data->timing_db_mode)
MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x1e8, 0x1);
MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x24,
((hspw + hbp + width + dummy_xres) << 16 |
@@ -1121,7 +1121,7 @@ static void mdss_dsi_mode_setup(struct mdss_panel_data *pdata)
MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x30, (hspw << 16));
MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x34, 0);
MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x38, (vspw << 16));
- if (ctrl_pdata->timing_db_mode)
+ if (ctrl_pdata->shared_data->timing_db_mode)
MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x1e4, 0x1);
} else { /* command mode */
if (mipi->dst_format == DSI_CMD_DST_FORMAT_RGB888)
@@ -1526,7 +1526,7 @@ do_send:
goto end;
}
- if (ctrl->hw_rev >= MDSS_DSI_HW_REV_101) {
+ if (ctrl->shared_data->hw_rev >= MDSS_DSI_HW_REV_101) {
/* clear the RDBK_DATA registers */
MIPI_OUTP(ctrl->ctrl_base + 0x01d4, 0x1);
wmb(); /* make sure the RDBK registers are cleared */
@@ -1767,7 +1767,7 @@ static int mdss_dsi_cmd_dma_rx(struct mdss_dsi_ctrl_pdata *ctrl,
if (cnt > 4)
cnt = 4; /* 4 x 32 bits registers only */
- if (ctrl->hw_rev >= MDSS_DSI_HW_REV_101) {
+ if (ctrl->shared_data->hw_rev >= MDSS_DSI_HW_REV_101) {
rp->read_cnt = (MIPI_INP((ctrl->ctrl_base) + 0x01d4) >> 16);
pr_debug("%s: bytes read:%d\n", __func__, rp->read_cnt);
@@ -1949,7 +1949,7 @@ static int mdss_dsi_mdp_busy_tout_check(struct mdss_dsi_ctrl_pdata *ctrl)
MIPI_OUTP(ctrl->ctrl_base + 0x0110, isr);
mdss_dsi_disable_irq_nosync(ctrl, DSI_MDP_TERM);
ctrl->mdp_busy = false;
- if (ctrl->cmd_clk_ln_recovery_en &&
+ if (ctrl->shared_data->cmd_clk_ln_recovery_en &&
ctrl->panel_mode == DSI_CMD_MODE) {
/* has hs_lane_recovery do the work */
stop_hs_clk = true;
@@ -2087,12 +2087,12 @@ int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp)
* will followed.
*/
if (!roi || (roi->w != 0 || roi->h != 0)) {
- if (ctrl->cmd_clk_ln_recovery_en &&
+ if (ctrl->shared_data->cmd_clk_ln_recovery_en &&
ctrl->panel_mode == DSI_CMD_MODE)
mdss_dsi_start_hs_clk_lane(ctrl);
}
} else { /* from dcs send */
- if (ctrl->cmd_clk_ln_recovery_en &&
+ if (ctrl->shared_data->cmd_clk_ln_recovery_en &&
ctrl->panel_mode == DSI_CMD_MODE &&
(req->flags & CMD_REQ_HS_MODE))
mdss_dsi_cmd_start_hs_clk_lane(ctrl);
@@ -2163,7 +2163,7 @@ need_lock:
mutex_unlock(&ctrl->cmd_mutex);
} else { /* from dcs send */
- if (ctrl->cmd_clk_ln_recovery_en &&
+ if (ctrl->shared_data->cmd_clk_ln_recovery_en &&
ctrl->panel_mode == DSI_CMD_MODE &&
(req && (req->flags & CMD_REQ_HS_MODE)))
mdss_dsi_cmd_stop_hs_clk_lane(ctrl);
@@ -2262,7 +2262,8 @@ static int dsi_event_thread(void *data)
pr_debug("%s: lane_status: 0x%x\n",
__func__, ln_status);
if (ctrl->recovery
- && (ctrl->hw_rev != MDSS_DSI_HW_REV_103)
+ && (ctrl->shared_data->hw_rev
+ != MDSS_DSI_HW_REV_103)
&& !(force_clk_ln_hs)
&& (ln_status
& DSI_DATA_LANES_STOP_STATE)
@@ -2276,7 +2277,7 @@ static int dsi_event_thread(void *data)
DSI_INTR_ERROR_MASK, 1);
mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 0);
} else if (ctrl->recovery
- && (ctrl->hw_rev
+ && (ctrl->shared_data->hw_rev
== MDSS_DSI_HW_REV_103)) {
pr_debug("%s: Handle overflow->Rev_103\n",
__func__);
@@ -2511,7 +2512,7 @@ irqreturn_t mdss_dsi_isr(int irq, void *ptr)
MDSS_XLOG(ctrl->ndx, ctrl->mdp_busy, isr, 0x99);
spin_lock(&ctrl->mdp_lock);
mdss_dsi_disable_irq_nosync(ctrl, DSI_MDP_TERM);
- if (ctrl->cmd_clk_ln_recovery_en &&
+ if (ctrl->shared_data->cmd_clk_ln_recovery_en &&
ctrl->panel_mode == DSI_CMD_MODE) {
/* stop force clk lane hs */
mdss_dsi_cfg_lane_ctrl(ctrl, BIT(28), 0);
diff --git a/drivers/video/fbdev/msm/mdss_dsi_panel.c b/drivers/video/fbdev/msm/mdss_dsi_panel.c
index b05689da9ec5..d6ad191cdf67 100644
--- a/drivers/video/fbdev/msm/mdss_dsi_panel.c
+++ b/drivers/video/fbdev/msm/mdss_dsi_panel.c
@@ -293,6 +293,13 @@ int mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable)
ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
panel_data);
+ if (mdss_dsi_is_right_ctrl(ctrl_pdata) &&
+ mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data)) {
+ pr_debug("%s:%d, right ctrl gpio configuration not needed\n",
+ __func__, __LINE__);
+ return rc;
+ }
+
if (!gpio_is_valid(ctrl_pdata->disp_en_gpio)) {
pr_debug("%s:%d, reset line not configured\n",
__func__, __LINE__);
diff --git a/drivers/video/fbdev/msm/msm_mdss_io_8974.c b/drivers/video/fbdev/msm/msm_mdss_io_8974.c
index 6d2c28acb3a1..9f616789f7a1 100644
--- a/drivers/video/fbdev/msm/msm_mdss_io_8974.c
+++ b/drivers/video/fbdev/msm/msm_mdss_io_8974.c
@@ -72,7 +72,8 @@ static void mdss_dsi_phy_sw_reset(struct mdss_dsi_ctrl_pdata *ctrl)
return;
}
- if (IS_MDSS_MAJOR_MINOR_SAME(ctrl->hw_rev, MDSS_DSI_HW_REV_104)) {
+ if (IS_MDSS_MAJOR_MINOR_SAME(ctrl->shared_data->hw_rev,
+ MDSS_DSI_HW_REV_104)) {
if (mdss_dsi_is_ctrl_clk_master(ctrl))
sctrl = mdss_dsi_get_ctrl_clk_slave();
else
@@ -89,7 +90,7 @@ static void mdss_dsi_phy_sw_reset(struct mdss_dsi_ctrl_pdata *ctrl)
* Need to turn off the PLL1 to avoid current leakage issues
*/
if (ctrl->ndx == DSI_CTRL_1) {
- if (ctrl->hw_rev == MDSS_DSI_HW_REV_103) {
+ if (ctrl->shared_data->hw_rev == MDSS_DSI_HW_REV_103) {
pr_debug("Turn off PLL 1 registers\n");
clk_set_rate(ctrl->vco_clk, 1);
}
@@ -103,7 +104,8 @@ static void mdss_dsi_phy_regulator_disable(struct mdss_dsi_ctrl_pdata *ctrl)
return;
}
- if (IS_MDSS_MAJOR_MINOR_SAME(ctrl->hw_rev, MDSS_DSI_HW_REV_104))
+ if (IS_MDSS_MAJOR_MINOR_SAME(ctrl->shared_data->hw_rev,
+ MDSS_DSI_HW_REV_104))
return;
MIPI_OUTP(ctrl->shared_ctrl_data->phy_regulator_io.base
@@ -117,7 +119,8 @@ static void mdss_dsi_phy_lane_shutdown(struct mdss_dsi_ctrl_pdata *ctrl)
return;
}
- if (IS_MDSS_MAJOR_MINOR_SAME(ctrl->hw_rev, MDSS_DSI_HW_REV_104))
+ if (IS_MDSS_MAJOR_MINOR_SAME(ctrl->shared_data->hw_rev,
+ MDSS_DSI_HW_REV_104))
MIPI_OUTP(ctrl->phy_io.base + DSIPHY_CMN_CTRL_0, ~0x1F);
else
MIPI_OUTP(ctrl->phy_io.base + MDSS_DSI_DSIPHY_CTRL_0, 0x000);
@@ -135,11 +138,11 @@ void mdss_dsi_phy_disable(struct mdss_dsi_ctrl_pdata *ctrl)
ctrl->shared_ctrl_data->phy_disable_refcount++;
/*
- * In dual-dsi configuration, the phy should be disabled for the
+ * In split-dsi configuration, the phy should be disabled for the
* first controller only when the second controller is disabled.
* This is true regardless of whether broadcast mode is enabled.
*/
- if (!mdss_dsi_split_display_enabled() ||
+ if (!mdss_dsi_is_hw_config_split(ctrl->shared_data) ||
ctrl->shared_ctrl_data->phy_disable_refcount == 2) {
other_ctrl = mdss_dsi_get_other_ctrl(ctrl);
@@ -175,7 +178,8 @@ void mdss_dsi_lp_cd_rx(struct mdss_dsi_ctrl_pdata *ctrl)
return;
}
- if (IS_MDSS_MAJOR_MINOR_SAME(ctrl->hw_rev, MDSS_DSI_HW_REV_104))
+ if (IS_MDSS_MAJOR_MINOR_SAME(ctrl->shared_data->hw_rev,
+ MDSS_DSI_HW_REV_104))
return;
pd = &(((ctrl->panel_data).panel_info.mipi).dsi_phy_db);
@@ -298,7 +302,7 @@ static void mdss_dsi_28nm_phy_init(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
/* DSI_0_PHY_DSIPHY_GLBL_TEST_CTRL */
if (((ctrl_pdata->panel_data).panel_info.pdest == DISPLAY_1) ||
- (ctrl_pdata->hw_rev == MDSS_DSI_HW_REV_103_1))
+ (ctrl_pdata->shared_data->hw_rev == MDSS_DSI_HW_REV_103_1))
MIPI_OUTP((ctrl_pdata->phy_io.base) + 0x01d4, 0x01);
else
MIPI_OUTP((ctrl_pdata->phy_io.base) + 0x01d4, 0x00);
@@ -530,7 +534,7 @@ static void mdss_dsi_8996_phy_config(struct mdss_dsi_ctrl_pdata *ctrl)
udelay(100);
MIPI_OUTP((ctrl->phy_io.base) + DSIPHY_CMN_CTRL_1, 0x00);
- if (mdss_dsi_split_display_enabled()) {
+ if (mdss_dsi_is_hw_config_split(ctrl->shared_data)) {
if (mdss_dsi_is_left_ctrl(ctrl))
mdss_dsi_8996_pll_source_from_left(ctrl);
else
@@ -571,7 +575,7 @@ static void mdss_dsi_phy_init(struct mdss_dsi_ctrl_pdata *ctrl)
return;
}
- switch (ctrl->hw_rev) {
+ switch (ctrl->shared_data->hw_rev) {
case MDSS_DSI_HW_REV_104:
case MDSS_DSI_HW_REV_104_1:
mdss_dsi_8996_phy_init(ctrl);
@@ -585,83 +589,121 @@ static void mdss_dsi_phy_init(struct mdss_dsi_ctrl_pdata *ctrl)
}
}
-int mdss_dsi_clk_init(struct platform_device *pdev,
- struct mdss_dsi_ctrl_pdata *ctrl)
+void mdss_dsi_bus_clk_deinit(struct device *dev,
+ struct dsi_shared_data *sdata)
+{
+ if (sdata->mmss_misc_ahb_clk)
+ devm_clk_put(dev, sdata->mmss_misc_ahb_clk);
+ if (sdata->axi_clk)
+ devm_clk_put(dev, sdata->axi_clk);
+ if (sdata->ahb_clk)
+ devm_clk_put(dev, sdata->ahb_clk);
+ if (sdata->mdp_core_clk)
+ devm_clk_put(dev, sdata->mdp_core_clk);
+}
+
+int mdss_dsi_bus_clk_init(struct platform_device *pdev,
+ struct dsi_shared_data *sdata)
{
struct device *dev = NULL;
int rc = 0;
if (!pdev) {
pr_err("%s: Invalid pdev\n", __func__);
- goto mdss_dsi_clk_err;
+ goto clk_err;
}
dev = &pdev->dev;
- ctrl->mdp_core_clk = clk_get(dev, "mdp_core_clk");
- if (IS_ERR(ctrl->mdp_core_clk)) {
- rc = PTR_ERR(ctrl->mdp_core_clk);
+ sdata->mdp_core_clk = devm_clk_get(dev, "mdp_core_clk");
+ if (IS_ERR(sdata->mdp_core_clk)) {
+ rc = PTR_ERR(sdata->mdp_core_clk);
pr_err("%s: Unable to get mdp core clk. rc=%d\n",
__func__, rc);
- goto mdss_dsi_clk_err;
+ goto clk_err;
}
- ctrl->ahb_clk = clk_get(dev, "iface_clk");
- if (IS_ERR(ctrl->ahb_clk)) {
- rc = PTR_ERR(ctrl->ahb_clk);
+ sdata->ahb_clk = devm_clk_get(dev, "iface_clk");
+ if (IS_ERR(sdata->ahb_clk)) {
+ rc = PTR_ERR(sdata->ahb_clk);
pr_err("%s: Unable to get mdss ahb clk. rc=%d\n",
__func__, rc);
- goto mdss_dsi_clk_err;
+ goto clk_err;
}
- ctrl->axi_clk = clk_get(dev, "bus_clk");
- if (IS_ERR(ctrl->axi_clk)) {
- rc = PTR_ERR(ctrl->axi_clk);
+ sdata->axi_clk = devm_clk_get(dev, "bus_clk");
+ if (IS_ERR(sdata->axi_clk)) {
+ rc = PTR_ERR(sdata->axi_clk);
pr_err("%s: Unable to get axi bus clk. rc=%d\n",
__func__, rc);
- goto mdss_dsi_clk_err;
+ goto clk_err;
}
- if ((ctrl->panel_data.panel_info.type == MIPI_CMD_PANEL) ||
- ctrl->panel_data.panel_info.mipi.dms_mode ||
- ctrl->panel_data.panel_info.ulps_suspend_enabled) {
- ctrl->mmss_misc_ahb_clk = clk_get(dev, "core_mmss_clk");
- if (IS_ERR(ctrl->mmss_misc_ahb_clk)) {
- ctrl->mmss_misc_ahb_clk = NULL;
- pr_info("%s: Unable to get mmss misc ahb clk\n",
- __func__);
- }
+ sdata->mmss_misc_ahb_clk = devm_clk_get(dev, "core_mmss_clk");
+ if (IS_ERR(sdata->mmss_misc_ahb_clk)) {
+ sdata->mmss_misc_ahb_clk = NULL;
+ pr_info("%s: Unable to get mmss misc ahb clk\n",
+ __func__);
}
- ctrl->byte_clk = clk_get(dev, "byte_clk");
+clk_err:
+ if (rc)
+ mdss_dsi_bus_clk_deinit(dev, sdata);
+ return rc;
+}
+
+void mdss_dsi_link_clk_deinit(struct device *dev,
+ struct mdss_dsi_ctrl_pdata *ctrl)
+{
+ if (ctrl->byte_clk)
+ devm_clk_put(dev, ctrl->byte_clk);
+ if (ctrl->esc_clk)
+ devm_clk_put(dev, ctrl->esc_clk);
+ if (ctrl->pixel_clk)
+ devm_clk_put(dev, ctrl->pixel_clk);
+}
+
+int mdss_dsi_link_clk_init(struct platform_device *pdev,
+ struct mdss_dsi_ctrl_pdata *ctrl)
+{
+ struct device *dev = NULL;
+ int rc = 0;
+
+ if (!pdev) {
+ pr_err("%s: Invalid pdev\n", __func__);
+ goto error;
+ }
+
+ dev = &pdev->dev;
+ ctrl->byte_clk = devm_clk_get(dev, "byte_clk");
if (IS_ERR(ctrl->byte_clk)) {
rc = PTR_ERR(ctrl->byte_clk);
pr_err("%s: can't find dsi_byte_clk. rc=%d\n",
__func__, rc);
ctrl->byte_clk = NULL;
- goto mdss_dsi_clk_err;
+ goto error;
}
- ctrl->pixel_clk = clk_get(dev, "pixel_clk");
+ ctrl->pixel_clk = devm_clk_get(dev, "pixel_clk");
if (IS_ERR(ctrl->pixel_clk)) {
rc = PTR_ERR(ctrl->pixel_clk);
pr_err("%s: can't find dsi_pixel_clk. rc=%d\n",
__func__, rc);
ctrl->pixel_clk = NULL;
- goto mdss_dsi_clk_err;
+ goto error;
}
- ctrl->esc_clk = clk_get(dev, "core_clk");
+ ctrl->esc_clk = devm_clk_get(dev, "core_clk");
if (IS_ERR(ctrl->esc_clk)) {
rc = PTR_ERR(ctrl->esc_clk);
pr_err("%s: can't find dsi_esc_clk. rc=%d\n",
__func__, rc);
ctrl->esc_clk = NULL;
- goto mdss_dsi_clk_err;
+ goto error;
}
-mdss_dsi_clk_err:
+error:
if (rc)
- mdss_dsi_clk_deinit(ctrl);
+ mdss_dsi_link_clk_deinit(dev, ctrl);
return rc;
}
@@ -688,6 +730,23 @@ int mdss_dsi_pll_1_clk_init(struct platform_device *pdev,
return rc;
}
+void mdss_dsi_shadow_clk_deinit(struct device *dev,
+ struct mdss_dsi_ctrl_pdata *ctrl)
+{
+ if (ctrl->mux_byte_clk)
+ devm_clk_put(dev, ctrl->mux_byte_clk);
+ if (ctrl->mux_pixel_clk)
+ devm_clk_put(dev, ctrl->mux_pixel_clk);
+ if (ctrl->pll_byte_clk)
+ devm_clk_put(dev, ctrl->pll_byte_clk);
+ if (ctrl->pll_pixel_clk)
+ devm_clk_put(dev, ctrl->pll_pixel_clk);
+ if (ctrl->shadow_byte_clk)
+ devm_clk_put(dev, ctrl->shadow_byte_clk);
+ if (ctrl->shadow_pixel_clk)
+ devm_clk_put(dev, ctrl->shadow_pixel_clk);
+}
+
int mdss_dsi_shadow_clk_init(struct platform_device *pdev,
struct mdss_dsi_ctrl_pdata *ctrl)
{
@@ -700,101 +759,66 @@ int mdss_dsi_shadow_clk_init(struct platform_device *pdev,
}
dev = &pdev->dev;
- ctrl->mux_byte_clk = clk_get(dev, "mdss_byte_clk_mux");
+ ctrl->mux_byte_clk = devm_clk_get(dev, "mdss_byte_clk_mux");
if (IS_ERR(ctrl->mux_byte_clk)) {
rc = PTR_ERR(ctrl->mux_byte_clk);
pr_err("%s: can't find mux_byte_clk. rc=%d\n",
__func__, rc);
ctrl->mux_byte_clk = NULL;
- goto mdss_dsi_shadow_clk_err;
+ goto error;
}
- ctrl->mux_pixel_clk = clk_get(dev, "mdss_pixel_clk_mux");
+ ctrl->mux_pixel_clk = devm_clk_get(dev, "mdss_pixel_clk_mux");
if (IS_ERR(ctrl->mux_pixel_clk)) {
rc = PTR_ERR(ctrl->mux_pixel_clk);
pr_err("%s: can't find mdss_mux_pixel_clk. rc=%d\n",
__func__, rc);
ctrl->mux_pixel_clk = NULL;
- goto mdss_dsi_shadow_clk_err;
+ goto error;
}
- ctrl->pll_byte_clk = clk_get(dev, "byte_clk_src");
+ ctrl->pll_byte_clk = devm_clk_get(dev, "byte_clk_src");
if (IS_ERR(ctrl->pll_byte_clk)) {
rc = PTR_ERR(ctrl->pll_byte_clk);
pr_err("%s: can't find pll_byte_clk. rc=%d\n",
__func__, rc);
ctrl->pll_byte_clk = NULL;
- goto mdss_dsi_shadow_clk_err;
+ goto error;
}
- ctrl->pll_pixel_clk = clk_get(dev, "pixel_clk_src");
+ ctrl->pll_pixel_clk = devm_clk_get(dev, "pixel_clk_src");
if (IS_ERR(ctrl->pll_pixel_clk)) {
rc = PTR_ERR(ctrl->pll_pixel_clk);
pr_err("%s: can't find pll_pixel_clk. rc=%d\n",
__func__, rc);
ctrl->pll_pixel_clk = NULL;
- goto mdss_dsi_shadow_clk_err;
+ goto error;
}
- ctrl->shadow_byte_clk = clk_get(dev, "shadow_byte_clk_src");
+ ctrl->shadow_byte_clk = devm_clk_get(dev, "shadow_byte_clk_src");
if (IS_ERR(ctrl->shadow_byte_clk)) {
rc = PTR_ERR(ctrl->shadow_byte_clk);
pr_err("%s: can't find shadow_byte_clk. rc=%d\n",
__func__, rc);
ctrl->shadow_byte_clk = NULL;
- goto mdss_dsi_shadow_clk_err;
+ goto error;
}
- ctrl->shadow_pixel_clk = clk_get(dev, "shadow_pixel_clk_src");
+ ctrl->shadow_pixel_clk = devm_clk_get(dev, "shadow_pixel_clk_src");
if (IS_ERR(ctrl->shadow_pixel_clk)) {
rc = PTR_ERR(ctrl->shadow_pixel_clk);
pr_err("%s: can't find shadow_pixel_clk. rc=%d\n",
__func__, rc);
ctrl->shadow_pixel_clk = NULL;
- goto mdss_dsi_shadow_clk_err;
+ goto error;
}
-mdss_dsi_shadow_clk_err:
+error:
if (rc)
- mdss_dsi_shadow_clk_deinit(ctrl);
+ mdss_dsi_shadow_clk_deinit(dev, ctrl);
return rc;
}
-void mdss_dsi_clk_deinit(struct mdss_dsi_ctrl_pdata *ctrl)
-{
- if (ctrl->byte_clk)
- clk_put(ctrl->byte_clk);
- if (ctrl->esc_clk)
- clk_put(ctrl->esc_clk);
- if (ctrl->pixel_clk)
- clk_put(ctrl->pixel_clk);
- if (ctrl->mmss_misc_ahb_clk)
- clk_put(ctrl->mmss_misc_ahb_clk);
- if (ctrl->axi_clk)
- clk_put(ctrl->axi_clk);
- if (ctrl->ahb_clk)
- clk_put(ctrl->ahb_clk);
- if (ctrl->mdp_core_clk)
- clk_put(ctrl->mdp_core_clk);
-}
-
-void mdss_dsi_shadow_clk_deinit(struct mdss_dsi_ctrl_pdata *ctrl)
-{
- if (ctrl->mux_byte_clk)
- clk_put(ctrl->mux_byte_clk);
- if (ctrl->mux_pixel_clk)
- clk_put(ctrl->mux_pixel_clk);
- if (ctrl->pll_byte_clk)
- clk_put(ctrl->pll_byte_clk);
- if (ctrl->pll_pixel_clk)
- clk_put(ctrl->pll_pixel_clk);
- if (ctrl->shadow_byte_clk)
- clk_put(ctrl->shadow_byte_clk);
- if (ctrl->shadow_pixel_clk)
- clk_put(ctrl->shadow_pixel_clk);
-}
-
-
int mdss_dsi_clk_div_config(struct mdss_panel_info *panel_info,
int frame_rate)
{
@@ -864,10 +888,11 @@ int mdss_dsi_clk_div_config(struct mdss_panel_info *panel_info,
static int mdss_dsi_bus_clk_start(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
{
int rc = 0;
+ struct dsi_shared_data *sdata = ctrl_pdata->shared_data;
pr_debug("%s: ndx=%d\n", __func__, ctrl_pdata->ndx);
- rc = clk_prepare_enable(ctrl_pdata->mdp_core_clk);
+ rc = clk_prepare_enable(sdata->mdp_core_clk);
if (rc) {
pr_err("%s: failed to enable mdp_core_clock. rc=%d\n",
__func__, rc);
@@ -875,20 +900,20 @@ static int mdss_dsi_bus_clk_start(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
}
mdss_update_reg_bus_vote(VOTE_INDEX_19_MHZ);
- rc = clk_prepare_enable(ctrl_pdata->ahb_clk);
+ rc = clk_prepare_enable(sdata->ahb_clk);
if (rc) {
pr_err("%s: failed to enable ahb clock. rc=%d\n", __func__, rc);
goto disable_core_clk;
}
- rc = clk_prepare_enable(ctrl_pdata->axi_clk);
+ rc = clk_prepare_enable(sdata->axi_clk);
if (rc) {
pr_err("%s: failed to enable ahb clock. rc=%d\n", __func__, rc);
goto disable_ahb_clk;
}
- if (ctrl_pdata->mmss_misc_ahb_clk) {
- rc = clk_prepare_enable(ctrl_pdata->mmss_misc_ahb_clk);
+ if (sdata->mmss_misc_ahb_clk) {
+ rc = clk_prepare_enable(sdata->mmss_misc_ahb_clk);
if (rc) {
pr_err("%s: failed to enable mmss misc ahb clk.rc=%d\n",
__func__, rc);
@@ -898,24 +923,25 @@ static int mdss_dsi_bus_clk_start(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
return rc;
disable_axi_clk:
- clk_disable_unprepare(ctrl_pdata->axi_clk);
+ clk_disable_unprepare(sdata->axi_clk);
disable_ahb_clk:
- clk_disable_unprepare(ctrl_pdata->ahb_clk);
+ clk_disable_unprepare(sdata->ahb_clk);
disable_core_clk:
mdss_update_reg_bus_vote(VOTE_INDEX_DISABLE);
- clk_disable_unprepare(ctrl_pdata->mdp_core_clk);
+ clk_disable_unprepare(sdata->mdp_core_clk);
error:
return rc;
}
static void mdss_dsi_bus_clk_stop(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
{
- if (ctrl_pdata->mmss_misc_ahb_clk)
- clk_disable_unprepare(ctrl_pdata->mmss_misc_ahb_clk);
- clk_disable_unprepare(ctrl_pdata->axi_clk);
- clk_disable_unprepare(ctrl_pdata->ahb_clk);
+ struct dsi_shared_data *sdata = ctrl_pdata->shared_data;
+ if (sdata->mmss_misc_ahb_clk)
+ clk_disable_unprepare(sdata->mmss_misc_ahb_clk);
+ clk_disable_unprepare(sdata->axi_clk);
+ clk_disable_unprepare(sdata->ahb_clk);
mdss_update_reg_bus_vote(VOTE_INDEX_DISABLE);
- clk_disable_unprepare(ctrl_pdata->mdp_core_clk);
+ clk_disable_unprepare(sdata->mdp_core_clk);
}
static int mdss_dsi_link_clk_prepare(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
@@ -1255,13 +1281,14 @@ static int mdss_dsi_clamp_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, int enable)
return -EINVAL;
}
- if (IS_MDSS_MAJOR_MINOR_SAME(ctrl->hw_rev, MDSS_DSI_HW_REV_104)) {
+ if (IS_MDSS_MAJOR_MINOR_SAME(ctrl->shared_data->hw_rev,
+ MDSS_DSI_HW_REV_104)) {
pr_debug("%s: clamp ctrl configuration is skipped\n", __func__);
return 0;
}
- clamp_reg_off = ctrl->ulps_clamp_ctrl_off;
- phyrst_reg_off = ctrl->ulps_phyrst_ctrl_off;
+ clamp_reg_off = ctrl->shared_data->ulps_clamp_ctrl_off;
+ phyrst_reg_off = ctrl->shared_data->ulps_phyrst_ctrl_off;
mipi = &ctrl->panel_data.panel_info.mipi;
/* clock lane will always be clamped */
@@ -1313,7 +1340,7 @@ static int mdss_dsi_clamp_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, int enable)
* reset when mdss ahb clock reset is asserted while coming
* out of power collapse
*/
- if (IS_MDSS_MAJOR_MINOR_SAME(ctrl->hw_rev,
+ if (IS_MDSS_MAJOR_MINOR_SAME(ctrl->shared_data->hw_rev,
MDSS_DSI_HW_REV_104)) {
regval = MIPI_INP(ctrl->mmss_misc_io.base +
@@ -1328,7 +1355,7 @@ static int mdss_dsi_clamp_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, int enable)
wmb();
ctrl->mmss_clamp = true;
} else if (!enable && ctrl->mmss_clamp) {
- if (IS_MDSS_MAJOR_MINOR_SAME(ctrl->hw_rev,
+ if (IS_MDSS_MAJOR_MINOR_SAME(ctrl->shared_data->hw_rev,
MDSS_DSI_HW_REV_104)) {
regval = MIPI_INP(ctrl->mmss_misc_io.base +
@@ -1379,12 +1406,14 @@ static int mdss_dsi_core_power_ctrl(struct mdss_dsi_ctrl_pdata *ctrl,
int rc = 0;
int i = 0;
struct mdss_panel_data *pdata = NULL;
+ struct dsi_shared_data *sdata;
if (!ctrl) {
pr_err("%s: invalid input\n", __func__);
return -EINVAL;
}
+ sdata = ctrl->shared_data;
pdata = &ctrl->panel_data;
if (!pdata) {
pr_err("%s: Invalid panel data\n", __func__);
@@ -1402,16 +1431,15 @@ static int mdss_dsi_core_power_ctrl(struct mdss_dsi_ctrl_pdata *ctrl,
* not be changed during static screen.
*/
pr_debug("%s: Enable DSI core power\n", __func__);
- for (i = 0; i < DSI_MAX_PM; i++) {
- if ((DSI_PANEL_PM == i) ||
- ((DSI_CORE_PM != i) &&
+ for (i = DSI_CORE_PM; i < DSI_MAX_PM; i++) {
+ if (((DSI_CORE_PM != i) &&
(pdata->panel_info.blank_state !=
MDSS_PANEL_BLANK_BLANK) &&
!pdata->panel_info.cont_splash_enabled))
continue;
rc = msm_dss_enable_vreg(
- ctrl->power_data[i].vreg_config,
- ctrl->power_data[i].num_vreg, 1);
+ sdata->power_data[i].vreg_config,
+ sdata->power_data[i].num_vreg, 1);
if (rc) {
pr_err("%s: failed to enable vregs for %s\n",
__func__,
@@ -1508,15 +1536,14 @@ static int mdss_dsi_core_power_ctrl(struct mdss_dsi_ctrl_pdata *ctrl,
pr_debug("%s: leaving DSI core power on\n", __func__);
} else {
pr_debug("%s: Disable DSI core power\n", __func__);
- for (i = DSI_MAX_PM - 1; i >= 0; i--) {
- if ((DSI_PANEL_PM == i) ||
- ((DSI_CORE_PM != i) &&
+ for (i = DSI_MAX_PM - 1; i >= DSI_CORE_PM; i--) {
+ if (((DSI_CORE_PM != i) &&
(pdata->panel_info.blank_state !=
MDSS_PANEL_BLANK_BLANK)))
continue;
rc = msm_dss_enable_vreg(
- ctrl->power_data[i].vreg_config,
- ctrl->power_data[i].num_vreg, 0);
+ sdata->power_data[i].vreg_config,
+ sdata->power_data[i].num_vreg, 0);
if (rc) {
pr_warn("%s: failed to disable vregs for %s\n",
__func__,
@@ -1533,13 +1560,12 @@ static int mdss_dsi_core_power_ctrl(struct mdss_dsi_ctrl_pdata *ctrl,
error_ulps:
mdss_dsi_bus_clk_stop(ctrl);
error_bus_clk_start:
- for (i = DSI_MAX_PM - 1; i >= 0; i--) {
- if ((DSI_PANEL_PM == i) || ((DSI_CORE_PM != i) &&
- (pdata->panel_info.blank_state !=
+ for (i = DSI_MAX_PM - 1; i >= DSI_CORE_PM; i--) {
+ if (((DSI_CORE_PM != i) && (pdata->panel_info.blank_state !=
MDSS_PANEL_BLANK_BLANK)))
continue;
- rc = msm_dss_enable_vreg(ctrl->power_data[i].vreg_config,
- ctrl->power_data[i].num_vreg, 0);
+ rc = msm_dss_enable_vreg(sdata->power_data[i].vreg_config,
+ sdata->power_data[i].num_vreg, 0);
if (rc) {
pr_warn("%s: failed to disable vregs for %s\n",
__func__, __mdss_dsi_pm_name(i));