diff options
| -rw-r--r-- | Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt | 4 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/fb/mdss-dsi.txt (renamed from Documentation/devicetree/bindings/fb/mdss-dsi-ctrl.txt) | 216 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dsi.c | 499 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dsi.h | 70 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dsi_panel.c | 138 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/msm_mdss_io_8974.c | 78 |
6 files changed, 580 insertions, 425 deletions
diff --git a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt index a3d4601dcf03..8c359938ac6d 100644 --- a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt +++ b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt @@ -85,9 +85,6 @@ Optional properties: screen using the qcom,memblock-reserve binding for the framebuffer device attached to the panel. - qcom,cmd-sync-wait-broadcast: Boolean used to broadcast dcs command to panels. -- qcom,cmd-sync-wait-trigger: Boolean used to identify the which panel in a dual-dsi - configuration will be used to trigger the DCS commands. - This flag should be set only for one of the two panels. - qcom,mdss-dsi-fbc-enable: Boolean used to enable frame buffer compression mode. - qcom,mdss-dsi-fbc-slice-height: Slice height(in lines) of compressed block. Expressed as power of 2. To set as 128 lines, @@ -429,7 +426,6 @@ Example: qcom,mdss-dsi-pixel-packing = <0>; qcom,mdss-dsi-panel-destination = "display_1"; qcom,cmd-sync-wait-broadcast; - qcom,cmd-sync-wait-trigger; qcom,mdss-dsi-fbc-enable; qcom,mdss-dsi-fbc-slice-height = <5>; qcom,mdss-dsi-fbc-2d-pred-mode; diff --git a/Documentation/devicetree/bindings/fb/mdss-dsi-ctrl.txt b/Documentation/devicetree/bindings/fb/mdss-dsi.txt index 51d92fae781d..2c520a7f72e0 100644 --- a/Documentation/devicetree/bindings/fb/mdss-dsi-ctrl.txt +++ b/Documentation/devicetree/bindings/fb/mdss-dsi.txt @@ -1,7 +1,18 @@ -Qualcomm mdss-dsi-ctrl +Qualcomm mdss-dsi -mdss-dsi-ctrl is a dsi controller device which supports host controllers that -are compatable with MIPI display serial interface specification. +mdss-dsi is the master DSI device which supports multiple DSI host controllers that +are compatible with MIPI display serial interface specification. + +Required properties: +- compatible: Must be "qcom,mdss-dsi" +- hw-config: Specifies the DSI host setup configuration + "hw-config" = "single_dsi" + "hw-config" = "dual_dsi" + "hw-config" = "split_dsi" +- ranges: The standard property which specifies the child address + space, parent address space and the length. + +mdss-dsi-ctrl is a dsi controller device which is treated as a subnode of the mdss-dsi device. Required properties: - compatible: Must be "qcom,mdss-dsi-ctrl" @@ -79,98 +90,115 @@ Optional properties: "lane_map_3210" = <3 2 1 0> Example: - mdss_dsi0: qcom,mdss_dsi@fd922800 { - compatible = "qcom,mdss-dsi-ctrl"; - label = "MDSS DSI CTRL->0"; - cell-index = <0>; - reg = <0xfd922800 0x1f8>, - <0xfd922b00 0x2b0>, - <0xfd998780 0x30>, - <0xfd828000 0x108>; - reg-names = "dsi_ctrl", "dsi_phy", "dsi_phy_regulator", "mmss_misc_phys"; - vdd-supply = <&pm8226_l15>; - vddio-supply = <&pm8226_l8>; - vdda-supply = <&pm8226_l4>; - vcca-supply = <&pm8226_l28>; - qcom,dsi-pref-prim-pan = <&dsi_tosh_720_vid>; - qcom,platform-strength-ctrl = [ff 06]; - qcom,platform-bist-ctrl = [00 00 b1 ff 00 00]; - qcom,regulator-ldo-mode; - qcom,platform-regulator-settings = [07 09 03 00 20 00 01]; - qcom,platform-lane-config = [00 00 00 00 00 00 00 01 97 - 00 00 00 00 05 00 00 01 97 - 00 00 00 00 0a 00 00 01 97 - 00 00 00 00 0f 00 00 01 97 - 00 c0 00 00 00 00 00 01 bb]; - qcom,mmss-ulp-clamp-ctrl-offset = <0x20>; - qcom,mmss-phyreset-ctrl-offset = <0x24>; - qcom,mdss-fb-map = <&mdss_fb0>; - qcom,mdss-mdp = <&mdss_mdp>; - pinctrl-names = "mdss_default", "mdss_sleep"; - pinctrl-0 = <&mdss_dsi_active>; - pinctrl-1 = <&mdss_dsi_suspend>; - qcom,platform-reset-gpio = <&msmgpio 25 1>; - qcom,platform-te-gpio = <&msmgpio 24 0>; - qcom,platform-enable-gpio = <&msmgpio 58 1>; - 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>; + mdss_dsi: qcom,mdss_dsi@0 { + compatible = "qcom,mdss-dsi"; + hw-config = "single_dsi"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x1a98000 0x1a98000 0x25c + 0x1a98500 0x1a98500 0x280 + 0x1a98780 0x1a98780 0x30 + 0x193e000 0x193e000 0x30>; + + mdss_dsi0: mdss_dsi_ctrl0@fd922800 { + compatible = "qcom,mdss-dsi-ctrl"; + label = "MDSS DSI CTRL->0"; + cell-index = <0>; + reg = <0xfd922800 0x1f8>, + <0xfd922b00 0x2b0>, + <0xfd998780 0x30>, + <0xfd828000 0x108>; + reg-names = "dsi_ctrl", "dsi_phy", + "dsi_phy_regulator", "mmss_misc_phys"; + + 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>; + + qcom,dsi-pref-prim-pan = <&dsi_tosh_720_vid>; + + qcom,platform-strength-ctrl = [ff 06]; + qcom,platform-bist-ctrl = [00 00 b1 ff 00 00]; + qcom,platform-regulator-settings = [07 09 03 00 20 00 01]; + qcom,platform-lane-config = [00 00 00 00 00 00 00 01 97 + 00 00 00 00 05 00 00 01 97 + 00 00 00 00 0a 00 00 01 97 + 00 00 00 00 0f 00 00 01 97 + 00 c0 00 00 00 00 00 01 bb]; + + qcom,mmss-ulp-clamp-ctrl-offset = <0x20>; + qcom,mmss-phyreset-ctrl-offset = <0x24>; + qcom,regulator-ldo-mode; + + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active>; + pinctrl-1 = <&mdss_dsi_suspend>; + qcom,platform-reset-gpio = <&msmgpio 25 1>; + qcom,platform-te-gpio = <&msmgpio 24 0>; + qcom,platform-enable-gpio = <&msmgpio 58 1>; + 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,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>; + + 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 64c28dd39718..aa7d870fd4a7 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.c +++ b/drivers/video/fbdev/msm/mdss_dsi.c @@ -32,11 +32,22 @@ #define XO_CLK_RATE 19200000 +/* Master structure to hold all the information about the DSI/panel */ +static struct mdss_dsi_data *mdss_dsi_res; + static struct dsi_drv_cm_data shared_ctrl_data; static int mdss_dsi_pinctrl_set_state(struct mdss_dsi_ctrl_pdata *ctrl_pdata, bool active); +static struct mdss_dsi_ctrl_pdata *mdss_dsi_get_ctrl(u32 ctrl_id) +{ + if (ctrl_id >= DSI_CTRL_MAX || !mdss_dsi_res) + return NULL; + + return mdss_dsi_res->ctrl_pdata[ctrl_id]; +} + static int mdss_dsi_regulator_init(struct platform_device *pdev) { int rc = 0; @@ -243,7 +254,7 @@ static int mdss_dsi_get_dt_vreg_data(struct device *dev, */ supply_root_node = of_parse_phandle(of_node, pm_supply_name, 0); if (!supply_root_node) { - pr_err("no supply entry present\n"); + pr_err("no supply entry present: %s\n", pm_supply_name); goto novreg; } } @@ -2007,55 +2018,86 @@ end: return dsi_pan_node; } +static struct device_node *mdss_dsi_config_panel(struct platform_device *pdev) +{ + struct mdss_dsi_ctrl_pdata *ctrl_pdata = platform_get_drvdata(pdev); + char panel_cfg[MDSS_MAX_PANEL_LEN]; + struct device_node *dsi_pan_node = NULL; + bool cmd_cfg_cont_splash = true; + int rc = 0; + + if (!ctrl_pdata) { + pr_err("%s: Unable to get the ctrl_pdata\n", __func__); + return NULL; + } + + /* DSI panels can be different between controllers */ + rc = mdss_dsi_get_panel_cfg(panel_cfg, ctrl_pdata); + if (!rc) + /* dsi panel cfg not present */ + pr_warn("%s:%d:dsi specific cfg not present\n", + __func__, __LINE__); + + /* find panel device node */ + dsi_pan_node = mdss_dsi_find_panel_of_node(pdev, panel_cfg); + if (!dsi_pan_node) { + pr_err("%s: can't find panel node %s\n", __func__, panel_cfg); + of_node_put(dsi_pan_node); + return NULL; + } + + cmd_cfg_cont_splash = mdss_panel_get_boot_cfg() ? true : false; + + rc = mdss_dsi_panel_init(dsi_pan_node, ctrl_pdata, cmd_cfg_cont_splash); + if (rc) { + pr_err("%s: dsi panel init failed\n", __func__); + of_node_put(dsi_pan_node); + return NULL; + } + + return dsi_pan_node; +} + static int mdss_dsi_ctrl_probe(struct platform_device *pdev) { int rc = 0, i = 0; u32 index; struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; struct device_node *dsi_pan_node = NULL; - char panel_cfg[MDSS_MAX_PANEL_LEN]; const char *ctrl_name; - bool cmd_cfg_cont_splash = true; - struct mdss_panel_cfg *pan_cfg = NULL; struct mdss_util_intf *util; - util = mdss_get_util_intf(); - if (util == NULL) { - pr_err("Failed to get mdss utility functions\n"); + if (!pdev || !pdev->dev.of_node) { + pr_err("%s: pdev not found for DSI controller\n", __func__); return -ENODEV; } - - if (!util->mdp_probe_done) { - pr_err("%s: MDP not probed yet!\n", __func__); - return -EPROBE_DEFER; + rc = of_property_read_u32(pdev->dev.of_node, + "cell-index", &index); + if (rc) { + dev_err(&pdev->dev, "%s: Cell-index not specified, rc=%d\n", + __func__, rc); + return rc; } - if (!pdev->dev.of_node) { - pr_err("DSI driver only supports device tree probe\n"); - return -ENOTSUPP; + if (index == 0) + pdev->id = 1; + else + pdev->id = 2; + + ctrl_pdata = mdss_dsi_get_ctrl(index); + if (!ctrl_pdata) { + pr_err("%s: Unable to get the ctrl_pdata\n", __func__); + return -EINVAL; } - pan_cfg = util->panel_intf_type(MDSS_PANEL_INTF_HDMI); - if (IS_ERR(pan_cfg)) { - return PTR_ERR(pan_cfg); - } else if (pan_cfg) { - pr_debug("%s: HDMI is primary\n", __func__); + platform_set_drvdata(pdev, ctrl_pdata); + + util = mdss_get_util_intf(); + if (util == NULL) { + pr_err("Failed to get mdss utility functions\n"); return -ENODEV; } - ctrl_pdata = platform_get_drvdata(pdev); - if (!ctrl_pdata) { - ctrl_pdata = devm_kzalloc(&pdev->dev, - sizeof(struct mdss_dsi_ctrl_pdata), - GFP_KERNEL); - if (!ctrl_pdata) { - pr_err("%s: FAILED: cannot alloc dsi ctrl\n", - __func__); - rc = -ENOMEM; - goto error_no_mem; - } - platform_set_drvdata(pdev, ctrl_pdata); - } ctrl_pdata->mdss_util = util; atomic_set(&ctrl_pdata->te_irq_ready, 0); @@ -2067,29 +2109,6 @@ static int mdss_dsi_ctrl_probe(struct platform_device *pdev) pr_info("%s: DSI Ctrl name = %s\n", __func__, ctrl_name); - rc = of_property_read_u32(pdev->dev.of_node, - "cell-index", &index); - if (rc) { - dev_err(&pdev->dev, - "%s: Cell-index not specified, rc=%d\n", - __func__, rc); - goto error_no_mem; - } - - if (index == 0) - pdev->id = 1; - else - pdev->id = 2; - - rc = of_platform_populate(pdev->dev.of_node, - NULL, NULL, &pdev->dev); - if (rc) { - dev_err(&pdev->dev, - "%s: failed to add child nodes, rc=%d\n", - __func__, rc); - goto error_no_mem; - } - rc = mdss_dsi_pinctrl_init(pdev); if (rc) pr_warn("%s: failed to get pin resources\n", __func__); @@ -2107,38 +2126,37 @@ static int mdss_dsi_ctrl_probe(struct platform_device *pdev) } } - /* DSI panels can be different between controllers */ - rc = mdss_dsi_get_panel_cfg(panel_cfg, ctrl_pdata); - if (!rc) - /* dsi panel cfg not present */ - pr_warn("%s:%d:dsi specific cfg not present\n", - __func__, __LINE__); + if (index == 0) + ctrl_pdata->panel_data.panel_info.pdest = DISPLAY_1; + else + ctrl_pdata->panel_data.panel_info.pdest = DISPLAY_2; - /* find panel device node */ - dsi_pan_node = mdss_dsi_find_panel_of_node(pdev, panel_cfg); + dsi_pan_node = mdss_dsi_config_panel(pdev); if (!dsi_pan_node) { - pr_err("%s: can't find panel node %s\n", __func__, panel_cfg); - goto error_pan_node; + pr_err("%s: panel configuration failed\n", __func__); + i--; + rc = -EINVAL; + goto error_vreg; } - cmd_cfg_cont_splash = mdss_panel_get_boot_cfg() ? true : false; - - rc = mdss_dsi_panel_init(dsi_pan_node, ctrl_pdata, cmd_cfg_cont_splash); - if (rc) { - pr_err("%s: dsi panel init failed\n", __func__); - goto error_pan_node; + if ((mdss_dsi_res->hw_config != SPLIT_DSI) || + ((mdss_dsi_res->hw_config == SPLIT_DSI) && + (ctrl_pdata->panel_data.panel_info.pdest == DISPLAY_1))) { + rc = mdss_panel_parse_bl_settings(dsi_pan_node, ctrl_pdata); + if (rc) { + pr_err("%s: dsi bl settings parse failed\n", __func__); + goto error_pan_node; + } + } else { + ctrl_pdata->bklt_ctrl = UNKNOWN_CTRL; } - rc = dsi_panel_device_register(dsi_pan_node, ctrl_pdata); + rc = dsi_panel_device_register(pdev, dsi_pan_node, ctrl_pdata); if (rc) { pr_err("%s: dsi panel dev reg failed\n", __func__); goto error_pan_node; } - ctrl_pdata->cmd_clk_ln_recovery_en = - of_property_read_bool(pdev->dev.of_node, - "qcom,dsi-clk-ln-recovery"); - if (mdss_dsi_is_te_based_esd(ctrl_pdata)) { rc = devm_request_irq(&pdev->dev, gpio_to_irq(ctrl_pdata->disp_te_gpio), @@ -2160,12 +2178,170 @@ error_vreg: for (; i >= 0; i--) mdss_dsi_put_dt_vreg_data(&pdev->dev, &ctrl_pdata->power_data[i]); -error_no_mem: - devm_kfree(&pdev->dev, ctrl_pdata); + return rc; +} + +static void mdss_dsi_res_deinit(struct platform_device *pdev) +{ + int i; + struct mdss_dsi_data *dsi_res = platform_get_drvdata(pdev); + if (!dsi_res) { + pr_err("%s: DSI root device drvdata not found\n", __func__); + return; + } + + for (i = 0; i < DSI_CTRL_MAX; i++) { + if (dsi_res->ctrl_pdata[i]) + devm_kfree(&pdev->dev, dsi_res->ctrl_pdata[i]); + } + + if (dsi_res) + devm_kfree(&pdev->dev, dsi_res); + + return; +} + +static int mdss_dsi_res_init(struct platform_device *pdev) +{ + int rc = 0, i; + + mdss_dsi_res = platform_get_drvdata(pdev); + if (!mdss_dsi_res) { + mdss_dsi_res = devm_kzalloc(&pdev->dev, + sizeof(struct mdss_dsi_data), + GFP_KERNEL); + if (!mdss_dsi_res) { + pr_err("%s: FAILED: cannot alloc dsi data\n", + __func__); + rc = -ENOMEM; + 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; + } + } + + platform_set_drvdata(pdev, mdss_dsi_res); + } + + mdss_dsi_res->pdev = pdev; + pr_debug("%s: Setting up mdss_dsi_res=%p\n", __func__, mdss_dsi_res); + + return 0; + +mem_fail: + mdss_dsi_res_deinit(pdev); return rc; } +static int mdss_dsi_parse_hw_cfg(struct platform_device *pdev) +{ + const char *data; + struct mdss_dsi_data *dsi_res = platform_get_drvdata(pdev); + + if (!dsi_res) { + pr_err("%s: DSI root device drvdata not found\n", __func__); + return -EINVAL; + } + + dsi_res->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; + else if (!strcmp(data, "split_dsi")) + dsi_res->hw_config = SPLIT_DSI; + else if (!strcmp(data, "single_dsi")) + dsi_res->hw_config = SINGLE_DSI; + else + pr_err("%s: Incorrect string for DSI config:%s. Setting default as SINGLE_DSI\n", + __func__, data); + } else { + pr_err("%s: Error: No DSI HW config found\n", + __func__); + return -EINVAL; + } + + pr_debug("%s: DSI h/w configuration is %d\n", __func__, + dsi_res->hw_config); + + return 0; +} + +static const struct of_device_id mdss_dsi_ctrl_dt_match[] = { + {.compatible = "qcom,mdss-dsi-ctrl"}, + {} +}; +MODULE_DEVICE_TABLE(of, mdss_dsi_ctrl_dt_match); + +static int mdss_dsi_probe(struct platform_device *pdev) +{ + struct mdss_panel_cfg *pan_cfg = NULL; + struct mdss_util_intf *util; + int rc = 0; + + util = mdss_get_util_intf(); + if (util == NULL) { + pr_err("%s: Failed to get mdss utility functions\n", __func__); + return -ENODEV; + } + + if (!util->mdp_probe_done) { + pr_err("%s: MDP not probed yet!\n", __func__); + return -EPROBE_DEFER; + } + + if (!pdev || !pdev->dev.of_node) { + pr_err("%s: DSI driver only supports device tree probe\n", + __func__); + return -ENOTSUPP; + } + + pan_cfg = util->panel_intf_type(MDSS_PANEL_INTF_HDMI); + if (IS_ERR(pan_cfg)) { + return PTR_ERR(pan_cfg); + } else if (pan_cfg) { + pr_debug("%s: HDMI is primary\n", __func__); + return -ENODEV; + } + + rc = mdss_dsi_res_init(pdev); + if (rc) { + pr_err("%s Unable to set dsi res\n", __func__); + return rc; + } + + rc = mdss_dsi_parse_hw_cfg(pdev); + if (rc) { + pr_err("%s Unable to parse dsi h/w config\n", __func__); + mdss_dsi_res_deinit(pdev); + return rc; + } + + of_platform_populate(pdev->dev.of_node, mdss_dsi_ctrl_dt_match, + NULL, &pdev->dev); + + return 0; +} + +static int mdss_dsi_remove(struct platform_device *pdev) +{ + mdss_dsi_res_deinit(pdev); + return 0; +} + static int mdss_dsi_ctrl_remove(struct platform_device *pdev) { struct msm_fb_data_type *mfd; @@ -2321,53 +2497,12 @@ static void mdss_dsi_parse_lane_swap(struct device_node *np, char *dlane_swap) } } -int dsi_panel_device_register(struct device_node *pan_node, - struct mdss_dsi_ctrl_pdata *ctrl_pdata) +static int mdss_dsi_parse_ctrl_params(struct platform_device *ctrl_pdev, + struct device_node *pan_node, struct mdss_dsi_ctrl_pdata *ctrl_pdata) { - struct mipi_panel_info *mipi; int rc, i, len; struct mdss_panel_info *pinfo = &(ctrl_pdata->panel_data.panel_info); - struct device_node *dsi_ctrl_np = NULL; - struct platform_device *ctrl_pdev = NULL; const char *data; - u64 clk_rate; - struct resource *res; - - mipi = &(pinfo->mipi); - - pinfo->type = - ((mipi->mode == DSI_VIDEO_MODE) - ? MIPI_VIDEO_PANEL : MIPI_CMD_PANEL); - - rc = mdss_dsi_clk_div_config(pinfo, mipi->frame_rate); - if (rc) { - pr_err("%s: unable to initialize the clk dividers\n", __func__); - return rc; - } - - dsi_ctrl_np = of_parse_phandle(pan_node, - "qcom,mdss-dsi-panel-controller", 0); - if (!dsi_ctrl_np) { - pr_err("%s: Dsi controller node not initialized\n", __func__); - return -EPROBE_DEFER; - } - - ctrl_pdev = of_find_device_by_node(dsi_ctrl_np); - - rc = mdss_dsi_get_dt_vreg_data(&ctrl_pdev->dev, pan_node, - &ctrl_pdata->power_data[DSI_PANEL_PM], 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); - if (rc) { - pr_err("%s: failed to init regulator, rc=%d\n", - __func__, rc); - return rc; - } data = of_get_property(ctrl_pdev->dev.of_node, "qcom,platform-strength-ctrl", &len); @@ -2435,15 +2570,33 @@ int dsi_panel_device_register(struct device_node *pan_node, ctrl_pdata->cmd_sync_wait_broadcast = of_property_read_bool( pan_node, "qcom,cmd-sync-wait-broadcast"); - ctrl_pdata->cmd_sync_wait_trigger = of_property_read_bool( - pan_node, "qcom,cmd-sync-wait-trigger"); + if (ctrl_pdata->cmd_sync_wait_broadcast && + (mdss_dsi_res->hw_config == SPLIT_DSI) && + (pinfo->pdest == DISPLAY_2)) + ctrl_pdata->cmd_sync_wait_trigger = true; pr_debug("%s: cmd_sync_wait_enable=%d trigger=%d\n", __func__, ctrl_pdata->cmd_sync_wait_broadcast, ctrl_pdata->cmd_sync_wait_trigger); - pinfo->panel_max_fps = mdss_panel_get_framerate(pinfo); - pinfo->panel_max_vtotal = mdss_panel_get_vtotal(pinfo); + 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)); + + return 0; + + +} + +static int mdss_dsi_parse_gpio_params(struct platform_device *ctrl_pdev, + struct mdss_dsi_ctrl_pdata *ctrl_pdata) +{ + struct mdss_panel_info *pinfo = &(ctrl_pdata->panel_data.panel_info); /* * If disp_en_gpio has been set previously (disp_en_gpio > 0) @@ -2489,11 +2642,61 @@ int dsi_panel_device_register(struct device_node *pan_node, ctrl_pdata->mode_gpio = -EINVAL; } - mdss_dsi_parse_lane_swap(ctrl_pdev->dev.of_node, - &(ctrl_pdata->dlane_swap)); + return 0; +} - ctrl_pdata->timing_db_mode = of_property_read_bool( - ctrl_pdev->dev.of_node, "qcom,timing-db-mode"); +int dsi_panel_device_register(struct platform_device *ctrl_pdev, + struct device_node *pan_node, struct mdss_dsi_ctrl_pdata *ctrl_pdata) +{ + struct mipi_panel_info *mipi; + int rc; + struct mdss_panel_info *pinfo = &(ctrl_pdata->panel_data.panel_info); + struct resource *res; + u64 clk_rate; + + mipi = &(pinfo->mipi); + + pinfo->type = + ((mipi->mode == DSI_VIDEO_MODE) + ? MIPI_VIDEO_PANEL : MIPI_CMD_PANEL); + + rc = mdss_dsi_clk_div_config(pinfo, mipi->frame_rate); + if (rc) { + pr_err("%s: unable to initialize the clk dividers\n", __func__); + return rc; + } + + rc = mdss_dsi_get_dt_vreg_data(&ctrl_pdev->dev, pan_node, + &ctrl_pdata->power_data[DSI_PANEL_PM], 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); + if (rc) { + pr_err("%s: failed to init regulator, rc=%d\n", + __func__, rc); + return rc; + } + + rc = mdss_dsi_parse_ctrl_params(ctrl_pdev, pan_node, ctrl_pdata); + if (rc) { + pr_err("%s: failed to parse ctrl settings, rc=%d\n", + __func__, rc); + return rc; + } + + pinfo->panel_max_fps = mdss_panel_get_framerate(pinfo); + pinfo->panel_max_vtotal = mdss_panel_get_vtotal(pinfo); + + rc = mdss_dsi_parse_gpio_params(ctrl_pdev, ctrl_pdata); + if (rc) { + pr_err("%s: failed to parse gpio params, rc=%d\n", + __func__, rc); + return rc; + } if (mdss_dsi_clk_init(ctrl_pdev, ctrl_pdata)) { pr_err("%s: unable to initialize Dsi ctrl clks\n", __func__); @@ -2629,11 +2832,21 @@ int dsi_panel_device_register(struct device_node *pan_node, return 0; } -static const struct of_device_id mdss_dsi_ctrl_dt_match[] = { - {.compatible = "qcom,mdss-dsi-ctrl"}, +static const struct of_device_id mdss_dsi_dt_match[] = { + {.compatible = "qcom,mdss-dsi"}, {} }; -MODULE_DEVICE_TABLE(of, mdss_dsi_ctrl_dt_match); +MODULE_DEVICE_TABLE(of, mdss_dsi_dt_match); + +static struct platform_driver mdss_dsi_driver = { + .probe = mdss_dsi_probe, + .remove = mdss_dsi_remove, + .shutdown = NULL, + .driver = { + .name = "mdss_dsi", + .of_match_table = mdss_dsi_dt_match, + }, +}; static struct platform_driver mdss_dsi_ctrl_driver = { .probe = mdss_dsi_ctrl_probe, @@ -2647,7 +2860,7 @@ static struct platform_driver mdss_dsi_ctrl_driver = { static int mdss_dsi_register_driver(void) { - return platform_driver_register(&mdss_dsi_ctrl_driver); + return platform_driver_register(&mdss_dsi_driver); } static int __init mdss_dsi_driver_init(void) @@ -2664,6 +2877,26 @@ static int __init mdss_dsi_driver_init(void) } module_init(mdss_dsi_driver_init); + +static int mdss_dsi_ctrl_register_driver(void) +{ + return platform_driver_register(&mdss_dsi_ctrl_driver); +} + +static int __init mdss_dsi_ctrl_driver_init(void) +{ + int ret; + + ret = mdss_dsi_ctrl_register_driver(); + if (ret) { + pr_err("mdss_dsi_ctrl_register_driver() failed!\n"); + return ret; + } + + return ret; +} +module_init(mdss_dsi_ctrl_driver_init); + static void __exit mdss_dsi_driver_cleanup(void) { platform_driver_unregister(&mdss_dsi_ctrl_driver); diff --git a/drivers/video/fbdev/msm/mdss_dsi.h b/drivers/video/fbdev/msm/mdss_dsi.h index 5a403d542528..a8076b6cac91 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.h +++ b/drivers/video/fbdev/msm/mdss_dsi.h @@ -204,48 +204,34 @@ extern struct device dsi_dev; extern u32 dsi_irq; extern struct mdss_dsi_ctrl_pdata *ctrl_list[]; -struct dsiphy_pll_divider_config { - u64 clk_rate; - u32 fb_divider; - u32 ref_divider_ratio; - u32 bit_clk_divider; /* oCLK1 */ - u32 byte_clk_divider; /* oCLK2 */ - u32 analog_posDiv; - u32 digital_posDiv; -}; - -extern struct dsiphy_pll_divider_config pll_divider_config; - -struct dsi_clk_mnd_table { - u8 lanes; - u8 bpp; - u8 pll_digital_posDiv; - u8 pclk_m; - u8 pclk_n; - u8 pclk_d; +enum { + DSI_CTRL_0, + DSI_CTRL_1, + DSI_CTRL_MAX, }; -static const struct dsi_clk_mnd_table mnd_table[] = { - { 1, 2, 8, 1, 1, 0}, - { 1, 3, 12, 1, 1, 0}, - { 2, 2, 4, 1, 1, 0}, - { 2, 3, 6, 1, 1, 0}, - { 3, 2, 1, 3, 8, 4}, - { 3, 3, 4, 1, 1, 0}, - { 4, 2, 2, 1, 1, 0}, - { 4, 3, 3, 1, 1, 0}, +struct mdss_dsi_data { + u32 hw_config; /* DSI setup configuration i.e. single/dual/split */ + bool res_init; + struct platform_device *pdev; + /* List of controller specific struct data */ + struct mdss_dsi_ctrl_pdata *ctrl_pdata[DSI_CTRL_MAX]; }; -struct dsi_clk_desc { - u32 src; - u32 m; - u32 n; - u32 d; - u32 mnd_mode; - u32 pre_div_func; +/* + * enum mdss_dsi_hw_config - Supported DSI h/w configurations + * + * @SINGLE_DSI: Single DSI panel driven by either DSI0 or DSI1. + * @DUAL_DSI: Two DSI panels driven independently by DSI0 & DSI1. + * @SPLIT_DSI: A split DSI panel driven by both the DSI controllers + * with the DSI link clocks sourced by a single DSI PLL. + */ +enum mdss_dsi_hw_config { + SINGLE_DSI, + DUAL_DSI, + SPLIT_DSI, }; - struct dsi_panel_cmds { char *buf; int blen; @@ -277,12 +263,6 @@ struct panel_horizontal_idle { int idle; }; -enum { - DSI_CTRL_0, - DSI_CTRL_1, - DSI_CTRL_MAX, -}; - #define DSI_CTRL_LEFT DSI_CTRL_0 #define DSI_CTRL_RIGHT DSI_CTRL_1 #define DSI_CTRL_CLK_SLAVE DSI_CTRL_RIGHT @@ -441,8 +421,8 @@ struct dsi_status_data { }; void mdss_dsi_read_hw_revision(struct mdss_dsi_ctrl_pdata *ctrl); -int dsi_panel_device_register(struct device_node *pan_node, - struct mdss_dsi_ctrl_pdata *ctrl_pdata); +int dsi_panel_device_register(struct platform_device *ctrl_pdev, + struct device_node *pan_node, struct mdss_dsi_ctrl_pdata *ctrl_pdata); int mdss_dsi_cmds_tx(struct mdss_dsi_ctrl_pdata *ctrl, struct dsi_cmd_desc *cmds, int cnt); @@ -510,6 +490,8 @@ u32 mdss_dsi_panel_cmd_read(struct mdss_dsi_ctrl_pdata *ctrl, char cmd0, int mdss_dsi_panel_init(struct device_node *node, struct mdss_dsi_ctrl_pdata *ctrl_pdata, bool cmd_cfg_cont_splash); +int mdss_panel_parse_bl_settings(struct device_node *np, + struct mdss_dsi_ctrl_pdata *ctrl_pdata); int mdss_panel_get_dst_fmt(u32 bpp, char mipi_mode, u32 pixel_packing, char *dst_format); diff --git a/drivers/video/fbdev/msm/mdss_dsi_panel.c b/drivers/video/fbdev/msm/mdss_dsi_panel.c index 8feaf5188a11..b05689da9ec5 100644 --- a/drivers/video/fbdev/msm/mdss_dsi_panel.c +++ b/drivers/video/fbdev/msm/mdss_dsi_panel.c @@ -1588,7 +1588,8 @@ static int mdss_dsi_parse_panel_features(struct device_node *np, "qcom,partial-update-roi-merge"); } - pinfo->dcs_cmd_by_left = of_property_read_bool(np, + if (pinfo->pdest == DISPLAY_1) + pinfo->dcs_cmd_by_left = of_property_read_bool(np, "qcom,dcs-cmd-by-left"); } @@ -1754,13 +1755,73 @@ static void mdss_dsi_parse_dfps_config(struct device_node *pan_node, return; } +int mdss_panel_parse_bl_settings(struct device_node *np, + struct mdss_dsi_ctrl_pdata *ctrl_pdata) +{ + const char *data; + int rc = 0; + u32 tmp; + + ctrl_pdata->bklt_ctrl = UNKNOWN_CTRL; + data = of_get_property(np, "qcom,mdss-dsi-bl-pmic-control-type", NULL); + if (data) { + if (!strcmp(data, "bl_ctrl_wled")) { + led_trigger_register_simple("bkl-trigger", + &bl_led_trigger); + pr_debug("%s: SUCCESS-> WLED TRIGGER register\n", + __func__); + ctrl_pdata->bklt_ctrl = BL_WLED; + } else if (!strcmp(data, "bl_ctrl_pwm")) { + ctrl_pdata->bklt_ctrl = BL_PWM; + ctrl_pdata->pwm_pmi = of_property_read_bool(np, + "qcom,mdss-dsi-bl-pwm-pmi"); + rc = of_property_read_u32(np, + "qcom,mdss-dsi-bl-pmic-pwm-frequency", &tmp); + if (rc) { + pr_err("%s:%d, Error, panel pwm_period\n", + __func__, __LINE__); + return -EINVAL; + } + ctrl_pdata->pwm_period = tmp; + if (ctrl_pdata->pwm_pmi) { + ctrl_pdata->pwm_bl = of_pwm_get(np, NULL); + if (IS_ERR(ctrl_pdata->pwm_bl)) { + pr_err("%s: Error, pwm device\n", + __func__); + ctrl_pdata->pwm_bl = NULL; + return -EINVAL; + } + } else { + rc = of_property_read_u32(np, + "qcom,mdss-dsi-bl-pmic-bank-select", + &tmp); + if (rc) { + pr_err("%s:%d, Error, lpg channel\n", + __func__, __LINE__); + return -EINVAL; + } + ctrl_pdata->pwm_lpg_chan = tmp; + tmp = of_get_named_gpio(np, + "qcom,mdss-dsi-pwm-gpio", 0); + ctrl_pdata->pwm_pmic_gpio = tmp; + pr_debug("%s: Configured PWM bklt ctrl\n", + __func__); + } + } else if (!strcmp(data, "bl_ctrl_dcs")) { + ctrl_pdata->bklt_ctrl = BL_DCS_CMD; + pr_debug("%s: Configured DCS_CMD bklt ctrl\n", + __func__); + } + } + return 0; +} + static int mdss_panel_parse_dt(struct device_node *np, struct mdss_dsi_ctrl_pdata *ctrl_pdata) { u32 tmp; int rc, i, len; const char *data; - static const char *pdest; struct mdss_panel_info *pinfo = &(ctrl_pdata->panel_data.panel_info); rc = of_property_read_u32(np, "qcom,mdss-dsi-panel-width", &tmp); @@ -1829,28 +1890,6 @@ static int mdss_panel_parse_dt(struct device_node *np, pinfo->mipi.dst_format = DSI_VIDEO_DST_FORMAT_RGB888; } - pdest = of_get_property(np, - "qcom,mdss-dsi-panel-destination", NULL); - - if (pdest) { - if (strlen(pdest) != 9) { - pr_err("%s: Unknown pdest specified\n", __func__); - return -EINVAL; - } - if (!strcmp(pdest, "display_1")) - pinfo->pdest = DISPLAY_1; - else if (!strcmp(pdest, "display_2")) - pinfo->pdest = DISPLAY_2; - else { - pr_debug("%s: incorrect pdest. Set Default\n", - __func__); - pinfo->pdest = DISPLAY_1; - } - } else { - pr_debug("%s: pdest not specified. Set Default\n", - __func__); - pinfo->pdest = DISPLAY_1; - } rc = of_property_read_u32(np, "qcom,mdss-dsi-h-front-porch", &tmp); pinfo->lcdc.h_front_porch = (!rc ? tmp : 6); rc = of_property_read_u32(np, "qcom,mdss-dsi-h-back-porch", &tmp); @@ -1882,57 +1921,6 @@ static int mdss_panel_parse_dt(struct device_node *np, pinfo->panel_orientation = MDP_FLIP_UD; } - ctrl_pdata->bklt_ctrl = UNKNOWN_CTRL; - data = of_get_property(np, "qcom,mdss-dsi-bl-pmic-control-type", NULL); - if (data) { - if (!strncmp(data, "bl_ctrl_wled", 12)) { - led_trigger_register_simple("bkl-trigger", - &bl_led_trigger); - pr_debug("%s: SUCCESS-> WLED TRIGGER register\n", - __func__); - ctrl_pdata->bklt_ctrl = BL_WLED; - } else if (!strncmp(data, "bl_ctrl_pwm", 11)) { - ctrl_pdata->bklt_ctrl = BL_PWM; - ctrl_pdata->pwm_pmi = of_property_read_bool(np, - "qcom,mdss-dsi-bl-pwm-pmi"); - rc = of_property_read_u32(np, - "qcom,mdss-dsi-bl-pmic-pwm-frequency", &tmp); - if (rc) { - pr_err("%s:%d, Error, panel pwm_period\n", - __func__, __LINE__); - return -EINVAL; - } - ctrl_pdata->pwm_period = tmp; - if (ctrl_pdata->pwm_pmi) { - ctrl_pdata->pwm_bl = of_pwm_get(np, NULL); - if (IS_ERR(ctrl_pdata->pwm_bl)) { - pr_err("%s: Error, pwm device\n", - __func__); - ctrl_pdata->pwm_bl = NULL; - return -EINVAL; - } - } else { - rc = of_property_read_u32(np, - "qcom,mdss-dsi-bl-pmic-bank-select", - &tmp); - if (rc) { - pr_err("%s:%d, Error, lpg channel\n", - __func__, __LINE__); - return -EINVAL; - } - ctrl_pdata->pwm_lpg_chan = tmp; - tmp = of_get_named_gpio(np, - "qcom,mdss-dsi-pwm-gpio", 0); - ctrl_pdata->pwm_pmic_gpio = tmp; - pr_debug("%s: Configured PWM bklt ctrl\n", - __func__); - } - } else if (!strncmp(data, "bl_ctrl_dcs", 11)) { - ctrl_pdata->bklt_ctrl = BL_DCS_CMD; - pr_debug("%s: Configured DCS_CMD bklt ctrl\n", - __func__); - } - } rc = of_property_read_u32(np, "qcom,mdss-brightness-max-level", &tmp); pinfo->brightness_max = (!rc ? tmp : MDSS_MAX_BL_BRIGHTNESS); rc = of_property_read_u32(np, "qcom,mdss-dsi-bl-min-level", &tmp); diff --git a/drivers/video/fbdev/msm/msm_mdss_io_8974.c b/drivers/video/fbdev/msm/msm_mdss_io_8974.c index 047f1090926f..6d2c28acb3a1 100644 --- a/drivers/video/fbdev/msm/msm_mdss_io_8974.c +++ b/drivers/video/fbdev/msm/msm_mdss_io_8974.c @@ -51,8 +51,6 @@ #define DSIPHY_PLL_CLKBUFLR_EN 0x041c #define DSIPHY_PLL_PLL_BANDGAP 0x0508 -static struct dsi_clk_desc dsi_pclk; - static void mdss_dsi_ctrl_phy_reset(struct mdss_dsi_ctrl_pdata *ctrl) { /* start phy sw reset */ @@ -796,8 +794,6 @@ void mdss_dsi_shadow_clk_deinit(struct mdss_dsi_ctrl_pdata *ctrl) clk_put(ctrl->shadow_pixel_clk); } -#define PREF_DIV_RATIO 27 -struct dsiphy_pll_divider_config pll_divider_config; int mdss_dsi_clk_div_config(struct mdss_panel_info *panel_info, int frame_rate) @@ -806,13 +802,9 @@ int mdss_dsi_clk_div_config(struct mdss_panel_info *panel_info, struct mdss_panel_data, panel_info); struct mdss_dsi_ctrl_pdata *ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); - u32 fb_divider, rate, vco; - u32 div_ratio = 0; - u32 pll_analog_posDiv = 1; u64 h_period, v_period, clk_rate; u32 dsi_pclk_rate; u8 lanes = 0, bpp; - struct dsi_clk_mnd_table const *mnd_entry = mnd_table; if (panel_info->mipi.data_lane3) lanes += 1; @@ -854,75 +846,11 @@ int mdss_dsi_clk_div_config(struct mdss_panel_info *panel_info, h_period * v_period * frame_rate * bpp * 8; } } - pll_divider_config.clk_rate = panel_info->clk_rate; - - if (pll_divider_config.clk_rate == 0) - pll_divider_config.clk_rate = 454000000; - - /* Half Bit Clock In Mhz */ - clk_rate = pll_divider_config.clk_rate; - do_div(clk_rate, 2U); - do_div(clk_rate, 1000000U); - rate = (u32)clk_rate; - - if (rate < 43) { - vco = rate * 16; - div_ratio = 16; - pll_analog_posDiv = 8; - } else if (rate < 85) { - vco = rate * 8; - div_ratio = 8; - pll_analog_posDiv = 4; - } else if (rate < 170) { - vco = rate * 4; - div_ratio = 4; - pll_analog_posDiv = 2; - } else if (rate < 340) { - vco = rate * 2; - div_ratio = 2; - pll_analog_posDiv = 1; - } else { - /* DSI PLL Direct path configuration */ - vco = rate * 1; - div_ratio = 1; - pll_analog_posDiv = 1; - } - /* find the mnd settings from mnd_table entry */ - for (; mnd_entry < mnd_table + ARRAY_SIZE(mnd_table); ++mnd_entry) { - if (((mnd_entry->lanes) == lanes) && - ((mnd_entry->bpp) == bpp)) - break; - } + if (panel_info->clk_rate == 0) + panel_info->clk_rate = 454000000; - if (mnd_entry == mnd_table + ARRAY_SIZE(mnd_table)) { - pr_err("%s: requested Lanes, %u & BPP, %u, not supported\n", - __func__, lanes, bpp); - return -EINVAL; - } - fb_divider = ((vco * PREF_DIV_RATIO) / 27); - pll_divider_config.fb_divider = fb_divider; - pll_divider_config.ref_divider_ratio = PREF_DIV_RATIO; - pll_divider_config.bit_clk_divider = div_ratio; - pll_divider_config.byte_clk_divider = - pll_divider_config.bit_clk_divider * 8; - pll_divider_config.analog_posDiv = pll_analog_posDiv; - pll_divider_config.digital_posDiv = - (mnd_entry->pll_digital_posDiv) * div_ratio; - - if ((mnd_entry->pclk_d == 0) - || (mnd_entry->pclk_m == 1)) { - dsi_pclk.mnd_mode = 0; - dsi_pclk.src = 0x3; - dsi_pclk.pre_div_func = (mnd_entry->pclk_n - 1); - } else { - dsi_pclk.mnd_mode = 2; - dsi_pclk.src = 0x3; - dsi_pclk.m = mnd_entry->pclk_m; - dsi_pclk.n = mnd_entry->pclk_n; - dsi_pclk.d = mnd_entry->pclk_d; - } - clk_rate = pll_divider_config.clk_rate; + clk_rate = panel_info->clk_rate; do_div(clk_rate, 8 * bpp); dsi_pclk_rate = (u32) clk_rate * lanes; |
