int dsi_panel_device_register(struct device_node *pan_node, struct mdss_dsi_ctrl_pdata *ctrl_pdata) { struct mipi_panel_info *mipi; int rc, i, len; struct device_node *dsi_ctrl_np = NULL; struct platform_device *ctrl_pdev = NULL; bool dynamic_fps; const char *data; struct mdss_panel_info *pinfo = &(ctrl_pdata->panel_data.panel_info); enum of_gpio_flags flags; 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_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); if ((!data) || (len != 2)) { pr_err("%s:%d, Unable to read Phy Strength ctrl settings", __func__, __LINE__); return -EINVAL; } pinfo->mipi.dsi_phy_db.strength[0] = data[0]; pinfo->mipi.dsi_phy_db.strength[1] = data[1]; data = of_get_property(ctrl_pdev->dev.of_node, "qcom,platform-regulator-settings", &len); if ((!data) || (len != 7)) { pr_err("%s:%d, Unable to read Phy regulator settings", __func__, __LINE__); return -EINVAL; } for (i = 0; i < len; i++) { pinfo->mipi.dsi_phy_db.regulator[i] = data[i]; } data = of_get_property(ctrl_pdev->dev.of_node, "qcom,platform-bist-ctrl", &len); if ((!data) || (len != 6)) { pr_err("%s:%d, Unable to read Phy Bist Ctrl settings", __func__, __LINE__); return -EINVAL; } for (i = 0; i < len; i++) { pinfo->mipi.dsi_phy_db.bistctrl[i] = data[i]; } data = of_get_property(ctrl_pdev->dev.of_node, "qcom,platform-lane-config", &len); if ((!data) || (len != 45)) { pr_err("%s:%d, Unable to read Phy lane configure settings", __func__, __LINE__); return -EINVAL; } for (i = 0; i < len; i++) { pinfo->mipi.dsi_phy_db.lanecfg[i] = data[i]; } ctrl_pdata->shared_pdata.broadcast_enable = of_property_read_bool( pan_node, "qcom,mdss-dsi-panel-broadcast-mode"); dynamic_fps = of_property_read_bool(pan_node, "qcom,mdss-dsi-pan-enable-dynamic-fps"); if (dynamic_fps) { pinfo->dynamic_fps = true; data = of_get_property(pan_node, "qcom,mdss-dsi-pan-fps-update", NULL); if (data) { if (!strcmp(data, "dfps_suspend_resume_mode")) { pinfo->dfps_update = DFPS_SUSPEND_RESUME_MODE; pr_debug("%s: dfps mode: suspend/resume\n", __func__); } else if (!strcmp(data, "dfps_immediate_clk_mode")) { pinfo->dfps_update = DFPS_IMMEDIATE_CLK_UPDATE_MODE; pr_debug("%s: dfps mode: Immediate clk\n", __func__); } else if (!strcmp(data, "dfps_immediate_porch_mode")) { pinfo->dfps_update = DFPS_IMMEDIATE_PORCH_UPDATE_MODE; pr_debug("%s: dfps mode: Immediate porch\n", __func__); } else { pr_debug("%s: dfps to default mode\n", __func__); pinfo->dfps_update = DFPS_SUSPEND_RESUME_MODE; pr_debug("%s: dfps mode: suspend/resume\n", __func__); } } else { pr_debug("%s: dfps update mode not configured\n", __func__); pinfo->dynamic_fps = false; pr_debug("%s: dynamic FPS disabled\n", __func__); } pinfo->new_fps = pinfo->mipi.frame_rate; } pinfo->panel_max_fps = mdss_panel_get_framerate(pinfo); pinfo->panel_max_vtotal = mdss_panel_get_vtotal(pinfo); ctrl_pdata->disp_en_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-enable-gpio", 0); if (!gpio_is_valid(ctrl_pdata->disp_en_gpio)) pr_err("%s:%d, Disp_en gpio not specified\n", __func__, __LINE__); ctrl_pdata->disp_te_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-te-gpio", 0); if (!gpio_is_valid(ctrl_pdata->disp_te_gpio)) { pr_err("%s:%d, Disp_te gpio not specified\n", __func__, __LINE__); } else { int func; rc = gpio_request(ctrl_pdata->disp_te_gpio, "disp_te"); if (rc) { pr_err("request TE gpio failed, rc=%d\n", rc); return -ENODEV; } if (pinfo->type == MIPI_CMD_PANEL) func = 1; else func = 0; rc = gpio_tlmm_config(GPIO_CFG( ctrl_pdata->disp_te_gpio, func, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), GPIO_CFG_ENABLE); if (rc) { pr_err("%s: unable to config tlmm = %d\n", __func__, ctrl_pdata->disp_te_gpio); gpio_free(ctrl_pdata->disp_te_gpio); return -ENODEV; } rc = gpio_direction_input(ctrl_pdata->disp_te_gpio); if (rc) { pr_err("set_direction for disp_en gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_te_gpio); return -ENODEV; } pr_debug("%s: te_gpio=%d\n", __func__, ctrl_pdata->disp_te_gpio); } ctrl_pdata->rst_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-reset-gpio", 0); if (!gpio_is_valid(ctrl_pdata->rst_gpio)) pr_err("%s:%d, reset gpio not specified\n", __func__, __LINE__); ctrl_pdata->mode_gpio = of_get_named_gpio( ctrl_pdev->dev.of_node, "qcom,platform-mode-gpio", 0); if (pinfo->mode_gpio_state != MODE_GPIO_NOT_VALID) { if (!gpio_is_valid(ctrl_pdata->mode_gpio)) pr_info("%s:%d, mode gpio not specified\n", __func__, __LINE__); } if (ctrl_pdata->partial_mode_enabled) { ctrl_pdata->mipi_d0_sel = of_get_named_gpio_flags( ctrl_pdev->dev.of_node, "mmi,mipi-d0-sel", 0, &flags); if (!gpio_is_valid(ctrl_pdata->mipi_d0_sel)) { pr_info("%s:%d, mipi d0 sel gpio not specified\n", __func__, __LINE__); ctrl_pdata->partial_mode_enabled = false; } else { rc = gpio_request_one(ctrl_pdata->mipi_d0_sel, flags, "mipi_d0_sel"); if (rc) { pr_err("request mipi d0 sel gpio failed, rc=%d\n", rc); if (gpio_is_valid(ctrl_pdata->disp_te_gpio)) gpio_free(ctrl_pdata->disp_te_gpio); ctrl_pdata->partial_mode_enabled = false; return -ENODEV; } gpio_export(ctrl_pdata->mipi_d0_sel, 1); } } if (mdss_dsi_clk_init(ctrl_pdev, ctrl_pdata)) { pr_err("%s: unable to initialize Dsi ctrl clks\n", __func__); return -EPERM; } if (mdss_dsi_retrieve_ctrl_resources(ctrl_pdev, pinfo->pdest, ctrl_pdata)) { pr_err("%s: unable to get Dsi controller res\n", __func__); return -EPERM; } ctrl_pdata->panel_data.event_handler = mdss_dsi_event_handler; if (ctrl_pdata->bklt_ctrl == BL_PWM) mdss_dsi_panel_pwm_cfg(ctrl_pdata); mdss_dsi_ctrl_init(ctrl_pdata); /* * register in mdp driver */ ctrl_pdata->pclk_rate = mipi->dsi_pclk_rate; ctrl_pdata->byte_clk_rate = pinfo->clk_rate / 8; pr_debug("%s: pclk=%d, bclk=%d\n", __func__, ctrl_pdata->pclk_rate, ctrl_pdata->byte_clk_rate); ctrl_pdata->ctrl_state = CTRL_STATE_UNKNOWN; if (pinfo->cont_splash_enabled) { pinfo->panel_power_on = 1; /* * This call intends to call to gpio_request for display's * reset gpio, because with cont_splash_enabled, there is * no call to the mdss_dsi_panel_reset(1), but when the first * suspend call, it will call mdss_dsi_panel_reset(0). This * will call to gpio_free() for reset spio, and WARN() msg will * be called because gpio_free() is called without gpio_request */ rc = mdss_dsi_panel_reset(&(ctrl_pdata->panel_data), 1); if (rc) { pr_err("%s: Panel reset on failed\n", __func__); return rc; } rc = mdss_dsi_panel_power_on(&(ctrl_pdata->panel_data), 1); if (rc) { pr_err("%s: Panel power on failed\n", __func__); return rc; } mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1); ctrl_pdata->ctrl_state |= (CTRL_STATE_PANEL_INIT | CTRL_STATE_MDP_ACTIVE); } else { pinfo->panel_power_on = 0; } rc = mdss_register_panel(ctrl_pdev, &(ctrl_pdata->panel_data)); if (rc) { pr_err("%s: unable to register MIPI DSI panel\n", __func__); return rc; } if (pinfo->pdest == DISPLAY_1) { mdss_debug_register_base("dsi0", ctrl_pdata->ctrl_base, ctrl_pdata->reg_size); ctrl_pdata->ndx = 0; } else { mdss_debug_register_base("dsi1", ctrl_pdata->ctrl_base, ctrl_pdata->reg_size); ctrl_pdata->ndx = 1; } pr_debug("%s: Panel data initialized\n", __func__); return 0; }
int dsi_panel_device_register(struct device_node *pan_node, struct mdss_dsi_ctrl_pdata *ctrl_pdata) { struct mipi_panel_info *mipi; int rc, i, len; struct device_node *dsi_ctrl_np = NULL; struct platform_device *ctrl_pdev = NULL; bool dynamic_fps; const char *data; struct mdss_panel_info *pinfo = &(ctrl_pdata->panel_data.panel_info); 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_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); if ((!data) || (len != 2)) { pr_err("%s:%d, Unable to read Phy Strength ctrl settings", __func__, __LINE__); return -EINVAL; } pinfo->mipi.dsi_phy_db.strength[0] = data[0]; pinfo->mipi.dsi_phy_db.strength[1] = data[1]; data = of_get_property(ctrl_pdev->dev.of_node, "qcom,platform-regulator-settings", &len); if ((!data) || (len != 7)) { pr_err("%s:%d, Unable to read Phy regulator settings", __func__, __LINE__); return -EINVAL; } for (i = 0; i < len; i++) { pinfo->mipi.dsi_phy_db.regulator[i] = data[i]; } data = of_get_property(ctrl_pdev->dev.of_node, "qcom,platform-bist-ctrl", &len); if ((!data) || (len != 6)) { pr_err("%s:%d, Unable to read Phy Bist Ctrl settings", __func__, __LINE__); return -EINVAL; } for (i = 0; i < len; i++) { pinfo->mipi.dsi_phy_db.bistctrl[i] = data[i]; } data = of_get_property(ctrl_pdev->dev.of_node, "qcom,platform-lane-config", &len); if ((!data) || (len != 45)) { pr_err("%s:%d, Unable to read Phy lane configure settings", __func__, __LINE__); return -EINVAL; } for (i = 0; i < len; i++) { pinfo->mipi.dsi_phy_db.lanecfg[i] = data[i]; } ctrl_pdata->shared_pdata.broadcast_enable = of_property_read_bool( pan_node, "qcom,mdss-dsi-panel-broadcast-mode"); dynamic_fps = of_property_read_bool(pan_node, "qcom,mdss-dsi-pan-enable-dynamic-fps"); if (dynamic_fps) { pinfo->dynamic_fps = true; data = of_get_property(pan_node, "qcom,mdss-dsi-pan-fps-update", NULL); if (data) { if (!strcmp(data, "dfps_suspend_resume_mode")) { pinfo->dfps_update = DFPS_SUSPEND_RESUME_MODE; pr_debug("%s: dfps mode: suspend/resume\n", __func__); } else if (!strcmp(data, "dfps_immediate_clk_mode")) { pinfo->dfps_update = DFPS_IMMEDIATE_CLK_UPDATE_MODE; pr_debug("%s: dfps mode: Immediate clk\n", __func__); } else if (!strcmp(data, "dfps_immediate_porch_mode")) { pinfo->dfps_update = DFPS_IMMEDIATE_PORCH_UPDATE_MODE; pr_debug("%s: dfps mode: Immediate porch\n", __func__); } else { pr_debug("%s: dfps to default mode\n", __func__); pinfo->dfps_update = DFPS_SUSPEND_RESUME_MODE; pr_debug("%s: dfps mode: suspend/resume\n", __func__); } } else { pr_debug("%s: dfps update mode not configured\n", __func__); pinfo->dynamic_fps = false; pr_debug("%s: dynamic FPS disabled\n", __func__); } pinfo->new_fps = pinfo->mipi.frame_rate; } ctrl_pdata->disp_en_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-enable-gpio", 0); if (!gpio_is_valid(ctrl_pdata->disp_en_gpio)) { pr_err("%s:%d, Disp_en gpio not specified\n", __func__, __LINE__); } else { rc = gpio_request(ctrl_pdata->disp_en_gpio, "disp_enable"); if (rc) { pr_err("request reset gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_en_gpio); return -ENODEV; } #ifdef CONFIG_HUAWEI_LCD rc = gpio_tlmm_config(GPIO_CFG( ctrl_pdata->disp_en_gpio, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE); if (rc) { pr_err("%s: unable to config tlmm = %d\n", __func__, ctrl_pdata->disp_en_gpio); gpio_free(ctrl_pdata->disp_en_gpio); return -ENODEV; } rc = gpio_direction_output(ctrl_pdata->disp_en_gpio,1); if (rc) { pr_err("set_direction for disp_en gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_en_gpio); return -ENODEV; } pr_debug("%s: disp_gpio=%d\n", __func__, ctrl_pdata->disp_en_gpio); #endif } #ifdef CONFIG_HUAWEI_LCD ctrl_pdata->bl_en_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,bl-enable-gpio", 0); if (!gpio_is_valid(ctrl_pdata->bl_en_gpio)) { pr_err("%s:%d, backlight_en gpio not specified\n", __func__, __LINE__); } else { rc = gpio_request(ctrl_pdata->bl_en_gpio, "backlight_enable"); if (rc) { pr_err("request backlight gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->bl_en_gpio); return -ENODEV; } rc = gpio_tlmm_config(GPIO_CFG( ctrl_pdata->bl_en_gpio, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE); if (rc) { pr_err("%s: unable to config tlmm = %d\n", __func__, ctrl_pdata->bl_en_gpio); gpio_free(ctrl_pdata->bl_en_gpio); return -ENODEV; } rc = gpio_direction_output(ctrl_pdata->bl_en_gpio,1); if (rc) { pr_err("set_direction for disp_en gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->bl_en_gpio); return -ENODEV; } pr_debug("%s: bl_gpio=%d\n", __func__, ctrl_pdata->bl_en_gpio); } #endif #ifdef CONFIG_HUAWEI_LCD /*get lcd negative voltage gpio110*/ ctrl_pdata->disp_en_gpio_vsn = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-enable-gpio-vsn", 0); //enable LCD_BIASDRV_EN2 if (!gpio_is_valid(ctrl_pdata->disp_en_gpio_vsn)) { pr_err("%s:%d, Disp_en gpio not specified\n", __func__, __LINE__); } else { rc = gpio_request(ctrl_pdata->disp_en_gpio_vsn, "disp_enable_vsn"); if (rc) { pr_err("request disp_en_gpio_vsn failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_en_gpio_vsn); return -ENODEV; } rc = gpio_tlmm_config(GPIO_CFG( ctrl_pdata->disp_en_gpio_vsn, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE); if (rc) { pr_err("%s: unable to config tlmm = %d\n", __func__, ctrl_pdata->disp_en_gpio_vsn); gpio_free(ctrl_pdata->disp_en_gpio_vsn); return -ENODEV; } rc = gpio_direction_output(ctrl_pdata->disp_en_gpio_vsn,1); if (rc) { pr_err("set_direction for disp_en gpio vsn failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_en_gpio_vsn); return -ENODEV; } pr_debug("%s: disp_gpio_vsn=%d\n", __func__, ctrl_pdata->disp_en_gpio_vsn); } #endif if (pinfo->type == MIPI_CMD_PANEL) { ctrl_pdata->disp_te_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-te-gpio", 0); if (!gpio_is_valid(ctrl_pdata->disp_te_gpio)) { pr_err("%s:%d, Disp_te gpio not specified\n", __func__, __LINE__); } } if (gpio_is_valid(ctrl_pdata->disp_te_gpio) && pinfo->type == MIPI_CMD_PANEL) { rc = gpio_request(ctrl_pdata->disp_te_gpio, "disp_te"); if (rc) { pr_err("request TE gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_te_gpio); return -ENODEV; } rc = gpio_tlmm_config(GPIO_CFG( ctrl_pdata->disp_te_gpio, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), GPIO_CFG_ENABLE); if (rc) { pr_err("%s: unable to config tlmm = %d\n", __func__, ctrl_pdata->disp_te_gpio); gpio_free(ctrl_pdata->disp_te_gpio); return -ENODEV; } rc = gpio_direction_input(ctrl_pdata->disp_te_gpio); if (rc) { pr_err("set_direction for disp_en gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_te_gpio); return -ENODEV; } pr_debug("%s: te_gpio=%d\n", __func__, ctrl_pdata->disp_te_gpio); } ctrl_pdata->rst_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-reset-gpio", 0); if (!gpio_is_valid(ctrl_pdata->rst_gpio)) { pr_err("%s:%d, reset gpio not specified\n", __func__, __LINE__); } else { rc = gpio_request(ctrl_pdata->rst_gpio, "disp_rst_n"); if (rc) { pr_err("request reset gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->rst_gpio); if (gpio_is_valid(ctrl_pdata->disp_en_gpio)) gpio_free(ctrl_pdata->disp_en_gpio); #ifdef CONFIG_HUAWEI_LCD if (gpio_is_valid(ctrl_pdata->bl_en_gpio)) gpio_free(ctrl_pdata->bl_en_gpio); if (gpio_is_valid(ctrl_pdata->disp_en_gpio_vsn)) gpio_free(ctrl_pdata->disp_en_gpio_vsn); #endif return -ENODEV; } } if (pinfo->mode_gpio_state != MODE_GPIO_NOT_VALID) { ctrl_pdata->mode_gpio = of_get_named_gpio( ctrl_pdev->dev.of_node, "qcom,platform-mode-gpio", 0); if (!gpio_is_valid(ctrl_pdata->mode_gpio)) { pr_info("%s:%d, mode gpio not specified\n", __func__, __LINE__); } else { rc = gpio_request(ctrl_pdata->mode_gpio, "panel_mode"); if (rc) { pr_err("request panel mode gpio failed,rc=%d\n", rc); gpio_free(ctrl_pdata->mode_gpio); if (gpio_is_valid(ctrl_pdata->disp_en_gpio)) gpio_free(ctrl_pdata->disp_en_gpio); if (gpio_is_valid(ctrl_pdata->rst_gpio)) gpio_free(ctrl_pdata->rst_gpio); if (gpio_is_valid(ctrl_pdata->disp_te_gpio)) gpio_free(ctrl_pdata->disp_te_gpio); return -ENODEV; } } } if (mdss_dsi_clk_init(ctrl_pdev, ctrl_pdata)) { pr_err("%s: unable to initialize Dsi ctrl clks\n", __func__); return -EPERM; } if (mdss_dsi_retrieve_ctrl_resources(ctrl_pdev, pinfo->pdest, ctrl_pdata)) { pr_err("%s: unable to get Dsi controller res\n", __func__); return -EPERM; } ctrl_pdata->panel_data.event_handler = mdss_dsi_event_handler; ctrl_pdata->check_status = mdss_dsi_bta_status_check; if (ctrl_pdata->bklt_ctrl == BL_PWM) mdss_dsi_panel_pwm_cfg(ctrl_pdata); mdss_dsi_ctrl_init(ctrl_pdata); /* * register in mdp driver */ ctrl_pdata->pclk_rate = mipi->dsi_pclk_rate; ctrl_pdata->byte_clk_rate = pinfo->clk_rate / 8; pr_debug("%s: pclk=%d, bclk=%d\n", __func__, ctrl_pdata->pclk_rate, ctrl_pdata->byte_clk_rate); ctrl_pdata->ctrl_state = CTRL_STATE_UNKNOWN; /* open cont_splash_enable in dtsi file */ if (pinfo->cont_splash_enabled) { pinfo->panel_power_on = 1; rc = mdss_dsi_panel_power_on(&(ctrl_pdata->panel_data), 1); if (rc) { pr_err("%s: Panel power on failed\n", __func__); return rc; } mdss_dsi_clk_ctrl(ctrl_pdata, 1); ctrl_pdata->ctrl_state |= (CTRL_STATE_PANEL_INIT | CTRL_STATE_MDP_ACTIVE); } else { pinfo->panel_power_on = 0; } rc = mdss_register_panel(ctrl_pdev, &(ctrl_pdata->panel_data)); if (rc) { pr_err("%s: unable to register MIPI DSI panel\n", __func__); if (ctrl_pdata->rst_gpio) gpio_free(ctrl_pdata->rst_gpio); if (gpio_is_valid(ctrl_pdata->disp_en_gpio)) gpio_free(ctrl_pdata->disp_en_gpio); #ifdef CONFIG_HUAWEI_LCD if (gpio_is_valid(ctrl_pdata->bl_en_gpio)) gpio_free(ctrl_pdata->bl_en_gpio); if (gpio_is_valid(ctrl_pdata->disp_en_gpio_vsn)) gpio_free(ctrl_pdata->disp_en_gpio_vsn); #endif return rc; } if (pinfo->pdest == DISPLAY_1) { mdss_debug_register_base("dsi0", ctrl_pdata->ctrl_base, ctrl_pdata->reg_size); ctrl_pdata->ndx = 0; } else { mdss_debug_register_base("dsi1", ctrl_pdata->ctrl_base, ctrl_pdata->reg_size); ctrl_pdata->ndx = 1; } pr_debug("%s: Panel data initialized\n", __func__); return 0; }
int dsi_panel_device_register(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; bool dynamic_fps; const char *data; 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_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); if ((!data) || (len != 2)) { pr_err("%s:%d, Unable to read Phy Strength ctrl settings", __func__, __LINE__); return -EINVAL; } pinfo->mipi.dsi_phy_db.strength[0] = data[0]; pinfo->mipi.dsi_phy_db.strength[1] = data[1]; pinfo->mipi.dsi_phy_db.reg_ldo_mode = of_property_read_bool( ctrl_pdev->dev.of_node, "qcom,regulator-ldo-mode"); data = of_get_property(ctrl_pdev->dev.of_node, "qcom,platform-regulator-settings", &len); if ((!data) || (len != 7)) { pr_err("%s:%d, Unable to read Phy regulator settings", __func__, __LINE__); return -EINVAL; } for (i = 0; i < len; i++) { pinfo->mipi.dsi_phy_db.regulator[i] = data[i]; } data = of_get_property(ctrl_pdev->dev.of_node, "qcom,platform-bist-ctrl", &len); if ((!data) || (len != 6)) { pr_err("%s:%d, Unable to read Phy Bist Ctrl settings", __func__, __LINE__); return -EINVAL; } for (i = 0; i < len; i++) { pinfo->mipi.dsi_phy_db.bistctrl[i] = data[i]; } data = of_get_property(ctrl_pdev->dev.of_node, "qcom,platform-lane-config", &len); if ((!data) || (len != 45)) { pr_err("%s:%d, Unable to read Phy lane configure settings", __func__, __LINE__); return -EINVAL; } for (i = 0; i < len; i++) { pinfo->mipi.dsi_phy_db.lanecfg[i] = data[i]; } ctrl_pdata->shared_pdata.broadcast_enable = of_property_read_bool( pan_node, "qcom,mdss-dsi-panel-broadcast-mode"); dynamic_fps = of_property_read_bool(pan_node, "qcom,mdss-dsi-pan-enable-dynamic-fps"); if (dynamic_fps) { pinfo->dynamic_fps = true; data = of_get_property(pan_node, "qcom,mdss-dsi-pan-fps-update", NULL); if (data) { if (!strcmp(data, "dfps_suspend_resume_mode")) { pinfo->dfps_update = DFPS_SUSPEND_RESUME_MODE; pr_debug("%s: dfps mode: suspend/resume\n", __func__); } else if (!strcmp(data, "dfps_immediate_clk_mode")) { pinfo->dfps_update = DFPS_IMMEDIATE_CLK_UPDATE_MODE; pr_debug("%s: dfps mode: Immediate clk\n", __func__); } else if (!strcmp(data, "dfps_immediate_porch_mode")) { pinfo->dfps_update = DFPS_IMMEDIATE_PORCH_UPDATE_MODE; pr_debug("%s: dfps mode: Immediate porch\n", __func__); } else { pr_debug("%s: dfps to default mode\n", __func__); pinfo->dfps_update = DFPS_SUSPEND_RESUME_MODE; pr_debug("%s: dfps mode: suspend/resume\n", __func__); } } else { pr_debug("%s: dfps update mode not configured\n", __func__); pinfo->dynamic_fps = false; pr_debug("%s: dynamic FPS disabled\n", __func__); } pinfo->new_fps = pinfo->mipi.frame_rate; } ctrl_pdata->disp_en_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-enable-gpio", 0); if (!gpio_is_valid(ctrl_pdata->disp_en_gpio)) pr_err("%s:%d, Disp_en gpio not specified\n", __func__, __LINE__); ctrl_pdata->bklt_en_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-bklight-en-gpio", 0); if (!gpio_is_valid(ctrl_pdata->bklt_en_gpio)) pr_info("%s: bklt_en gpio not specified\n", __func__); ctrl_pdata->rst_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-reset-gpio", 0); if (!gpio_is_valid(ctrl_pdata->rst_gpio)) pr_err("%s:%d, reset gpio not specified\n", __func__, __LINE__); ctrl_pdata->disp_te_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-te-gpio", 0); if (!gpio_is_valid(ctrl_pdata->disp_te_gpio)) pr_info("%s: disp_te_gpio not specified\n", __func__); if (pinfo->mode_gpio_state != MODE_GPIO_NOT_VALID) { ctrl_pdata->mode_gpio = of_get_named_gpio( ctrl_pdev->dev.of_node, "qcom,platform-mode-gpio", 0); if (!gpio_is_valid(ctrl_pdata->mode_gpio)) pr_info("%s:%d, mode gpio not specified\n", __func__, __LINE__); } else { ctrl_pdata->mode_gpio = -EINVAL; } if (mdss_dsi_clk_init(ctrl_pdev, ctrl_pdata)) { pr_err("%s: unable to initialize Dsi ctrl clks\n", __func__); return -EPERM; } if (mdss_dsi_retrieve_ctrl_resources(ctrl_pdev, pinfo->pdest, ctrl_pdata)) { pr_err("%s: unable to get Dsi controller res\n", __func__); return -EPERM; } ctrl_pdata->panel_data.event_handler = mdss_dsi_event_handler; if (ctrl_pdata->status_mode == ESD_REG) ctrl_pdata->check_status = mdss_dsi_reg_status_check; else if (ctrl_pdata->status_mode == ESD_BTA) ctrl_pdata->check_status = mdss_dsi_bta_status_check; else if (ctrl_pdata->status_mode == ESD_REG_ZTE) zte_lcd_check_status_init(ctrl_pdata); if (ctrl_pdata->status_mode == ESD_MAX) { pr_err("%s: Using default BTA for ESD check\n", __func__); ctrl_pdata->check_status = mdss_dsi_bta_status_check; } #ifdef CONFIG_ZTEMT_LCD_ESD_TE_CHECK if (ctrl_pdata->panel_name && (!strcmp(ctrl_pdata->panel_name, "cs nt35592 720p video mode dsi panel") || !strcmp(ctrl_pdata->panel_name, "lianchuang nt35592 720p video mode dsi panel"))) { ctrl_pdata->check_status = zte_check_status_by_te; printk("nt35592 check by te\n"); } else if (ctrl_pdata->panel_name && !strcmp(ctrl_pdata->panel_name, "success hx8392b 720p video mode dsi panel")) { ctrl_pdata->check_status = success_hx83920b_check_status; printk("hx83920b check faled always\n"); } #endif if (ctrl_pdata->bklt_ctrl == BL_PWM) mdss_dsi_panel_pwm_cfg(ctrl_pdata); mdss_dsi_ctrl_init(ctrl_pdata); /* * register in mdp driver */ ctrl_pdata->pclk_rate = mipi->dsi_pclk_rate; ctrl_pdata->byte_clk_rate = pinfo->clk_rate / 8; pr_debug("%s: pclk=%d, bclk=%d\n", __func__, ctrl_pdata->pclk_rate, ctrl_pdata->byte_clk_rate); ctrl_pdata->ctrl_state = CTRL_STATE_UNKNOWN; if (pinfo->cont_splash_enabled) { pinfo->panel_power_on = 1; rc = mdss_dsi_panel_power_on(&(ctrl_pdata->panel_data), 1); if (rc) { pr_err("%s: Panel power on failed\n", __func__); return rc; } if (pinfo->mipi.lp11_init) { if (mdss_dsi_pinctrl_set_state(ctrl_pdata, true)) pr_debug("reset enable: pinctrl not enabled\n"); rc = mdss_dsi_panel_reset(&(ctrl_pdata->panel_data), 1); if (rc) { pr_err("%s: Panel reset failed. rc=%d\n", __func__, rc); return rc; } } mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1); ctrl_pdata->ctrl_state |= (CTRL_STATE_PANEL_INIT | CTRL_STATE_MDP_ACTIVE); } else { pinfo->panel_power_on = 0; } rc = mdss_register_panel(ctrl_pdev, &(ctrl_pdata->panel_data)); if (rc) { pr_err("%s: unable to register MIPI DSI panel\n", __func__); return rc; } if (pinfo->pdest == DISPLAY_1) { mdss_debug_register_base("dsi0", ctrl_pdata->ctrl_base, ctrl_pdata->reg_size); ctrl_pdata->ndx = 0; } else { mdss_debug_register_base("dsi1", ctrl_pdata->ctrl_base, ctrl_pdata->reg_size); ctrl_pdata->ndx = 1; } pr_debug("%s: Panel data initialized\n", __func__); return 0; }
int dsi_panel_device_register(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; bool dynamic_fps; const char *data; pr_info("%s : ++ \n",__func__); 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_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); if ((!data) || (len != 2)) { pr_err("%s:%d, Unable to read Phy Strength ctrl settings\n", __func__, __LINE__); return -EINVAL; } pinfo->mipi.dsi_phy_db.strength[0] = data[0]; pinfo->mipi.dsi_phy_db.strength[1] = data[1]; data = of_get_property(ctrl_pdev->dev.of_node, "qcom,platform-regulator-settings", &len); if ((!data) || (len != 7)) { pr_err("%s:%d, Unable to read Phy regulator settings\n", __func__, __LINE__); return -EINVAL; } for (i = 0; i < len; i++) { pinfo->mipi.dsi_phy_db.regulator[i] = data[i]; } data = of_get_property(ctrl_pdev->dev.of_node, "qcom,platform-bist-ctrl", &len); if ((!data) || (len != 6)) { pr_err("%s:%d, Unable to read Phy Bist Ctrl settings\n", __func__, __LINE__); return -EINVAL; } for (i = 0; i < len; i++) { pinfo->mipi.dsi_phy_db.bistctrl[i] = data[i]; } data = of_get_property(ctrl_pdev->dev.of_node, "qcom,platform-lane-config", &len); if ((!data) || (len != 45)) { pr_err("%s:%d, Unable to read Phy lane configure settings\n", __func__, __LINE__); return -EINVAL; } for (i = 0; i < len; i++) { pinfo->mipi.dsi_phy_db.lanecfg[i] = data[i]; } 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"); pr_debug("%s: cmd_sync_wait_enable=%d trigger=%d\n", __func__, ctrl_pdata->cmd_sync_wait_broadcast, ctrl_pdata->cmd_sync_wait_trigger); dynamic_fps = of_property_read_bool(pan_node, "qcom,mdss-dsi-pan-enable-dynamic-fps"); if (dynamic_fps) { pinfo->dynamic_fps = true; data = of_get_property(pan_node, "qcom,mdss-dsi-pan-fps-update", NULL); if (data) { if (!strcmp(data, "dfps_suspend_resume_mode")) { pinfo->dfps_update = DFPS_SUSPEND_RESUME_MODE; pr_debug("%s: dfps mode: suspend/resume\n", __func__); } else if (!strcmp(data, "dfps_immediate_clk_mode")) { pinfo->dfps_update = DFPS_IMMEDIATE_CLK_UPDATE_MODE; pr_debug("%s: dfps mode: Immediate clk\n", __func__); } else if (!strcmp(data, "dfps_immediate_porch_mode")) { pinfo->dfps_update = DFPS_IMMEDIATE_PORCH_UPDATE_MODE; pr_debug("%s: dfps mode: Immediate porch\n", __func__); } else { pr_debug("%s: dfps to default mode\n", __func__); pinfo->dfps_update = DFPS_SUSPEND_RESUME_MODE; pr_debug("%s: dfps mode: suspend/resume\n", __func__); } } else { pr_debug("%s: dfps update mode not configured\n", __func__); pinfo->dynamic_fps = false; pr_debug("%s: dynamic FPS disabled\n", __func__); } pinfo->new_fps = pinfo->mipi.frame_rate; } ctrl_pdata->disp_en_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-enable-gpio", 0); if (!gpio_is_valid(ctrl_pdata->disp_en_gpio)) pr_err("%s:%d, Disp_en gpio not specified\n", __func__, __LINE__); else pr_err("%s:%d, Disp_en gpio (%d)",__func__, __LINE__,ctrl_pdata->disp_en_gpio ); if (ctrl_pdata->panel_data.panel_info.mipi.mode == DSI_CMD_MODE) { ctrl_pdata->disp_te_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-te-gpio", 0); if (!gpio_is_valid(ctrl_pdata->disp_te_gpio)) pr_err("%s:%d, Disp_te gpio not specified\n", __func__, __LINE__); else pr_err("%s:%d, Disp_te gpio (%d)",__func__, __LINE__,ctrl_pdata->disp_en_gpio ); } ctrl_pdata->bklt_en_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-bklight-en-gpio", 0); if (!gpio_is_valid(ctrl_pdata->bklt_en_gpio)) pr_info("%s: bklt_en gpio not specified\n", __func__); else pr_info("%s bklt_en_gpio gpio : %d", __func__, ctrl_pdata->bklt_en_gpio); ctrl_pdata->rst_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-reset-gpio", 0); if (!gpio_is_valid(ctrl_pdata->rst_gpio)) pr_err("%s:%d, reset gpio not specified\n", __func__, __LINE__); else pr_info("%s reset gpio : %d", __func__, ctrl_pdata->rst_gpio); if (pinfo->mode_gpio_state != MODE_GPIO_NOT_VALID) { ctrl_pdata->mode_gpio = of_get_named_gpio( ctrl_pdev->dev.of_node, "qcom,platform-mode-gpio", 0); if (!gpio_is_valid(ctrl_pdata->mode_gpio)) pr_info("%s:%d, mode gpio not specified\n", __func__, __LINE__); } else { ctrl_pdata->mode_gpio = -EINVAL; } if (mdss_dsi_clk_init(ctrl_pdev, ctrl_pdata)) { pr_err("%s: unable to initialize Dsi ctrl clks\n", __func__); return -EPERM; } if (mdss_dsi_retrieve_ctrl_resources(ctrl_pdev, pinfo->pdest, ctrl_pdata)) { pr_err("%s: unable to get Dsi controller res\n", __func__); return -EPERM; } ctrl_pdata->panel_data.event_handler = mdss_dsi_event_handler; ctrl_pdata->check_status = mdss_dsi_bta_status_check; if (ctrl_pdata->bklt_ctrl == BL_PWM) mdss_dsi_panel_pwm_cfg(ctrl_pdata); mdss_dsi_ctrl_init(ctrl_pdata); /* * register in mdp driver */ ctrl_pdata->pclk_rate = mipi->dsi_pclk_rate; ctrl_pdata->byte_clk_rate = pinfo->clk_rate / 8; pr_debug("%s: pclk=%d, bclk=%d\n", __func__, ctrl_pdata->pclk_rate, ctrl_pdata->byte_clk_rate); ctrl_pdata->ctrl_state = CTRL_STATE_UNKNOWN; pr_info("%s : pinfo->cont_splash_enabled(%d)\n", __func__, pinfo->cont_splash_enabled); if (pinfo->cont_splash_enabled) { rc = mdss_dsi_panel_power_ctrl(&(ctrl_pdata->panel_data), MDSS_PANEL_POWER_ON); if (rc) { pr_err("%s: Panel power on failed\n", __func__); return rc; } pinfo->blank_state = MDSS_PANEL_BLANK_UNBLANK; mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1); ctrl_pdata->ctrl_state |= (CTRL_STATE_PANEL_INIT | CTRL_STATE_MDP_ACTIVE); } else { pinfo->panel_power_state = MDSS_PANEL_POWER_OFF; } pinfo->is_prim_panel = true; #if defined(CONFIG_FB_MSM_MDSS_SAMSUNG) rc = mdss_dsi_request_gpios(ctrl_pdata); if (rc) { pr_err("gpio request failed\n"); } #endif rc = mdss_register_panel(ctrl_pdev, &(ctrl_pdata->panel_data)); if (rc) { pr_err("%s: unable to register MIPI DSI panel\n", __func__); return rc; } if (pinfo->pdest == DISPLAY_1) { mdss_debug_register_base("dsi0", ctrl_pdata->ctrl_base, ctrl_pdata->reg_size); ctrl_pdata->ndx = 0; } else { mdss_debug_register_base("dsi1", ctrl_pdata->ctrl_base, ctrl_pdata->reg_size); ctrl_pdata->ndx = 1; } pr_debug("%s: Panel data initialized\n", __func__); return 0; }
int dsi_panel_device_register(struct device_node *pan_node, struct mdss_dsi_ctrl_pdata *ctrl_pdata) { struct mipi_panel_info *mipi; int rc, i, len; struct device_node *dsi_ctrl_np = NULL; struct platform_device *ctrl_pdev = NULL; bool dynamic_fps; const char *data; struct mdss_panel_info *pinfo = &(ctrl_pdata->panel_data.panel_info); 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_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); if ((!data) || (len != 2)) { pr_err("%s:%d, Unable to read Phy Strength ctrl settings", __func__, __LINE__); return -EINVAL; } pinfo->mipi.dsi_phy_db.strength[0] = data[0]; pinfo->mipi.dsi_phy_db.strength[1] = data[1]; data = of_get_property(ctrl_pdev->dev.of_node, "qcom,platform-regulator-settings", &len); if ((!data) || (len != 7)) { pr_err("%s:%d, Unable to read Phy regulator settings", __func__, __LINE__); return -EINVAL; } for (i = 0; i < len; i++) { pinfo->mipi.dsi_phy_db.regulator[i] = data[i]; } data = of_get_property(ctrl_pdev->dev.of_node, "qcom,platform-bist-ctrl", &len); if ((!data) || (len != 6)) { pr_err("%s:%d, Unable to read Phy Bist Ctrl settings", __func__, __LINE__); return -EINVAL; } for (i = 0; i < len; i++) { pinfo->mipi.dsi_phy_db.bistctrl[i] = data[i]; } data = of_get_property(ctrl_pdev->dev.of_node, "qcom,platform-lane-config", &len); if ((!data) || (len != 45)) { pr_err("%s:%d, Unable to read Phy lane configure settings", __func__, __LINE__); return -EINVAL; } for (i = 0; i < len; i++) { pinfo->mipi.dsi_phy_db.lanecfg[i] = data[i]; } ctrl_pdata->shared_pdata.broadcast_enable = of_property_read_bool( pan_node, "qcom,mdss-dsi-panel-broadcast-mode"); dynamic_fps = of_property_read_bool(pan_node, "qcom,mdss-dsi-pan-enable-dynamic-fps"); if (dynamic_fps) { pinfo->dynamic_fps = true; data = of_get_property(pan_node, "qcom,mdss-dsi-pan-fps-update", NULL); if (data) { if (!strcmp(data, "dfps_suspend_resume_mode")) { pinfo->dfps_update = DFPS_SUSPEND_RESUME_MODE; pr_debug("%s: dfps mode: suspend/resume\n", __func__); } else if (!strcmp(data, "dfps_immediate_clk_mode")) { pinfo->dfps_update = DFPS_IMMEDIATE_CLK_UPDATE_MODE; pr_debug("%s: dfps mode: Immediate clk\n", __func__); } else if (!strcmp(data, "dfps_immediate_porch_mode")) { pinfo->dfps_update = DFPS_IMMEDIATE_PORCH_UPDATE_MODE; pr_debug("%s: dfps mode: Immediate porch\n", __func__); } else { pr_debug("%s: dfps to default mode\n", __func__); pinfo->dfps_update = DFPS_SUSPEND_RESUME_MODE; pr_debug("%s: dfps mode: suspend/resume\n", __func__); } } else { pr_debug("%s: dfps update mode not configured\n", __func__); pinfo->dynamic_fps = false; pr_debug("%s: dynamic FPS disabled\n", __func__); } pinfo->new_fps = pinfo->mipi.frame_rate; } pinfo->panel_max_fps = mdss_panel_get_framerate(pinfo); pinfo->panel_max_vtotal = mdss_panel_get_vtotal(pinfo); ctrl_pdata->disp_en_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-enable-gpio", 0); if (!gpio_is_valid(ctrl_pdata->disp_en_gpio)) { pr_err("%s:%d, Disp_en gpio not specified\n", __func__, __LINE__); } else { rc = gpio_request(ctrl_pdata->disp_en_gpio, "disp_enable"); if (rc) { pr_err("request reset gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_en_gpio); return -ENODEV; } rc = gpio_direction_output(ctrl_pdata->disp_en_gpio, 1); if (rc) { pr_err("set_direction for disp_en gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_en_gpio); return -ENODEV; } } ctrl_pdata->rst_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-reset-gpio", 0); printk("***************** ctrl_pdata->rst_gpio = %d *****************\n", ctrl_pdata->rst_gpio); if (!gpio_is_valid(ctrl_pdata->rst_gpio)) { pr_err("%s:%d, reset gpio not specified\n", __func__, __LINE__); } else { rc = gpio_request(ctrl_pdata->rst_gpio, "disp_rst_n"); if (rc) { pr_err("request reset gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->rst_gpio); if (gpio_is_valid(ctrl_pdata->disp_en_gpio)) gpio_free(ctrl_pdata->disp_en_gpio); return -ENODEV; } } ctrl_pdata->disp_vsn_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-vsn-gpio", 0); if (!gpio_is_valid(ctrl_pdata->disp_vsn_gpio)) { pr_err("%s:%d, vsn gpio not specified\n", __func__, __LINE__); } else { rc = gpio_request(ctrl_pdata->disp_vsn_gpio, "disp_vsn"); if (rc) { pr_err("request vsn gpio failed, rc=%d\n", rc); return -ENODEV; } } ctrl_pdata->disp_vsp_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-vsp-gpio", 0); if (!gpio_is_valid(ctrl_pdata->disp_vsp_gpio)) { pr_err("%s:%d, vsp gpio not specified\n", __func__, __LINE__); } else { rc = gpio_request(ctrl_pdata->disp_vsp_gpio, "disp_vsp"); if (rc) { pr_err("request vsp gpio failed, rc=%d\n", rc); return -ENODEV; } } ctrl_pdata->bl_outdoor_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-outdoor-gpio", 0); #if 1 if (!gpio_is_valid(ctrl_pdata->bl_outdoor_gpio)) { pr_err("%s:%d, bl_outdoor_gpio gpio not specified\n", __func__, __LINE__); } else { rc = gpio_request(ctrl_pdata->bl_outdoor_gpio, "bl_outdoor"); if (rc) { pr_err("request bl outdoor gpio failed, rc=%d\n", rc); return -ENODEV; } } #endif #ifdef ESD_FOR_LCD ctrl_pdata->disp_te_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-te-gpio", 0); if (!gpio_is_valid(ctrl_pdata->disp_te_gpio)) { pr_err("%s:%d, Disp_te gpio not specified\n", __func__, __LINE__); } if (gpio_is_valid(ctrl_pdata->disp_te_gpio)) { rc = gpio_request(ctrl_pdata->disp_te_gpio, "disp_te"); if (rc) { pr_err("request TE gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_te_gpio); return -ENODEV; } INIT_DELAYED_WORK(&lcd_te_work, lcd_te_abnormal_handle); init_timer(&te_timer); te_timer.function = te_timer_handle; ctrl_pdata->te_irq = gpio_to_irq(ctrl_pdata->disp_te_gpio); rc = request_irq(ctrl_pdata->te_irq, lcd_te_irq_handle, IRQF_TRIGGER_RISING, "LCD_TE", ctrl_pdata); if (rc) { printk(KERN_ERR "lcd te request irq(%d) failure, rc = %d\n", ctrl_pdata->te_irq, rc); return -1; } te_running = 0; disable_irq(ctrl_pdata->te_irq); printk("************************** te irq %d requested *******************************\n", ctrl_pdata->te_irq); pr_debug("%s: te_gpio=%d\n", __func__, ctrl_pdata->disp_te_gpio); } #endif pr_info("[DIS] DISPLAY_GPIO[ te: %d en: %d rst: %d vsp: %d vsn: %d bl_outdoor: %d]", ctrl_pdata->disp_te_gpio ,ctrl_pdata->disp_en_gpio, ctrl_pdata->rst_gpio, ctrl_pdata->disp_vsp_gpio, ctrl_pdata->disp_vsn_gpio, ctrl_pdata->bl_outdoor_gpio); if (pinfo->mode_gpio_state != MODE_GPIO_NOT_VALID) { ctrl_pdata->mode_gpio = of_get_named_gpio( ctrl_pdev->dev.of_node, "qcom,platform-mode-gpio", 0); if (!gpio_is_valid(ctrl_pdata->mode_gpio)) pr_info("%s:%d, mode gpio not specified\n", __func__, __LINE__); } else { ctrl_pdata->mode_gpio = -EINVAL; } if (mdss_dsi_clk_init(ctrl_pdev, ctrl_pdata)) { pr_err("%s: unable to initialize Dsi ctrl clks\n", __func__); return -EPERM; } if (mdss_dsi_retrieve_ctrl_resources(ctrl_pdev, pinfo->pdest, ctrl_pdata)) { pr_err("%s: unable to get Dsi controller res\n", __func__); return -EPERM; } ctrl_pdata->panel_data.event_handler = mdss_dsi_event_handler; if (ctrl_pdata->status_mode == ESD_REG) ctrl_pdata->check_status = mdss_dsi_reg_status_check; else if (ctrl_pdata->status_mode == ESD_BTA) ctrl_pdata->check_status = mdss_dsi_bta_status_check; if (ctrl_pdata->status_mode == ESD_MAX) { pr_err("%s: Using default BTA for ESD check\n", __func__); ctrl_pdata->check_status = mdss_dsi_bta_status_check; } if (ctrl_pdata->bklt_ctrl == BL_PWM) mdss_dsi_panel_pwm_cfg(ctrl_pdata); mdss_dsi_ctrl_init(ctrl_pdata); /* * register in mdp driver */ ctrl_pdata->pclk_rate = mipi->dsi_pclk_rate; ctrl_pdata->byte_clk_rate = pinfo->clk_rate / 8; pr_debug("%s: pclk=%d, bclk=%d\n", __func__, ctrl_pdata->pclk_rate, ctrl_pdata->byte_clk_rate); ctrl_pdata->ctrl_state = CTRL_STATE_UNKNOWN; if (pinfo->cont_splash_enabled) { pinfo->panel_power_on = 1; rc = mdss_dsi_panel_power_on(&(ctrl_pdata->panel_data), 1); if (rc) { pr_err("%s: Panel power on failed\n", __func__); return rc; } mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1); ctrl_pdata->ctrl_state |= (CTRL_STATE_PANEL_INIT | CTRL_STATE_MDP_ACTIVE); } else { pinfo->panel_power_on = 0; } rc = mdss_register_panel(ctrl_pdev, &(ctrl_pdata->panel_data)); if (rc) { pr_err("%s: unable to register MIPI DSI panel\n", __func__); return rc; } if (pinfo->pdest == DISPLAY_1) { mdss_debug_register_base("dsi0", ctrl_pdata->ctrl_base, ctrl_pdata->reg_size); ctrl_pdata->ndx = 0; } else { mdss_debug_register_base("dsi1", ctrl_pdata->ctrl_base, ctrl_pdata->reg_size); ctrl_pdata->ndx = 1; } pr_debug("%s: Panel data initialized\n", __func__); return 0; }
int dsi_panel_device_register(struct platform_device *pdev, struct mdss_panel_common_pdata *panel_data) { struct mipi_panel_info *mipi; int rc; u8 lanes = 0, bpp; u32 h_period, v_period, dsi_pclk_rate; struct mdss_dsi_ctrl_pdata *ctrl_pdata; struct device_node *dsi_ctrl_np = NULL; struct platform_device *ctrl_pdev = NULL; bool broadcast; bool cont_splash_enabled = false; h_period = ((panel_data->panel_info.lcdc.h_pulse_width) + (panel_data->panel_info.lcdc.h_back_porch) + (panel_data->panel_info.xres) + (panel_data->panel_info.lcdc.h_front_porch)); v_period = ((panel_data->panel_info.lcdc.v_pulse_width) + (panel_data->panel_info.lcdc.v_back_porch) + (panel_data->panel_info.yres) + (panel_data->panel_info.lcdc.v_front_porch)); mipi = &panel_data->panel_info.mipi; panel_data->panel_info.type = ((mipi->mode == DSI_VIDEO_MODE) ? MIPI_VIDEO_PANEL : MIPI_CMD_PANEL); if (mipi->data_lane3) lanes += 1; if (mipi->data_lane2) lanes += 1; if (mipi->data_lane1) lanes += 1; if (mipi->data_lane0) lanes += 1; if ((mipi->dst_format == DSI_CMD_DST_FORMAT_RGB888) || (mipi->dst_format == DSI_VIDEO_DST_FORMAT_RGB888) || (mipi->dst_format == DSI_VIDEO_DST_FORMAT_RGB666_LOOSE)) bpp = 3; else if ((mipi->dst_format == DSI_CMD_DST_FORMAT_RGB565) || (mipi->dst_format == DSI_VIDEO_DST_FORMAT_RGB565)) bpp = 2; else bpp = 3; /* Default format set to RGB888 */ if (!panel_data->panel_info.clk_rate) { h_period += panel_data->panel_info.lcdc.xres_pad; v_period += panel_data->panel_info.lcdc.yres_pad; if (lanes > 0) { panel_data->panel_info.clk_rate = ((h_period * v_period * (mipi->frame_rate) * bpp * 8) / lanes); } else { pr_err("%s: forcing mdss_dsi lanes to 1\n", __func__); panel_data->panel_info.clk_rate = (h_period * v_period * (mipi->frame_rate) * bpp * 8); } } pll_divider_config.clk_rate = panel_data->panel_info.clk_rate; rc = mdss_dsi_clk_div_config(bpp, lanes, &dsi_pclk_rate); if (rc) { pr_err("%s: unable to initialize the clk dividers\n", __func__); return rc; } if ((dsi_pclk_rate < 3300000) || (dsi_pclk_rate > 250000000)) dsi_pclk_rate = 35000000; mipi->dsi_pclk_rate = dsi_pclk_rate; dsi_ctrl_np = of_parse_phandle(pdev->dev.of_node, "qcom,dsi-ctrl-phandle", 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); ctrl_pdata = platform_get_drvdata(ctrl_pdev); if (!ctrl_pdata) { pr_err("%s: no dsi ctrl driver data\n", __func__); return -EINVAL; } rc = mdss_dsi_regulator_init(ctrl_pdev); if (rc) { dev_err(&pdev->dev, "%s: failed to init regulator, rc=%d\n", __func__, rc); return rc; } broadcast = of_property_read_bool(pdev->dev.of_node, "qcom,mdss-pan-broadcast-mode"); if (broadcast) ctrl_pdata->shared_pdata.broadcast_enable = 1; ctrl_pdata->disp_en_gpio = of_get_named_gpio(pdev->dev.of_node, "qcom,enable-gpio", 0); if (!gpio_is_valid(ctrl_pdata->disp_en_gpio)) { pr_err("%s:%d, Disp_en gpio not specified\n", __func__, __LINE__); } else { rc = gpio_request(ctrl_pdata->disp_en_gpio, "disp_enable"); if (rc) { pr_err("request reset gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_en_gpio); return -ENODEV; } } ctrl_pdata->disp_te_gpio = of_get_named_gpio(pdev->dev.of_node, "qcom,te-gpio", 0); if (!gpio_is_valid(ctrl_pdata->disp_te_gpio)) { pr_err("%s:%d, Disp_te gpio not specified\n", __func__, __LINE__); } else { rc = gpio_request(ctrl_pdata->disp_te_gpio, "disp_te"); if (rc) { pr_err("request TE gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_te_gpio); return -ENODEV; } rc = gpio_tlmm_config(GPIO_CFG( ctrl_pdata->disp_te_gpio, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), GPIO_CFG_ENABLE); if (rc) { pr_err("%s: unable to config tlmm = %d\n", __func__, ctrl_pdata->disp_te_gpio); gpio_free(ctrl_pdata->disp_te_gpio); return -ENODEV; } rc = gpio_direction_input(ctrl_pdata->disp_te_gpio); if (rc) { pr_err("set_direction for disp_en gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_te_gpio); return -ENODEV; } pr_debug("%s: te_gpio=%d\n", __func__, ctrl_pdata->disp_te_gpio); } ctrl_pdata->rst_gpio = of_get_named_gpio(pdev->dev.of_node, "qcom,rst-gpio", 0); if (!gpio_is_valid(ctrl_pdata->rst_gpio)) { pr_err("%s:%d, reset gpio not specified\n", __func__, __LINE__); } else { rc = gpio_request(ctrl_pdata->rst_gpio, "disp_rst_n"); if (rc) { pr_err("request reset gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->rst_gpio); if (gpio_is_valid(ctrl_pdata->disp_en_gpio)) gpio_free(ctrl_pdata->disp_en_gpio); return -ENODEV; } } if (mdss_dsi_clk_init(ctrl_pdev, ctrl_pdata)) { pr_err("%s: unable to initialize Dsi ctrl clks\n", __func__); return -EPERM; } if (mdss_dsi_retrieve_ctrl_resources(ctrl_pdev, panel_data->panel_info.pdest, ctrl_pdata)) { pr_err("%s: unable to get Dsi controller res\n", __func__); return -EPERM; } ctrl_pdata->panel_data.event_handler = mdss_dsi_event_handler; ctrl_pdata->on_cmds = panel_data->on_cmds; ctrl_pdata->off_cmds = panel_data->off_cmds; memcpy(&((ctrl_pdata->panel_data).panel_info), &(panel_data->panel_info), sizeof(struct mdss_panel_info)); ctrl_pdata->panel_data.set_backlight = panel_data->bl_fnc; ctrl_pdata->bklt_ctrl = panel_data->panel_info.bklt_ctrl; ctrl_pdata->pwm_pmic_gpio = panel_data->panel_info.pwm_pmic_gpio; ctrl_pdata->pwm_period = panel_data->panel_info.pwm_period; ctrl_pdata->pwm_lpg_chan = panel_data->panel_info.pwm_lpg_chan; ctrl_pdata->bklt_max = panel_data->panel_info.bl_max; if (ctrl_pdata->bklt_ctrl == BL_PWM) mdss_dsi_panel_pwm_cfg(ctrl_pdata); mdss_dsi_ctrl_init(ctrl_pdata); /* * register in mdp driver */ ctrl_pdata->pclk_rate = dsi_pclk_rate; ctrl_pdata->byte_clk_rate = panel_data->panel_info.clk_rate / 8; pr_debug("%s: pclk=%d, bclk=%d\n", __func__, ctrl_pdata->pclk_rate, ctrl_pdata->byte_clk_rate); ctrl_pdata->ctrl_state = CTRL_STATE_UNKNOWN; cont_splash_enabled = of_property_read_bool(pdev->dev.of_node, "qcom,cont-splash-enabled"); if (!cont_splash_enabled) { pr_info("%s:%d Continuous splash flag not found.\n", __func__, __LINE__); ctrl_pdata->panel_data.panel_info.cont_splash_enabled = 0; ctrl_pdata->panel_data.panel_info.panel_power_on = 0; } else { pr_info("%s:%d Continuous splash flag enabled.\n", __func__, __LINE__); ctrl_pdata->panel_data.panel_info.cont_splash_enabled = 1; ctrl_pdata->panel_data.panel_info.panel_power_on = 1; rc = mdss_dsi_panel_power_on(&(ctrl_pdata->panel_data), 1); if (rc) { pr_err("%s: Panel power on failed\n", __func__); return rc; } mdss_dsi_clk_ctrl(ctrl_pdata, 1); ctrl_pdata->ctrl_state |= (CTRL_STATE_PANEL_INIT | CTRL_STATE_MDP_ACTIVE); } rc = mdss_register_panel(ctrl_pdev, &(ctrl_pdata->panel_data)); if (rc) { dev_err(&pdev->dev, "unable to register MIPI DSI panel\n"); if (ctrl_pdata->rst_gpio) gpio_free(ctrl_pdata->rst_gpio); if (gpio_is_valid(ctrl_pdata->disp_en_gpio)) gpio_free(ctrl_pdata->disp_en_gpio); return rc; } ctrl_pdata->on = panel_data->on; ctrl_pdata->off = panel_data->off; if (panel_data->panel_info.pdest == DISPLAY_1) { mdss_debug_register_base("dsi0", ctrl_pdata->ctrl_base, ctrl_pdata->reg_size); ctrl_pdata->ndx = 0; } else { mdss_debug_register_base("dsi1", ctrl_pdata->ctrl_base, ctrl_pdata->reg_size); ctrl_pdata->ndx = 1; } pr_debug("%s: Panal data initialized\n", __func__); return 0; }
int dsi_panel_device_register(struct platform_device *pdev, struct mdss_panel_common_pdata *panel_data) { struct mipi_panel_info *mipi; int rc; struct mdss_dsi_ctrl_pdata *ctrl_pdata; struct device_node *dsi_ctrl_np = NULL; struct platform_device *ctrl_pdev = NULL; bool broadcast; bool dynamic_fps; bool cont_splash_enabled = false; const char *data; mipi = &panel_data->panel_info.mipi; panel_data->panel_info.type = ((mipi->mode == DSI_VIDEO_MODE) ? MIPI_VIDEO_PANEL : MIPI_CMD_PANEL); rc = mdss_dsi_clk_div_config(&panel_data->panel_info, mipi->frame_rate); if (rc) { pr_err("%s: unable to initialize the clk dividers\n", __func__); return rc; } dsi_ctrl_np = of_parse_phandle(pdev->dev.of_node, "qcom,dsi-ctrl-phandle", 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); ctrl_pdata = platform_get_drvdata(ctrl_pdev); if (!ctrl_pdata) { pr_err("%s: no dsi ctrl driver data\n", __func__); return -EINVAL; } rc = mdss_dsi_regulator_init(ctrl_pdev); if (rc) { dev_err(&pdev->dev, "%s: failed to init regulator, rc=%d\n", __func__, rc); return rc; } broadcast = of_property_read_bool(pdev->dev.of_node, "qcom,mdss-pan-broadcast-mode"); if (broadcast) ctrl_pdata->shared_pdata.broadcast_enable = 1; dynamic_fps = of_property_read_bool(pdev->dev.of_node, "qcom,mdss-dsi-pan-enable-dynamic-fps"); if (dynamic_fps) { panel_data->panel_info.dynamic_fps = true; data = of_get_property(pdev->dev.of_node, "qcom,mdss-dsi-pan-fps-update", NULL); if (data) { if (!strcmp(data, "dfps_suspend_resume_mode")) { panel_data->panel_info.dfps_update = DFPS_SUSPEND_RESUME_MODE; pr_debug("%s: dfps mode: suspend/resume\n", __func__); } else if (!strcmp(data, "dfps_immediate_clk_mode")) { panel_data->panel_info.dfps_update = DFPS_IMMEDIATE_CLK_UPDATE_MODE; pr_debug("%s: dfps mode: Immediate clk\n", __func__); } else { pr_debug("%s: dfps to default mode\n", __func__); panel_data->panel_info.dfps_update = DFPS_SUSPEND_RESUME_MODE; pr_debug("%s: dfps mode: suspend/resume\n", __func__); } } else { pr_debug("%s: dfps update mode not configured\n", __func__); panel_data->panel_info.dynamic_fps = false; pr_debug("%s: dynamic FPS disabled\n", __func__); } panel_data->panel_info.new_fps = panel_data->panel_info.mipi.frame_rate; } ctrl_pdata->disp_en_gpio = of_get_named_gpio(pdev->dev.of_node, "qcom,enable-gpio", 0); if (!gpio_is_valid(ctrl_pdata->disp_en_gpio)) { pr_err("%s:%d, Disp_en gpio not specified\n", __func__, __LINE__); } else { rc = gpio_request(ctrl_pdata->disp_en_gpio, "disp_enable"); if (rc) { pr_err("request reset gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_en_gpio); return -ENODEV; } } ctrl_pdata->disp_te_gpio = of_get_named_gpio(pdev->dev.of_node, "qcom,te-gpio", 0); if (!gpio_is_valid(ctrl_pdata->disp_te_gpio)) { pr_err("%s:%d, Disp_te gpio not specified\n", __func__, __LINE__); } else { rc = gpio_request(ctrl_pdata->disp_te_gpio, "disp_te"); if (rc) { pr_err("request TE gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_te_gpio); return -ENODEV; } rc = gpio_tlmm_config(GPIO_CFG( ctrl_pdata->disp_te_gpio, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), GPIO_CFG_ENABLE); if (rc) { pr_err("%s: unable to config tlmm = %d\n", __func__, ctrl_pdata->disp_te_gpio); gpio_free(ctrl_pdata->disp_te_gpio); return -ENODEV; } rc = gpio_direction_input(ctrl_pdata->disp_te_gpio); if (rc) { pr_err("set_direction for disp_en gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_te_gpio); return -ENODEV; } pr_debug("%s: te_gpio=%d\n", __func__, ctrl_pdata->disp_te_gpio); } ctrl_pdata->rst_gpio = of_get_named_gpio(pdev->dev.of_node, "qcom,rst-gpio", 0); if (!gpio_is_valid(ctrl_pdata->rst_gpio)) { pr_err("%s:%d, reset gpio not specified\n", __func__, __LINE__); } else { rc = gpio_request(ctrl_pdata->rst_gpio, "disp_rst_n"); if (rc) { pr_err("request reset gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->rst_gpio); if (gpio_is_valid(ctrl_pdata->disp_en_gpio)) gpio_free(ctrl_pdata->disp_en_gpio); return -ENODEV; } } if (mdss_dsi_clk_init(ctrl_pdev, ctrl_pdata)) { pr_err("%s: unable to initialize Dsi ctrl clks\n", __func__); return -EPERM; } if (mdss_dsi_retrieve_ctrl_resources(ctrl_pdev, panel_data->panel_info.pdest, ctrl_pdata)) { pr_err("%s: unable to get Dsi controller res\n", __func__); return -EPERM; } ctrl_pdata->panel_data.event_handler = mdss_dsi_event_handler; ctrl_pdata->on_cmds = panel_data->on_cmds; ctrl_pdata->off_cmds = panel_data->off_cmds; memcpy(&((ctrl_pdata->panel_data).panel_info), &(panel_data->panel_info), sizeof(struct mdss_panel_info)); ctrl_pdata->panel_data.set_backlight = panel_data->bl_fnc; ctrl_pdata->bklt_ctrl = panel_data->panel_info.bklt_ctrl; ctrl_pdata->pwm_pmic_gpio = panel_data->panel_info.pwm_pmic_gpio; ctrl_pdata->pwm_period = panel_data->panel_info.pwm_period; ctrl_pdata->pwm_lpg_chan = panel_data->panel_info.pwm_lpg_chan; ctrl_pdata->bklt_max = panel_data->panel_info.bl_max; if (ctrl_pdata->bklt_ctrl == BL_PWM) mdss_dsi_panel_pwm_cfg(ctrl_pdata); mdss_dsi_ctrl_init(ctrl_pdata); /* * register in mdp driver */ ctrl_pdata->pclk_rate = mipi->dsi_pclk_rate; ctrl_pdata->byte_clk_rate = panel_data->panel_info.clk_rate / 8; pr_debug("%s: pclk=%d, bclk=%d\n", __func__, ctrl_pdata->pclk_rate, ctrl_pdata->byte_clk_rate); ctrl_pdata->ctrl_state = CTRL_STATE_UNKNOWN; cont_splash_enabled = of_property_read_bool(pdev->dev.of_node, "qcom,cont-splash-enabled"); if (!cont_splash_enabled) { pr_info("%s:%d Continuous splash flag not found.\n", __func__, __LINE__); ctrl_pdata->panel_data.panel_info.cont_splash_enabled = 0; ctrl_pdata->panel_data.panel_info.panel_power_on = 0; } else { pr_info("%s:%d Continuous splash flag enabled.\n", __func__, __LINE__); ctrl_pdata->panel_data.panel_info.cont_splash_enabled = 1; ctrl_pdata->panel_data.panel_info.panel_power_on = 1; rc = mdss_dsi_panel_power_on(&(ctrl_pdata->panel_data), 1); if (rc) { pr_err("%s: Panel power on failed\n", __func__); return rc; } mdss_dsi_clk_ctrl(ctrl_pdata, 1); ctrl_pdata->ctrl_state |= (CTRL_STATE_PANEL_INIT | CTRL_STATE_MDP_ACTIVE); } rc = mdss_register_panel(ctrl_pdev, &(ctrl_pdata->panel_data)); if (rc) { dev_err(&pdev->dev, "unable to register MIPI DSI panel\n"); if (ctrl_pdata->rst_gpio) gpio_free(ctrl_pdata->rst_gpio); if (gpio_is_valid(ctrl_pdata->disp_en_gpio)) gpio_free(ctrl_pdata->disp_en_gpio); return rc; } ctrl_pdata->on = panel_data->on; ctrl_pdata->off = panel_data->off; if (panel_data->panel_info.pdest == DISPLAY_1) { mdss_debug_register_base("dsi0", ctrl_pdata->ctrl_base, ctrl_pdata->reg_size); ctrl_pdata->ndx = 0; } else { mdss_debug_register_base("dsi1", ctrl_pdata->ctrl_base, ctrl_pdata->reg_size); ctrl_pdata->ndx = 1; } pr_debug("%s: Panal data initialized\n", __func__); return 0; }
int dsi_panel_device_register(struct platform_device *pdev, struct mdss_panel_common_pdata *panel_data) { struct mipi_panel_info *mipi; int rc, i, len; u8 lanes = 0, bpp; u32 h_period, v_period, dsi_pclk_rate, tmp[9]; struct mdss_dsi_ctrl_pdata *ctrl_pdata; struct device_node *dsi_ctrl_np = NULL; struct platform_device *ctrl_pdev = NULL; bool cont_splash_enabled = false; const char *data; h_period = ((panel_data->panel_info.lcdc.h_pulse_width) + (panel_data->panel_info.lcdc.h_back_porch) + (panel_data->panel_info.xres) + (panel_data->panel_info.lcdc.h_front_porch)); v_period = ((panel_data->panel_info.lcdc.v_pulse_width) + (panel_data->panel_info.lcdc.v_back_porch) + (panel_data->panel_info.yres) + (panel_data->panel_info.lcdc.v_front_porch)); mipi = &panel_data->panel_info.mipi; panel_data->panel_info.type = ((mipi->mode == DSI_VIDEO_MODE) ? MIPI_VIDEO_PANEL : MIPI_CMD_PANEL); if (mipi->data_lane3) lanes += 1; if (mipi->data_lane2) lanes += 1; if (mipi->data_lane1) lanes += 1; if (mipi->data_lane0) lanes += 1; if ((mipi->dst_format == DSI_CMD_DST_FORMAT_RGB888) || (mipi->dst_format == DSI_VIDEO_DST_FORMAT_RGB888) || (mipi->dst_format == DSI_VIDEO_DST_FORMAT_RGB666_LOOSE)) bpp = 3; else if ((mipi->dst_format == DSI_CMD_DST_FORMAT_RGB565) || (mipi->dst_format == DSI_VIDEO_DST_FORMAT_RGB565)) bpp = 2; else bpp = 3; /* Default format set to RGB888 */ if (!panel_data->panel_info.clk_rate) { h_period += panel_data->panel_info.lcdc.xres_pad; v_period += panel_data->panel_info.lcdc.yres_pad; if (lanes > 0) { panel_data->panel_info.clk_rate = ((h_period * v_period * (mipi->frame_rate) * bpp * 8) / lanes); } else { pr_err("%s: forcing mdss_dsi lanes to 1\n", __func__); panel_data->panel_info.clk_rate = (h_period * v_period * (mipi->frame_rate) * bpp * 8); } } pll_divider_config.clk_rate = panel_data->panel_info.clk_rate; rc = mdss_dsi_clk_div_config(bpp, lanes, &dsi_pclk_rate); if (rc) { pr_err("%s: unable to initialize the clk dividers\n", __func__); return rc; } if ((dsi_pclk_rate < 3300000) || (dsi_pclk_rate > 250000000)) dsi_pclk_rate = 35000000; mipi->dsi_pclk_rate = dsi_pclk_rate; dsi_ctrl_np = of_parse_phandle(pdev->dev.of_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); ctrl_pdata = platform_get_drvdata(ctrl_pdev); if (!ctrl_pdata) { pr_err("%s: no dsi ctrl driver data\n", __func__); return -EINVAL; } rc = mdss_dsi_regulator_init(ctrl_pdev); if (rc) { dev_err(&pdev->dev, "%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); if ((!data) || (len != 2)) { pr_err("%s:%d, Unable to read Phy Strength ctrl settings", __func__, __LINE__); return -EINVAL; } (panel_data->panel_info.mipi.dsi_phy_db)->strength[0] = data[0]; (panel_data->panel_info.mipi.dsi_phy_db)->strength[1] = data[1]; data = of_get_property(ctrl_pdev->dev.of_node, "qcom,platform-regulator-settings", &len); if ((!data) || (len != 7)) { pr_err("%s:%d, Unable to read Phy regulator settings", __func__, __LINE__); return -EINVAL; } for (i = 0; i < len; i++) { (panel_data->panel_info.mipi.dsi_phy_db)->regulator[i] = data[i]; } data = of_get_property(ctrl_pdev->dev.of_node, "qcom,platform-bist-ctrl", &len); if ((!data) || (len != 6)) { pr_err("%s:%d, Unable to read Phy Bist Ctrl settings", __func__, __LINE__); return -EINVAL; } for (i = 0; i < len; i++) { (panel_data->panel_info.mipi.dsi_phy_db)->bistCtrl[i] = data[i]; } data = of_get_property(ctrl_pdev->dev.of_node, "qcom,platform-lane-config", &len); if ((!data) || (len != 45)) { pr_err("%s:%d, Unable to read Phy lane configure settings", __func__, __LINE__); return -EINVAL; } for (i = 0; i < len; i++) { (panel_data->panel_info.mipi.dsi_phy_db)->laneCfg[i] = data[i]; } ctrl_pdata->shared_pdata.broadcast_enable = of_property_read_bool( pdev->dev.of_node, "qcom,mdss-dsi-panel-broadcast-mode"); ctrl_pdata->disp_en_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-enable-gpio", 0); if (!gpio_is_valid(ctrl_pdata->disp_en_gpio)) { pr_err("%s:%d, Disp_en gpio not specified\n", __func__, __LINE__); } else { rc = gpio_request(ctrl_pdata->disp_en_gpio, "disp_enable"); if (rc) { pr_err("request reset gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_en_gpio); return -ENODEV; } } ctrl_pdata->disp_te_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-te-gpio", 0); if (!gpio_is_valid(ctrl_pdata->disp_te_gpio)) { pr_err("%s:%d, Disp_te gpio not specified\n", __func__, __LINE__); } else { int func; rc = gpio_request(ctrl_pdata->disp_te_gpio, "disp_te"); if (rc) { pr_err("request TE gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_te_gpio); return -ENODEV; } if (panel_data->panel_info.mipi.mode == DSI_CMD_MODE) func = 1; else func = 0; rc = gpio_tlmm_config(GPIO_CFG( ctrl_pdata->disp_te_gpio, func, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), GPIO_CFG_ENABLE); if (rc) { pr_err("%s: unable to config tlmm = %d\n", __func__, ctrl_pdata->disp_te_gpio); gpio_free(ctrl_pdata->disp_te_gpio); return -ENODEV; } rc = gpio_direction_input(ctrl_pdata->disp_te_gpio); if (rc) { pr_err("set_direction for disp_en gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_te_gpio); return -ENODEV; } pr_debug("%s: te_gpio=%d\n", __func__, ctrl_pdata->disp_te_gpio); } rc = of_property_read_u32_array(ctrl_pdev->dev.of_node, "qcom,platform-reset-sequence", tmp, MDSS_DSI_RST_SEQ_LEN); if (rc) pr_err("%s:%d, unable to read gpio reset sequence\n", __func__, __LINE__); else for (i = 0; i < MDSS_DSI_RST_SEQ_LEN; ++i) ctrl_pdata->rst_seq[i] = tmp[i]; ctrl_pdata->rst_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-reset-gpio", 0); if (!gpio_is_valid(ctrl_pdata->rst_gpio)) { pr_err("%s:%d, reset gpio not specified\n", __func__, __LINE__); } else { rc = gpio_request(ctrl_pdata->rst_gpio, "disp_rst_n"); if (rc) { pr_err("request reset gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->rst_gpio); if (gpio_is_valid(ctrl_pdata->disp_en_gpio)) gpio_free(ctrl_pdata->disp_en_gpio); return -ENODEV; } } if (mdss_dsi_clk_init(ctrl_pdev, ctrl_pdata)) { pr_err("%s: unable to initialize Dsi ctrl clks\n", __func__); return -EPERM; } if (mdss_dsi_retrieve_ctrl_resources(ctrl_pdev, panel_data->panel_info.pdest, ctrl_pdata)) { pr_err("%s: unable to get Dsi controller res\n", __func__); return -EPERM; } ctrl_pdata->panel_data.event_handler = mdss_dsi_event_handler; ctrl_pdata->on_cmds = panel_data->on_cmds; ctrl_pdata->off_cmds = panel_data->off_cmds; ctrl_pdata->off_cmds_1 = panel_data->off_cmds_1; memcpy(&((ctrl_pdata->panel_data).panel_info), &(panel_data->panel_info), sizeof(struct mdss_panel_info)); ctrl_pdata->panel_config = panel_data->panel_config; ctrl_pdata->panel_esd_data = panel_data->panel_esd_data; ctrl_pdata->rst_seq_len = panel_data->rst_seq_len; memcpy(ctrl_pdata->rst_seq, panel_data->rst_seq, sizeof(ctrl_pdata->rst_seq)); ctrl_pdata->dis_rst_seq_len = panel_data->dis_rst_seq_len; memcpy(ctrl_pdata->dis_rst_seq, panel_data->dis_rst_seq, sizeof(ctrl_pdata->dis_rst_seq)); ctrl_pdata->panel_data.set_backlight = panel_data->bl_fnc; ctrl_pdata->bklt_ctrl = panel_data->panel_info.bklt_ctrl; ctrl_pdata->pwm_pmic_gpio = panel_data->panel_info.pwm_pmic_gpio; ctrl_pdata->pwm_period = panel_data->panel_info.pwm_period; ctrl_pdata->pwm_lpg_chan = panel_data->panel_info.pwm_lpg_chan; ctrl_pdata->bklt_max = panel_data->panel_info.bl_max; ctrl_pdata->panel_vregs = panel_data->vregs; ctrl_pdata->pdev = pdev; if (ctrl_pdata->bklt_ctrl == BL_PWM) mdss_dsi_panel_pwm_cfg(ctrl_pdata); mdss_dsi_ctrl_init(ctrl_pdata); /* * register in mdp driver */ ctrl_pdata->pclk_rate = dsi_pclk_rate; ctrl_pdata->byte_clk_rate = panel_data->panel_info.clk_rate / 8; pr_debug("%s: pclk=%d, bclk=%d\n", __func__, ctrl_pdata->pclk_rate, ctrl_pdata->byte_clk_rate); ctrl_pdata->ctrl_state = CTRL_STATE_UNKNOWN; cont_splash_enabled = of_property_read_bool(pdev->dev.of_node, "qcom,cont-splash-enabled"); /* If it is bare board, disable splash feature. */ if (panel_data->panel_config.bare_board) cont_splash_enabled = 0; if (!cont_splash_enabled) { pr_info("%s:%d Continuous splash flag not found.\n", __func__, __LINE__); ctrl_pdata->panel_data.panel_info.cont_splash_enabled = 0; ctrl_pdata->panel_data.panel_info.panel_power_on = 0; } else { pr_info("%s:%d Continuous splash flag enabled.\n", __func__, __LINE__); ctrl_pdata->panel_data.panel_info.cont_splash_enabled = 1; ctrl_pdata->panel_data.panel_info.panel_power_on = 1; rc = mdss_dsi_panel_power_on(&(ctrl_pdata->panel_data), 1); if (rc) { pr_err("%s: Panel power on failed\n", __func__); return rc; } mdss_dsi_clk_ctrl(ctrl_pdata, 1); ctrl_pdata->ctrl_state |= (CTRL_STATE_PANEL_INIT | CTRL_STATE_MDP_ACTIVE); } rc = mdss_register_panel(ctrl_pdev, &(ctrl_pdata->panel_data)); if (rc) { dev_err(&pdev->dev, "unable to register MIPI DSI panel\n"); if (ctrl_pdata->rst_gpio) gpio_free(ctrl_pdata->rst_gpio); if (gpio_is_valid(ctrl_pdata->disp_en_gpio)) gpio_free(ctrl_pdata->disp_en_gpio); return rc; } ctrl_pdata->on = panel_data->on; ctrl_pdata->off = panel_data->off; ctrl_pdata->esd = panel_data->esd; ctrl_pdata->lock_mutex = panel_data->lock_mutex; ctrl_pdata->unlock_mutex = panel_data->unlock_mutex; ctrl_pdata->reg_read = panel_data->reg_read; ctrl_pdata->reg_write = panel_data->reg_write; if (panel_data->panel_info.pdest == DISPLAY_1) { mdss_debug_register_base("dsi0", ctrl_pdata->ctrl_base, ctrl_pdata->reg_size); ctrl_pdata->ndx = 0; } else { mdss_debug_register_base("dsi1", ctrl_pdata->ctrl_base, ctrl_pdata->reg_size); ctrl_pdata->ndx = 1; } if (ctrl_pdata->panel_config.esd_enable) { pr_debug("%s: create ESD worker thread\n", __func__); ctrl_pdata->panel_esd_data.esd_wq = create_singlethread_workqueue("mdss_panel_esd"); if (ctrl_pdata->panel_esd_data.esd_wq == NULL) { pr_err("%s: failed to create ESD work queue\n", __func__); ctrl_pdata->panel_config.esd_enable = false; } } else pr_info("MDSS PANEL: ESD detection is disable\n"); mutex_init(&ctrl_pdata->panel_config.panel_mutex); pr_debug("%s: Panel data initialized\n", __func__); return 0; }
int dsi_panel_device_register(struct device_node *pan_node, struct mdss_dsi_ctrl_pdata *ctrl_pdata) { struct mipi_panel_info *mipi; int rc, i, len; struct device_node *dsi_ctrl_np = NULL; struct platform_device *ctrl_pdev = NULL; bool dynamic_fps; const char *data; struct mdss_panel_info *pinfo = &(ctrl_pdata->panel_data.panel_info); 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_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); if ((!data) || (len != 2)) { pr_err("%s:%d, Unable to read Phy Strength ctrl settings", __func__, __LINE__); return -EINVAL; } pinfo->mipi.dsi_phy_db.strength[0] = data[0]; pinfo->mipi.dsi_phy_db.strength[1] = data[1]; data = of_get_property(ctrl_pdev->dev.of_node, "qcom,platform-regulator-settings", &len); if ((!data) || (len != 7)) { pr_err("%s:%d, Unable to read Phy regulator settings", __func__, __LINE__); return -EINVAL; } for (i = 0; i < len; i++) { pinfo->mipi.dsi_phy_db.regulator[i] = data[i]; } data = of_get_property(ctrl_pdev->dev.of_node, "qcom,platform-bist-ctrl", &len); if ((!data) || (len != 6)) { pr_err("%s:%d, Unable to read Phy Bist Ctrl settings", __func__, __LINE__); return -EINVAL; } for (i = 0; i < len; i++) { pinfo->mipi.dsi_phy_db.bistctrl[i] = data[i]; } data = of_get_property(ctrl_pdev->dev.of_node, "qcom,platform-lane-config", &len); if ((!data) || (len != 45)) { pr_err("%s:%d, Unable to read Phy lane configure settings", __func__, __LINE__); return -EINVAL; } for (i = 0; i < len; i++) { pinfo->mipi.dsi_phy_db.lanecfg[i] = data[i]; } ctrl_pdata->shared_pdata.broadcast_enable = of_property_read_bool( pan_node, "qcom,mdss-dsi-panel-broadcast-mode"); dynamic_fps = of_property_read_bool(pan_node, "qcom,mdss-dsi-pan-enable-dynamic-fps"); if (dynamic_fps) { pinfo->dynamic_fps = true; data = of_get_property(pan_node, "qcom,mdss-dsi-pan-fps-update", NULL); if (data) { if (!strcmp(data, "dfps_suspend_resume_mode")) { pinfo->dfps_update = DFPS_SUSPEND_RESUME_MODE; pr_debug("%s: dfps mode: suspend/resume\n", __func__); } else if (!strcmp(data, "dfps_immediate_clk_mode")) { pinfo->dfps_update = DFPS_IMMEDIATE_CLK_UPDATE_MODE; pr_debug("%s: dfps mode: Immediate clk\n", __func__); } else { pr_debug("%s: dfps to default mode\n", __func__); pinfo->dfps_update = DFPS_SUSPEND_RESUME_MODE; pr_debug("%s: dfps mode: suspend/resume\n", __func__); } } else { pr_debug("%s: dfps update mode not configured\n", __func__); pinfo->dynamic_fps = false; pr_debug("%s: dynamic FPS disabled\n", __func__); } pinfo->new_fps = pinfo->mipi.frame_rate; } ctrl_pdata->disp_en_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-enable-gpio", 0); if (!gpio_is_valid(ctrl_pdata->disp_en_gpio)) { pr_err("%s:%d, Disp_en gpio not specified\n", __func__, __LINE__); } else { rc = gpio_request(ctrl_pdata->disp_en_gpio, "disp_enable"); if (rc) { pr_err("request reset gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_en_gpio); return -ENODEV; } } if (pinfo->type == MIPI_CMD_PANEL) { ctrl_pdata->disp_te_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-te-gpio", 0); if (!gpio_is_valid(ctrl_pdata->disp_te_gpio)) { pr_err("%s:%d, Disp_te gpio not specified\n", __func__, __LINE__); } if (gpio_is_valid(ctrl_pdata->disp_te_gpio)) { rc = gpio_request(ctrl_pdata->disp_te_gpio, "disp_te"); if (rc) { pr_err("request TE gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_te_gpio); return -ENODEV; } rc = gpio_tlmm_config(GPIO_CFG( ctrl_pdata->disp_te_gpio, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), GPIO_CFG_ENABLE); if (rc) { pr_err("%s: unable to config tlmm = %d\n", __func__, ctrl_pdata->disp_te_gpio); gpio_free(ctrl_pdata->disp_te_gpio); return -ENODEV; } rc = gpio_direction_input(ctrl_pdata->disp_te_gpio); if (rc) { pr_err("set_direction for disp_en gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_te_gpio); return -ENODEV; } pr_debug("%s: te_gpio=%d\n", __func__, ctrl_pdata->disp_te_gpio); } } ctrl_pdata->rst_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-reset-gpio", 0); if (!gpio_is_valid(ctrl_pdata->rst_gpio)) { pr_err("%s:%d, reset gpio not specified\n", __func__, __LINE__); } else { rc = gpio_request(ctrl_pdata->rst_gpio, "disp_rst_n"); if (rc) { pr_err("request reset gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->rst_gpio); if (gpio_is_valid(ctrl_pdata->disp_en_gpio)) gpio_free(ctrl_pdata->disp_en_gpio); return -ENODEV; } } if (pinfo->mode_gpio_state != MODE_GPIO_NOT_VALID) { ctrl_pdata->mode_gpio = of_get_named_gpio( ctrl_pdev->dev.of_node, "qcom,platform-mode-gpio", 0); if (!gpio_is_valid(ctrl_pdata->mode_gpio)) { pr_info("%s:%d, mode gpio not specified\n", __func__, __LINE__); } else { rc = gpio_request(ctrl_pdata->mode_gpio, "panel_mode"); if (rc) { pr_err("request panel mode gpio failed,rc=%d\n", rc); gpio_free(ctrl_pdata->mode_gpio); if (gpio_is_valid(ctrl_pdata->disp_en_gpio)) gpio_free(ctrl_pdata->disp_en_gpio); if (gpio_is_valid(ctrl_pdata->rst_gpio)) gpio_free(ctrl_pdata->rst_gpio); if (gpio_is_valid(ctrl_pdata->disp_te_gpio)) gpio_free(ctrl_pdata->disp_te_gpio); return -ENODEV; } } } #if defined(CONFIG_FB_MSM_MDSS_SHARP_HD_PANEL) || defined(CONFIG_FB_MSM_MDSS_HIMAX_QHD_PANEL) ctrl_pdata->bl_on_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,bl-on-gpio", 0); if (!gpio_is_valid(ctrl_pdata->bl_on_gpio)) { pr_err("%s:%dbl_on_gpio gpio not specified\n", __func__, __LINE__); } else { rc = gpio_request(ctrl_pdata->bl_on_gpio, "backlight_enable"); if (rc) { pr_err("request bl_on_gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->bl_on_gpio); }else { rc = gpio_tlmm_config(GPIO_CFG(ctrl_pdata->bl_on_gpio, 0, GPIO_CFG_OUTPUT,GPIO_CFG_NO_PULL,GPIO_CFG_8MA), GPIO_CFG_ENABLE); if (rc) pr_err("request BL ON gpio failed, rc=%d\n",rc); } } ctrl_pdata->disp_en_gpio_p = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,disp-on-gpio-p", 0); rc = gpio_request(ctrl_pdata->disp_en_gpio_p, "disp_en_gpio_p"); if (rc) { pr_err("request disp_en_gpio_p gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_en_gpio_p); }else{ rc = gpio_tlmm_config(GPIO_CFG(ctrl_pdata->disp_en_gpio_p, 0, GPIO_CFG_OUTPUT,GPIO_CFG_NO_PULL,GPIO_CFG_8MA), GPIO_CFG_ENABLE); if (rc) pr_err("request disp_en_gpio_p failed, rc=%d\n",rc); } ctrl_pdata->disp_en_gpio_n = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,disp-on-gpio-n", 0); rc = gpio_request(ctrl_pdata->disp_en_gpio_n, "disp_en_gpio_n"); if (rc) { pr_err("request disp_en_gpio_n gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_en_gpio_n); }else{ rc = gpio_tlmm_config(GPIO_CFG(ctrl_pdata->disp_en_gpio_n, 0, GPIO_CFG_OUTPUT,GPIO_CFG_NO_PULL,GPIO_CFG_8MA), GPIO_CFG_ENABLE); if (rc) pr_err("request disp_en_gpio_n failed, rc=%d\n",rc); } #endif #if defined(CONFIG_FB_MSM_MDSS_SDC_WXGA_PANEL) ctrl_pdata->bl_on_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,bl-on-gpio", 0); if (!gpio_is_valid(ctrl_pdata->bl_on_gpio)) { pr_err("%s:%dbl_on_gpio gpio not specified\n", __func__, __LINE__); } else { rc = gpio_request(ctrl_pdata->bl_on_gpio, "backlight_enable"); if (rc) { pr_err("request bl_on_gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->bl_on_gpio); } } ctrl_pdata->bl_sda = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,bl-sda", 0); rc = gpio_request(ctrl_pdata->bl_sda, "bl_sda"); if (rc) { pr_err("request bl_sda gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->bl_sda); }else{ rc = gpio_tlmm_config(GPIO_CFG(ctrl_pdata->bl_sda, 0, GPIO_CFG_OUTPUT,GPIO_CFG_NO_PULL,GPIO_CFG_8MA), GPIO_CFG_ENABLE); if (rc) pr_err("request bl_sda failed, rc=%d\n",rc); } ctrl_pdata->bl_scl= of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,bl-scl", 0); rc = gpio_request(ctrl_pdata->bl_scl, "bl_scl"); if (rc) { pr_err("request bl_scl gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->bl_scl); }else{ rc = gpio_tlmm_config(GPIO_CFG(ctrl_pdata->bl_scl, 0, GPIO_CFG_OUTPUT,GPIO_CFG_NO_PULL,GPIO_CFG_8MA), GPIO_CFG_ENABLE); if (rc) pr_err("request bl_scl failed, rc=%d\n",rc); } ctrl_pdata->bl_rst_gpio= of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,bl-rst-gpio", 0); rc = gpio_request(ctrl_pdata->bl_rst_gpio, "bl_rst"); if (rc) { pr_err("request bl_rst gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->bl_rst_gpio); }else{ rc = gpio_tlmm_config(GPIO_CFG(ctrl_pdata->bl_rst_gpio, 0, GPIO_CFG_OUTPUT,GPIO_CFG_NO_PULL,GPIO_CFG_8MA), GPIO_CFG_ENABLE); if (rc) pr_err("request bl_rst failed, rc=%d\n",rc); } ctrl_pdata->bl_ap_pwm= of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,bl-wled", 0); rc = gpio_request(ctrl_pdata->bl_ap_pwm, "bl_ap_pwm"); if (rc) { pr_err("request bl_ap_pwm gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->bl_ap_pwm); }else{ rc = gpio_tlmm_config(GPIO_CFG(ctrl_pdata->bl_ap_pwm, 0, GPIO_CFG_OUTPUT,GPIO_CFG_NO_PULL,GPIO_CFG_8MA), GPIO_CFG_ENABLE); if (rc) pr_err("request bl_ap_pwm failed, rc=%d\n",rc); } ctrl_pdata->bl_ldi_en = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,lcd_ldi_int", 0); rc = gpio_request(ctrl_pdata->bl_ldi_en, "bl_ldi_en"); if (rc) { pr_err("request bl_ldi_en gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->bl_ldi_en); } #endif #if defined(CONFIG_FB_MSM_MDSS_BOE_WXGA_PANEL) ctrl_pdata->bl_on_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,bl-on-gpio", 0); if (!gpio_is_valid(ctrl_pdata->bl_on_gpio)) { pr_err("%s:%dbl_on_gpio gpio not specified\n", __func__, __LINE__); } else { rc = gpio_request(ctrl_pdata->bl_on_gpio, "backlight_enable"); if (rc) { pr_err("request bl_on_gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->bl_on_gpio); }else { rc = gpio_tlmm_config(GPIO_CFG(ctrl_pdata->bl_on_gpio, 0, GPIO_CFG_OUTPUT,GPIO_CFG_NO_PULL,GPIO_CFG_8MA), GPIO_CFG_ENABLE); if (rc) pr_err("request BL ON gpio failed, rc=%d\n",rc); } } ctrl_pdata->disp_en_gpio_3v = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,disp-on-gpio", 0); rc = gpio_request(ctrl_pdata->disp_en_gpio_3v, "disp_en_gpio"); if (rc) { pr_err("request disp_en_gpio_3v gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_en_gpio_3v); }else{ rc = gpio_tlmm_config(GPIO_CFG(ctrl_pdata->disp_en_gpio_3v, 0, GPIO_CFG_OUTPUT,GPIO_CFG_NO_PULL,GPIO_CFG_8MA), GPIO_CFG_ENABLE); if (rc) pr_err("request disp_en_gpio_3v failed, rc=%d\n",rc); } #endif #if defined(CONFIG_FB_MSM_MDSS_S6E8AA0A_HD_PANEL) ctrl_pdata->disp_en_gpio_2_2v = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,disp-on-gpio", 0); rc = gpio_request(ctrl_pdata->disp_en_gpio_2_2v, "disp_en_gpio_2_2v"); if (rc) { pr_err("request disp_en_gpio_2_2v gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_en_gpio_2_2v); }else{ rc = gpio_tlmm_config(GPIO_CFG(ctrl_pdata->disp_en_gpio_2_2v, 0, GPIO_CFG_OUTPUT,GPIO_CFG_NO_PULL,GPIO_CFG_8MA), GPIO_CFG_ENABLE); if (rc) pr_err("request disp_en_gpio_2_2v failed, rc=%d\n",rc); } #endif #if defined(CONFIG_FB_MSM_MDSS_MAGNA_WVGA_PANEL) ctrl_pdata->disp_en_gpio_1_8v = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,disp-on-gpio", 0); rc = gpio_request(ctrl_pdata->disp_en_gpio_1_8v, "disp_en_gpio_1_8v"); if (rc) { pr_err("request disp_en_gpio_1_8v gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_en_gpio_1_8v); }else{ rc = gpio_tlmm_config(GPIO_CFG(ctrl_pdata->disp_en_gpio_1_8v, 0, GPIO_CFG_OUTPUT,GPIO_CFG_NO_PULL,GPIO_CFG_8MA), GPIO_CFG_ENABLE); if (rc) pr_err("request disp_en_gpio_1_8v failed, rc=%d\n",rc); } #endif if (mdss_dsi_clk_init(ctrl_pdev, ctrl_pdata)) { pr_err("%s: unable to initialize Dsi ctrl clks\n", __func__); return -EPERM; } if (mdss_dsi_retrieve_ctrl_resources(ctrl_pdev, pinfo->pdest, ctrl_pdata)) { pr_err("%s: unable to get Dsi controller res\n", __func__); return -EPERM; } ctrl_pdata->panel_data.event_handler = mdss_dsi_event_handler; ctrl_pdata->panel_data.panel_reset_fn = ctrl_pdata->panel_reset; if (ctrl_pdata->bklt_ctrl == BL_PWM) mdss_dsi_panel_pwm_cfg(ctrl_pdata); mdss_dsi_ctrl_init(ctrl_pdata); /* * register in mdp driver */ ctrl_pdata->pclk_rate = mipi->dsi_pclk_rate; ctrl_pdata->byte_clk_rate = pinfo->clk_rate / 8; pr_debug("%s: pclk=%d, bclk=%d\n", __func__, ctrl_pdata->pclk_rate, ctrl_pdata->byte_clk_rate); ctrl_pdata->ctrl_state = CTRL_STATE_UNKNOWN; if (pinfo->cont_splash_enabled) { pinfo->panel_power_on = 1; rc = mdss_dsi_panel_power_on(&(ctrl_pdata->panel_data), 1); if (rc) { pr_err("%s: Panel power on failed\n", __func__); return rc; } mdss_dsi_clk_ctrl(ctrl_pdata, 1); ctrl_pdata->ctrl_state |= (CTRL_STATE_PANEL_INIT | CTRL_STATE_MDP_ACTIVE); } else { pinfo->panel_power_on = 0; } rc = mdss_register_panel(ctrl_pdev, &(ctrl_pdata->panel_data)); if (rc) { pr_err("%s: unable to register MIPI DSI panel\n", __func__); if (ctrl_pdata->rst_gpio) gpio_free(ctrl_pdata->rst_gpio); if (gpio_is_valid(ctrl_pdata->disp_en_gpio)) gpio_free(ctrl_pdata->disp_en_gpio); return rc; } if (pinfo->pdest == DISPLAY_1) { mdss_debug_register_base("dsi0", ctrl_pdata->ctrl_base, ctrl_pdata->reg_size); ctrl_pdata->ndx = 0; } else { mdss_debug_register_base("dsi1", ctrl_pdata->ctrl_base, ctrl_pdata->reg_size); ctrl_pdata->ndx = 1; } pr_debug("%s: Panel data initialized\n", __func__); return 0; }
int dsi_panel_device_register(struct device_node *pan_node, struct mdss_dsi_ctrl_pdata *ctrl_pdata) { struct mipi_panel_info *mipi; int rc, i, len; struct device_node *dsi_ctrl_np = NULL; struct platform_device *ctrl_pdev = NULL; bool dynamic_fps; const char *data; struct mdss_panel_info *pinfo = &(ctrl_pdata->panel_data.panel_info); 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_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); if ((!data) || (len != 2)) { pr_err("%s:%d, Unable to read Phy Strength ctrl settings", __func__, __LINE__); return -EINVAL; } pinfo->mipi.dsi_phy_db.strength[0] = data[0]; pinfo->mipi.dsi_phy_db.strength[1] = data[1]; data = of_get_property(ctrl_pdev->dev.of_node, "qcom,platform-regulator-settings", &len); if ((!data) || (len != 7)) { pr_err("%s:%d, Unable to read Phy regulator settings", __func__, __LINE__); return -EINVAL; } for (i = 0; i < len; i++) { pinfo->mipi.dsi_phy_db.regulator[i] = data[i]; } data = of_get_property(ctrl_pdev->dev.of_node, "qcom,platform-bist-ctrl", &len); if ((!data) || (len != 6)) { pr_err("%s:%d, Unable to read Phy Bist Ctrl settings", __func__, __LINE__); return -EINVAL; } for (i = 0; i < len; i++) { pinfo->mipi.dsi_phy_db.bistctrl[i] = data[i]; } data = of_get_property(ctrl_pdev->dev.of_node, "qcom,platform-lane-config", &len); if ((!data) || (len != 45)) { pr_err("%s:%d, Unable to read Phy lane configure settings", __func__, __LINE__); return -EINVAL; } for (i = 0; i < len; i++) { pinfo->mipi.dsi_phy_db.lanecfg[i] = data[i]; } ctrl_pdata->shared_pdata.broadcast_enable = of_property_read_bool( pan_node, "qcom,mdss-dsi-panel-broadcast-mode"); dynamic_fps = of_property_read_bool(pan_node, "qcom,mdss-dsi-pan-enable-dynamic-fps"); if (dynamic_fps) { pinfo->dynamic_fps = true; data = of_get_property(pan_node, "qcom,mdss-dsi-pan-fps-update", NULL); if (data) { if (!strcmp(data, "dfps_suspend_resume_mode")) { pinfo->dfps_update = DFPS_SUSPEND_RESUME_MODE; pr_debug("%s: dfps mode: suspend/resume\n", __func__); } else if (!strcmp(data, "dfps_immediate_clk_mode")) { pinfo->dfps_update = DFPS_IMMEDIATE_CLK_UPDATE_MODE; pr_debug("%s: dfps mode: Immediate clk\n", __func__); } else if (!strcmp(data, "dfps_immediate_porch_mode")) { pinfo->dfps_update = DFPS_IMMEDIATE_PORCH_UPDATE_MODE; pr_debug("%s: dfps mode: Immediate porch\n", __func__); } else { pr_debug("%s: dfps to default mode\n", __func__); pinfo->dfps_update = DFPS_SUSPEND_RESUME_MODE; pr_debug("%s: dfps mode: suspend/resume\n", __func__); } } else { pr_debug("%s: dfps update mode not configured\n", __func__); pinfo->dynamic_fps = false; pr_debug("%s: dynamic FPS disabled\n", __func__); } pinfo->new_fps = pinfo->mipi.frame_rate; } ctrl_pdata->disp_en_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-enable-gpio", 0); if (!gpio_is_valid(ctrl_pdata->disp_en_gpio)) pr_err("%s:%d, Disp_en gpio not specified\n", __func__, __LINE__); #ifdef CONFIG_ZTEMT_LCD_POWER_CONTRL /*avdd neg ctl board2 add ,mayu 6.25*/ ctrl_pdata->avdd_neg_en_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-avddn-enable-gpio", 0); if (!gpio_is_valid(ctrl_pdata->avdd_neg_en_gpio)) { pr_err("%s:%d, avdd_neg_en_gpio gpio not specified\n", __func__, __LINE__); } else { rc = gpio_request(ctrl_pdata->avdd_neg_en_gpio, "lcd_avdd_neg_enable"); if (rc) { pr_err("request reset gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->avdd_neg_en_gpio); return -ENODEV; } } #endif #ifdef CONFIG_ZTEMT_LCD_ESD_TE_CHECK /*esd check faild check,mayu add*/ if (pinfo->type != MIPI_CMD_PANEL) { ctrl_pdata->disp_te_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-te-gpio", 0); if (!gpio_is_valid(ctrl_pdata->disp_te_gpio)) { pr_err("lcd:%s:%d, Disp_te gpio not specified\n", __func__, __LINE__); } rc = gpio_request(ctrl_pdata->disp_te_gpio, "disp_te"); if (rc) { pr_err("request TE gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_te_gpio); return -ENODEV; } rc = gpio_tlmm_config(GPIO_CFG( ctrl_pdata->disp_te_gpio, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), GPIO_CFG_ENABLE); rc = gpio_direction_input(ctrl_pdata->disp_te_gpio); } #endif if (pinfo->type == MIPI_CMD_PANEL) { ctrl_pdata->disp_te_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-te-gpio", 0); if (!gpio_is_valid(ctrl_pdata->disp_te_gpio)) { pr_err("%s:%d, Disp_te gpio not specified\n", __func__, __LINE__); } } if (gpio_is_valid(ctrl_pdata->disp_te_gpio) && pinfo->type == MIPI_CMD_PANEL) { rc = gpio_request(ctrl_pdata->disp_te_gpio, "disp_te"); if (rc) { pr_err("request TE gpio failed, rc=%d\n", rc); return -ENODEV; } rc = gpio_tlmm_config(GPIO_CFG( ctrl_pdata->disp_te_gpio, 1, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), GPIO_CFG_ENABLE); if (rc) { pr_err("%s: unable to config tlmm = %d\n", __func__, ctrl_pdata->disp_te_gpio); gpio_free(ctrl_pdata->disp_te_gpio); return -ENODEV; } rc = gpio_direction_input(ctrl_pdata->disp_te_gpio); if (rc) { pr_err("set_direction for disp_en gpio failed, rc=%d\n", rc); gpio_free(ctrl_pdata->disp_te_gpio); return -ENODEV; } pr_debug("%s: te_gpio=%d\n", __func__, ctrl_pdata->disp_te_gpio); } ctrl_pdata->rst_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-reset-gpio", 0); if (!gpio_is_valid(ctrl_pdata->rst_gpio)) pr_err("%s:%d, reset gpio not specified\n", __func__, __LINE__); if (pinfo->mode_gpio_state != MODE_GPIO_NOT_VALID) { ctrl_pdata->mode_gpio = of_get_named_gpio( ctrl_pdev->dev.of_node, "qcom,platform-mode-gpio", 0); if (!gpio_is_valid(ctrl_pdata->mode_gpio)) pr_info("%s:%d, mode gpio not specified\n", __func__, __LINE__); } if (mdss_dsi_clk_init(ctrl_pdev, ctrl_pdata)) { pr_err("%s: unable to initialize Dsi ctrl clks\n", __func__); return -EPERM; } if (mdss_dsi_retrieve_ctrl_resources(ctrl_pdev, pinfo->pdest, ctrl_pdata)) { pr_err("%s: unable to get Dsi controller res\n", __func__); return -EPERM; } ctrl_pdata->panel_data.event_handler = mdss_dsi_event_handler; /*qcom ori*/ ctrl_pdata->check_status = mdss_dsi_bta_status_check; #ifdef CONFIG_ZTEMT_LCD_ESD_TE_CHECK #if defined(CONFIG_ZTEMT_NE501_LCD) /*esd check faild check,mayu add*/ if (ctrl_pdata->panel_name && (!strcmp(ctrl_pdata->panel_name, "cs nt35592 720p video mode dsi panel") || !strcmp(ctrl_pdata->panel_name, "lianchuang nt35592 720p video mode dsi panel"))) { ctrl_pdata->check_status = zte_check_status_by_te; printk("nt35592 check by te\n"); } else if (ctrl_pdata->panel_name && !strcmp(ctrl_pdata->panel_name, "success hx8392b 720p video mode dsi panel")) { ctrl_pdata->check_status = success_hx83920b_check_status; printk("hx83920b check faled always\n"); } #elif defined(CONFIG_ZTEMT_NX404H_LCD) if (ctrl_pdata->panel_name && !strcmp(ctrl_pdata->panel_name, "otm1282a 720p command mode dsi panel")) { ctrl_pdata->check_status = zte_check_status_by_te; }else{ //other lcd run empty fun ctrl_pdata->check_status = zte_check_status_ok; } #endif #endif //CONFIG_ZTEMT_LCD_ESD_TE_CHECK if (ctrl_pdata->bklt_ctrl == BL_PWM) mdss_dsi_panel_pwm_cfg(ctrl_pdata); mdss_dsi_ctrl_init(ctrl_pdata); /* * register in mdp driver */ ctrl_pdata->pclk_rate = mipi->dsi_pclk_rate; ctrl_pdata->byte_clk_rate = pinfo->clk_rate / 8; pr_debug("%s: pclk=%d, bclk=%d\n", __func__, ctrl_pdata->pclk_rate, ctrl_pdata->byte_clk_rate); ctrl_pdata->ctrl_state = CTRL_STATE_UNKNOWN; if (pinfo->cont_splash_enabled) { pinfo->panel_power_on = 1; rc = mdss_dsi_panel_power_on(&(ctrl_pdata->panel_data), 1); if (rc) { pr_err("%s: Panel power on failed\n", __func__); return rc; } mdss_dsi_clk_ctrl(ctrl_pdata, 1); ctrl_pdata->ctrl_state |= (CTRL_STATE_PANEL_INIT | CTRL_STATE_MDP_ACTIVE); } else { pinfo->panel_power_on = 0; } rc = mdss_register_panel(ctrl_pdev, &(ctrl_pdata->panel_data)); if (rc) { pr_err("%s: unable to register MIPI DSI panel\n", __func__); return rc; } if (pinfo->pdest == DISPLAY_1) { mdss_debug_register_base("dsi0", ctrl_pdata->ctrl_base, ctrl_pdata->reg_size); ctrl_pdata->ndx = 0; } else { mdss_debug_register_base("dsi1", ctrl_pdata->ctrl_base, ctrl_pdata->reg_size); ctrl_pdata->ndx = 1; } pr_debug("%s: Panel data initialized\n", __func__); return 0; }