int mdss_edp_on(struct mdss_panel_data *pdata) { struct mdss_edp_drv_pdata *edp_drv = NULL; int ret = 0; if (!pdata) { pr_err("%s: Invalid input data\n", __func__); return -EINVAL; } edp_drv = container_of(pdata, struct mdss_edp_drv_pdata, panel_data); pr_debug("%s:+, cont_splash=%d\n", __func__, edp_drv->cont_splash); if (!edp_drv->cont_splash) { /* vote for clocks */ mdss_edp_phy_pll_reset(edp_drv); mdss_edp_aux_reset(edp_drv); mdss_edp_mainlink_reset(edp_drv); mdss_edp_aux_ctrl(edp_drv, 1); ret = mdss_edp_prepare_clocks(edp_drv); if (ret) return ret; mdss_edp_phy_power_ctrl(edp_drv, 1); ret = mdss_edp_clk_enable(edp_drv); if (ret) { mdss_edp_unprepare_clocks(edp_drv); return ret; } mdss_edp_phy_pll_ready(edp_drv); mdss_edp_lane_power_ctrl(edp_drv, 1); mdss_edp_clock_synchrous(edp_drv, 1); mdss_edp_phy_vm_pe_init(edp_drv); mdss_edp_config_ctrl(edp_drv); mdss_edp_sw_mvid_nvid(edp_drv); mdss_edp_timing_cfg(edp_drv); gpio_set_value(edp_drv->gpio_panel_en, 1); INIT_COMPLETION(edp_drv->idle_comp); mdss_edp_mainlink_ctrl(edp_drv, 1); } else { mdss_edp_aux_ctrl(edp_drv, 1); } mdss_edp_irq_enable(edp_drv); mdss_edp_wait4train(edp_drv); edp_drv->cont_splash = 0; pr_debug("%s:-\n", __func__); return ret; }
int mdss_edp_off(struct mdss_panel_data *pdata) { struct mdss_edp_drv_pdata *edp_drv = NULL; int ret = 0; edp_drv = container_of(pdata, struct mdss_edp_drv_pdata, panel_data); if (!edp_drv) { pr_err("%s: Invalid input data\n", __func__); return -EINVAL; } pr_debug("%s:+, cont_splash=%d\n", __func__, edp_drv->cont_splash); /* wait until link training is completed */ mutex_lock(&edp_drv->train_mutex); INIT_COMPLETION(edp_drv->idle_comp); mdss_edp_state_ctrl(edp_drv, ST_PUSH_IDLE); ret = wait_for_completion_timeout(&edp_drv->idle_comp, msecs_to_jiffies(100)); if (ret == 0) pr_err("%s: idle pattern timedout\n", __func__); mdss_edp_state_ctrl(edp_drv, 0); mdss_edp_sink_power_state(edp_drv, SINK_POWER_OFF); mdss_edp_irq_disable(edp_drv); gpio_set_value(edp_drv->gpio_panel_en, 0); if (gpio_is_valid(edp_drv->gpio_lvl_en)) gpio_set_value(edp_drv->gpio_lvl_en, 0); if (edp_drv->bl_pwm != NULL) pwm_disable(edp_drv->bl_pwm); edp_drv->is_pwm_enabled = 0; mdss_edp_mainlink_reset(edp_drv); mdss_edp_mainlink_ctrl(edp_drv, 0); mdss_edp_lane_power_ctrl(edp_drv, 0); mdss_edp_phy_power_ctrl(edp_drv, 0); mdss_edp_clk_disable(edp_drv); mdss_edp_unprepare_clocks(edp_drv); mdss_edp_aux_ctrl(edp_drv, 0); pr_debug("%s-: state_ctrl=%x\n", __func__, edp_read(edp_drv->base + 0x8)); mutex_unlock(&edp_drv->train_mutex); return 0; }
static int mdss_edp_probe(struct platform_device *pdev) { int ret; struct mdss_edp_drv_pdata *edp_drv; struct mdss_panel_cfg *pan_cfg = NULL; if (!mdss_is_ready()) { pr_err("%s: MDP not probed yet!\n", __func__); return -EPROBE_DEFER; } pan_cfg = mdss_panel_intf_type(MDSS_PANEL_INTF_EDP); if (IS_ERR(pan_cfg)) { return PTR_ERR(pan_cfg); } else if (!pan_cfg) { pr_debug("%s: not configured as prim\n", __func__); return -ENODEV; } if (!pdev->dev.of_node) { pr_err("%s: Failed\n", __func__); return -EPERM; } edp_drv = devm_kzalloc(&pdev->dev, sizeof(*edp_drv), GFP_KERNEL); if (edp_drv == NULL) { pr_err("%s: Failed, could not allocate edp_drv", __func__); return -ENOMEM; } edp_drv->mdss_util = mdss_get_util_intf(); if (edp_drv->mdss_util == NULL) { pr_err("Failed to get mdss utility functions\n"); return -ENODEV; } edp_drv->panel_data.panel_info.is_prim_panel = true; mdss_edp_hw.irq_info = mdss_intr_line(); if (mdss_edp_hw.irq_info == NULL) { pr_err("Failed to get mdss irq information\n"); return -ENODEV; } edp_drv->pdev = pdev; edp_drv->pdev->id = 1; edp_drv->clk_on = 0; edp_drv->aux_rate = 19200000; edp_drv->mask1 = EDP_INTR_MASK1; edp_drv->mask2 = EDP_INTR_MASK2; mutex_init(&edp_drv->emutex); spin_lock_init(&edp_drv->lock); ret = mdss_edp_get_base_address(edp_drv); if (ret) goto probe_err; ret = mdss_edp_get_mmss_cc_base_address(edp_drv); if (ret) goto edp_base_unmap; ret = mdss_edp_regulator_init(edp_drv); if (ret) goto mmss_cc_base_unmap; ret = mdss_edp_clk_init(edp_drv); if (ret) goto edp_clk_deinit; ret = mdss_edp_gpio_panel_en(edp_drv); if (ret) goto edp_clk_deinit; ret = mdss_edp_gpio_lvl_en(edp_drv); if (ret) pr_err("%s: No gpio_lvl_en detected\n", __func__); ret = mdss_edp_pwm_config(edp_drv); if (ret) goto edp_free_gpio_panel_en; mdss_edp_irq_setup(edp_drv); mdss_edp_aux_init(edp_drv); mdss_edp_event_setup(edp_drv); edp_drv->cont_splash = of_property_read_bool(pdev->dev.of_node, "qcom,cont-splash-enabled"); /* only need aux and ahb clock for aux channel */ mdss_edp_prepare_aux_clocks(edp_drv); mdss_edp_aux_clk_enable(edp_drv); if (!edp_drv->cont_splash) { mdss_edp_phy_pll_reset(edp_drv); mdss_edp_aux_reset(edp_drv); mdss_edp_mainlink_reset(edp_drv); mdss_edp_phy_power_ctrl(edp_drv, 1); mdss_edp_aux_ctrl(edp_drv, 1); } mdss_edp_irq_enable(edp_drv); mdss_edp_edid_read(edp_drv, 0); mdss_edp_dpcd_cap_read(edp_drv); mdss_edp_fill_link_cfg(edp_drv); mdss_edp_irq_disable(edp_drv); if (!edp_drv->cont_splash) { mdss_edp_aux_ctrl(edp_drv, 0); mdss_edp_phy_power_ctrl(edp_drv, 0); } mdss_edp_aux_clk_disable(edp_drv); mdss_edp_unprepare_aux_clocks(edp_drv); if (edp_drv->cont_splash) { /* vote for clocks */ mdss_edp_prepare_clocks(edp_drv); mdss_edp_clk_enable(edp_drv); } mdss_edp_device_register(edp_drv); edp_drv->inited = true; pr_debug("%s: done\n", __func__); return 0; edp_free_gpio_panel_en: gpio_free(edp_drv->gpio_panel_en); if (gpio_is_valid(edp_drv->gpio_lvl_en)) gpio_free(edp_drv->gpio_lvl_en); edp_clk_deinit: mdss_edp_clk_deinit(edp_drv); mdss_edp_regulator_off(edp_drv); mmss_cc_base_unmap: iounmap(edp_drv->mmss_cc_base); edp_base_unmap: iounmap(edp_drv->base); probe_err: return ret; }