Lines Matching refs:ctrl
153 static int edp_clk_init(struct edp_ctrl *ctrl) in edp_clk_init() argument
155 struct device *dev = &ctrl->pdev->dev; in edp_clk_init()
158 ctrl->aux_clk = devm_clk_get(dev, "core_clk"); in edp_clk_init()
159 if (IS_ERR(ctrl->aux_clk)) { in edp_clk_init()
160 ret = PTR_ERR(ctrl->aux_clk); in edp_clk_init()
162 ctrl->aux_clk = NULL; in edp_clk_init()
166 ctrl->pixel_clk = devm_clk_get(dev, "pixel_clk"); in edp_clk_init()
167 if (IS_ERR(ctrl->pixel_clk)) { in edp_clk_init()
168 ret = PTR_ERR(ctrl->pixel_clk); in edp_clk_init()
170 ctrl->pixel_clk = NULL; in edp_clk_init()
174 ctrl->ahb_clk = devm_clk_get(dev, "iface_clk"); in edp_clk_init()
175 if (IS_ERR(ctrl->ahb_clk)) { in edp_clk_init()
176 ret = PTR_ERR(ctrl->ahb_clk); in edp_clk_init()
178 ctrl->ahb_clk = NULL; in edp_clk_init()
182 ctrl->link_clk = devm_clk_get(dev, "link_clk"); in edp_clk_init()
183 if (IS_ERR(ctrl->link_clk)) { in edp_clk_init()
184 ret = PTR_ERR(ctrl->link_clk); in edp_clk_init()
186 ctrl->link_clk = NULL; in edp_clk_init()
191 ctrl->mdp_core_clk = devm_clk_get(dev, "mdp_core_clk"); in edp_clk_init()
192 if (IS_ERR(ctrl->mdp_core_clk)) { in edp_clk_init()
193 ret = PTR_ERR(ctrl->mdp_core_clk); in edp_clk_init()
195 ctrl->mdp_core_clk = NULL; in edp_clk_init()
202 static int edp_clk_enable(struct edp_ctrl *ctrl, u32 clk_mask) in edp_clk_enable() argument
209 ret = clk_prepare_enable(ctrl->ahb_clk); in edp_clk_enable()
216 ret = clk_set_rate(ctrl->aux_clk, 19200000); in edp_clk_enable()
221 ret = clk_prepare_enable(ctrl->aux_clk); in edp_clk_enable()
230 (unsigned long)ctrl->link_rate * 27000000); in edp_clk_enable()
231 ret = clk_set_rate(ctrl->link_clk, in edp_clk_enable()
232 (unsigned long)ctrl->link_rate * 27000000); in edp_clk_enable()
239 ret = clk_prepare_enable(ctrl->link_clk); in edp_clk_enable()
247 (unsigned long)ctrl->pixel_rate * 1000); in edp_clk_enable()
248 ret = clk_set_rate(ctrl->pixel_clk, in edp_clk_enable()
249 (unsigned long)ctrl->pixel_rate * 1000); in edp_clk_enable()
256 ret = clk_prepare_enable(ctrl->pixel_clk); in edp_clk_enable()
263 ret = clk_prepare_enable(ctrl->mdp_core_clk); in edp_clk_enable()
274 clk_disable_unprepare(ctrl->pixel_clk); in edp_clk_enable()
277 clk_disable_unprepare(ctrl->link_clk); in edp_clk_enable()
280 clk_disable_unprepare(ctrl->aux_clk); in edp_clk_enable()
283 clk_disable_unprepare(ctrl->ahb_clk); in edp_clk_enable()
288 static void edp_clk_disable(struct edp_ctrl *ctrl, u32 clk_mask) in edp_clk_disable() argument
291 clk_disable_unprepare(ctrl->mdp_core_clk); in edp_clk_disable()
293 clk_disable_unprepare(ctrl->pixel_clk); in edp_clk_disable()
295 clk_disable_unprepare(ctrl->link_clk); in edp_clk_disable()
297 clk_disable_unprepare(ctrl->aux_clk); in edp_clk_disable()
299 clk_disable_unprepare(ctrl->ahb_clk); in edp_clk_disable()
302 static int edp_regulator_init(struct edp_ctrl *ctrl) in edp_regulator_init() argument
304 struct device *dev = &ctrl->pdev->dev; in edp_regulator_init()
307 ctrl->vdda_vreg = devm_regulator_get(dev, "vdda"); in edp_regulator_init()
308 if (IS_ERR(ctrl->vdda_vreg)) { in edp_regulator_init()
310 PTR_ERR(ctrl->vdda_vreg)); in edp_regulator_init()
311 ctrl->vdda_vreg = NULL; in edp_regulator_init()
312 return PTR_ERR(ctrl->vdda_vreg); in edp_regulator_init()
314 ctrl->lvl_vreg = devm_regulator_get(dev, "lvl-vdd"); in edp_regulator_init()
315 if (IS_ERR(ctrl->lvl_vreg)) { in edp_regulator_init()
317 PTR_ERR(ctrl->lvl_vreg)); in edp_regulator_init()
318 ctrl->lvl_vreg = NULL; in edp_regulator_init()
319 return PTR_ERR(ctrl->lvl_vreg); in edp_regulator_init()
325 static int edp_regulator_enable(struct edp_ctrl *ctrl) in edp_regulator_enable() argument
329 ret = regulator_set_voltage(ctrl->vdda_vreg, VDDA_MIN_UV, VDDA_MAX_UV); in edp_regulator_enable()
335 ret = regulator_set_load(ctrl->vdda_vreg, VDDA_UA_ON_LOAD); in edp_regulator_enable()
341 ret = regulator_enable(ctrl->vdda_vreg); in edp_regulator_enable()
347 ret = regulator_enable(ctrl->lvl_vreg); in edp_regulator_enable()
357 regulator_disable(ctrl->vdda_vreg); in edp_regulator_enable()
359 regulator_set_load(ctrl->vdda_vreg, VDDA_UA_OFF_LOAD); in edp_regulator_enable()
364 static void edp_regulator_disable(struct edp_ctrl *ctrl) in edp_regulator_disable() argument
366 regulator_disable(ctrl->lvl_vreg); in edp_regulator_disable()
367 regulator_disable(ctrl->vdda_vreg); in edp_regulator_disable()
368 regulator_set_load(ctrl->vdda_vreg, VDDA_UA_OFF_LOAD); in edp_regulator_disable()
371 static int edp_gpio_config(struct edp_ctrl *ctrl) in edp_gpio_config() argument
373 struct device *dev = &ctrl->pdev->dev; in edp_gpio_config()
376 ctrl->panel_hpd_gpio = devm_gpiod_get(dev, "panel-hpd"); in edp_gpio_config()
377 if (IS_ERR(ctrl->panel_hpd_gpio)) { in edp_gpio_config()
378 ret = PTR_ERR(ctrl->panel_hpd_gpio); in edp_gpio_config()
379 ctrl->panel_hpd_gpio = NULL; in edp_gpio_config()
384 ret = gpiod_direction_input(ctrl->panel_hpd_gpio); in edp_gpio_config()
390 ctrl->panel_en_gpio = devm_gpiod_get(dev, "panel-en"); in edp_gpio_config()
391 if (IS_ERR(ctrl->panel_en_gpio)) { in edp_gpio_config()
392 ret = PTR_ERR(ctrl->panel_en_gpio); in edp_gpio_config()
393 ctrl->panel_en_gpio = NULL; in edp_gpio_config()
398 ret = gpiod_direction_output(ctrl->panel_en_gpio, 0); in edp_gpio_config()
410 static void edp_ctrl_irq_enable(struct edp_ctrl *ctrl, int enable) in edp_ctrl_irq_enable() argument
415 spin_lock_irqsave(&ctrl->irq_lock, flags); in edp_ctrl_irq_enable()
417 edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_1, EDP_INTR_MASK1); in edp_ctrl_irq_enable()
418 edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_2, EDP_INTR_MASK2); in edp_ctrl_irq_enable()
420 edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_1, 0x0); in edp_ctrl_irq_enable()
421 edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_2, 0x0); in edp_ctrl_irq_enable()
423 spin_unlock_irqrestore(&ctrl->irq_lock, flags); in edp_ctrl_irq_enable()
427 static void edp_fill_link_cfg(struct edp_ctrl *ctrl) in edp_fill_link_cfg() argument
432 u8 max_lane = ctrl->dp_link.num_lanes; in edp_fill_link_cfg()
435 prate = ctrl->pixel_rate; in edp_fill_link_cfg()
436 bpp = ctrl->color_depth * 3; in edp_fill_link_cfg()
442 ctrl->link_rate = drm_dp_link_rate_to_bw_code(ctrl->dp_link.rate); in edp_fill_link_cfg()
448 lrate *= ctrl->link_rate; in edp_fill_link_cfg()
457 ctrl->lane_cnt = lane; in edp_fill_link_cfg()
458 DBG("rate=%d lane=%d", ctrl->link_rate, ctrl->lane_cnt); in edp_fill_link_cfg()
461 static void edp_config_ctrl(struct edp_ctrl *ctrl) in edp_config_ctrl() argument
466 data = EDP_CONFIGURATION_CTRL_LANES(ctrl->lane_cnt - 1); in edp_config_ctrl()
468 if (ctrl->dp_link.capabilities & DP_LINK_CAP_ENHANCED_FRAMING) in edp_config_ctrl()
472 if (ctrl->color_depth == 8) in edp_config_ctrl()
477 if (!ctrl->interlaced) /* progressive */ in edp_config_ctrl()
483 edp_write(ctrl->base + REG_EDP_CONFIGURATION_CTRL, data); in edp_config_ctrl()
486 static void edp_state_ctrl(struct edp_ctrl *ctrl, u32 state) in edp_state_ctrl() argument
488 edp_write(ctrl->base + REG_EDP_STATE_CTRL, state); in edp_state_ctrl()
493 static int edp_lane_set_write(struct edp_ctrl *ctrl, in edp_lane_set_write() argument
511 if (drm_dp_dpcd_write(ctrl->drm_aux, 0x103, buf, 4) < 4) { in edp_lane_set_write()
519 static int edp_train_pattern_set_write(struct edp_ctrl *ctrl, u8 pattern) in edp_train_pattern_set_write() argument
524 if (drm_dp_dpcd_write(ctrl->drm_aux, in edp_train_pattern_set_write()
533 static void edp_sink_train_set_adjust(struct edp_ctrl *ctrl, in edp_sink_train_set_adjust() argument
541 for (i = 0; i < ctrl->lane_cnt; i++) { in edp_sink_train_set_adjust()
548 ctrl->v_level = max >> DP_TRAIN_VOLTAGE_SWING_SHIFT; in edp_sink_train_set_adjust()
552 for (i = 0; i < ctrl->lane_cnt; i++) { in edp_sink_train_set_adjust()
559 ctrl->p_level = max >> DP_TRAIN_PRE_EMPHASIS_SHIFT; in edp_sink_train_set_adjust()
560 DBG("v_level=%d, p_level=%d", ctrl->v_level, ctrl->p_level); in edp_sink_train_set_adjust()
563 static void edp_host_train_set(struct edp_ctrl *ctrl, u32 train) in edp_host_train_set() argument
571 edp_state_ctrl(ctrl, EDP_STATE_CTRL_TRAIN_PATTERN_1 << shift); in edp_host_train_set()
573 data = edp_read(ctrl->base + REG_EDP_MAINLINK_READY); in edp_host_train_set()
597 static int edp_voltage_pre_emphasise_set(struct edp_ctrl *ctrl) in edp_voltage_pre_emphasise_set() argument
602 DBG("v=%d p=%d", ctrl->v_level, ctrl->p_level); in edp_voltage_pre_emphasise_set()
604 value0 = vm_pre_emphasis[(int)(ctrl->v_level)][(int)(ctrl->p_level)]; in edp_voltage_pre_emphasise_set()
605 value1 = vm_voltage_swing[(int)(ctrl->v_level)][(int)(ctrl->p_level)]; in edp_voltage_pre_emphasise_set()
609 msm_edp_phy_vm_pe_cfg(ctrl->phy, value0, value1); in edp_voltage_pre_emphasise_set()
610 return edp_lane_set_write(ctrl, ctrl->v_level, ctrl->p_level); in edp_voltage_pre_emphasise_set()
616 static int edp_start_link_train_1(struct edp_ctrl *ctrl) in edp_start_link_train_1() argument
626 edp_host_train_set(ctrl, DP_TRAINING_PATTERN_1); in edp_start_link_train_1()
627 ret = edp_voltage_pre_emphasise_set(ctrl); in edp_start_link_train_1()
630 ret = edp_train_pattern_set_write(ctrl, in edp_start_link_train_1()
636 old_v_level = ctrl->v_level; in edp_start_link_train_1()
638 drm_dp_link_train_clock_recovery_delay(ctrl->dpcd); in edp_start_link_train_1()
640 rlen = drm_dp_dpcd_read_link_status(ctrl->drm_aux, link_status); in edp_start_link_train_1()
645 if (drm_dp_clock_recovery_ok(link_status, ctrl->lane_cnt)) { in edp_start_link_train_1()
650 if (ctrl->v_level == DPCD_LINK_VOLTAGE_MAX) { in edp_start_link_train_1()
655 if (old_v_level == ctrl->v_level) { in edp_start_link_train_1()
663 old_v_level = ctrl->v_level; in edp_start_link_train_1()
666 edp_sink_train_set_adjust(ctrl, link_status); in edp_start_link_train_1()
667 ret = edp_voltage_pre_emphasise_set(ctrl); in edp_start_link_train_1()
675 static int edp_start_link_train_2(struct edp_ctrl *ctrl) in edp_start_link_train_2() argument
684 edp_host_train_set(ctrl, DP_TRAINING_PATTERN_2); in edp_start_link_train_2()
685 ret = edp_voltage_pre_emphasise_set(ctrl); in edp_start_link_train_2()
689 ret = edp_train_pattern_set_write(ctrl, in edp_start_link_train_2()
695 drm_dp_link_train_channel_eq_delay(ctrl->dpcd); in edp_start_link_train_2()
697 rlen = drm_dp_dpcd_read_link_status(ctrl->drm_aux, link_status); in edp_start_link_train_2()
702 if (drm_dp_channel_eq_ok(link_status, ctrl->lane_cnt)) { in edp_start_link_train_2()
713 edp_sink_train_set_adjust(ctrl, link_status); in edp_start_link_train_2()
714 ret = edp_voltage_pre_emphasise_set(ctrl); in edp_start_link_train_2()
722 static int edp_link_rate_down_shift(struct edp_ctrl *ctrl) in edp_link_rate_down_shift() argument
728 rate = ctrl->link_rate; in edp_link_rate_down_shift()
729 lane = ctrl->lane_cnt; in edp_link_rate_down_shift()
730 max_lane = ctrl->dp_link.num_lanes; in edp_link_rate_down_shift()
732 bpp = ctrl->color_depth * 3; in edp_link_rate_down_shift()
733 prate = ctrl->pixel_rate; in edp_link_rate_down_shift()
753 ctrl->pixel_rate, in edp_link_rate_down_shift()
757 ctrl->link_rate = rate; in edp_link_rate_down_shift()
758 ctrl->lane_cnt = lane; in edp_link_rate_down_shift()
767 static int edp_clear_training_pattern(struct edp_ctrl *ctrl) in edp_clear_training_pattern() argument
771 ret = edp_train_pattern_set_write(ctrl, 0); in edp_clear_training_pattern()
773 drm_dp_link_train_channel_eq_delay(ctrl->dpcd); in edp_clear_training_pattern()
778 static int edp_do_link_train(struct edp_ctrl *ctrl) in edp_do_link_train() argument
788 dp_link.num_lanes = ctrl->lane_cnt; in edp_do_link_train()
789 dp_link.rate = drm_dp_bw_code_to_link_rate(ctrl->link_rate); in edp_do_link_train()
790 dp_link.capabilities = ctrl->dp_link.capabilities; in edp_do_link_train()
791 if (drm_dp_link_configure(ctrl->drm_aux, &dp_link) < 0) in edp_do_link_train()
794 ctrl->v_level = 0; /* start from default level */ in edp_do_link_train()
795 ctrl->p_level = 0; in edp_do_link_train()
797 edp_state_ctrl(ctrl, 0); in edp_do_link_train()
798 if (edp_clear_training_pattern(ctrl)) in edp_do_link_train()
801 ret = edp_start_link_train_1(ctrl); in edp_do_link_train()
803 if (edp_link_rate_down_shift(ctrl) == 0) { in edp_do_link_train()
815 edp_state_ctrl(ctrl, 0); in edp_do_link_train()
816 if (edp_clear_training_pattern(ctrl)) in edp_do_link_train()
819 ret = edp_start_link_train_2(ctrl); in edp_do_link_train()
821 if (edp_link_rate_down_shift(ctrl) == 0) { in edp_do_link_train()
833 edp_state_ctrl(ctrl, EDP_STATE_CTRL_SEND_VIDEO); in edp_do_link_train()
835 edp_clear_training_pattern(ctrl); in edp_do_link_train()
840 static void edp_clock_synchrous(struct edp_ctrl *ctrl, int sync) in edp_clock_synchrous() argument
845 data = edp_read(ctrl->base + REG_EDP_MISC1_MISC0); in edp_clock_synchrous()
854 if (ctrl->color_depth == 8) in edp_clock_synchrous()
856 else if (ctrl->color_depth == 10) in edp_clock_synchrous()
858 else if (ctrl->color_depth == 12) in edp_clock_synchrous()
860 else if (ctrl->color_depth == 16) in edp_clock_synchrous()
865 edp_write(ctrl->base + REG_EDP_MISC1_MISC0, data); in edp_clock_synchrous()
868 static int edp_sw_mvid_nvid(struct edp_ctrl *ctrl, u32 m, u32 n) in edp_sw_mvid_nvid() argument
872 if (ctrl->link_rate == DP_LINK_BW_1_62) { in edp_sw_mvid_nvid()
874 } else if (ctrl->link_rate == DP_LINK_BW_2_7) { in edp_sw_mvid_nvid()
878 ctrl->link_rate); in edp_sw_mvid_nvid()
882 edp_write(ctrl->base + REG_EDP_SOFTWARE_MVID, m * m_multi); in edp_sw_mvid_nvid()
883 edp_write(ctrl->base + REG_EDP_SOFTWARE_NVID, n * n_multi); in edp_sw_mvid_nvid()
888 static void edp_mainlink_ctrl(struct edp_ctrl *ctrl, int enable) in edp_mainlink_ctrl() argument
892 edp_write(ctrl->base + REG_EDP_MAINLINK_CTRL, EDP_MAINLINK_CTRL_RESET); in edp_mainlink_ctrl()
900 edp_write(ctrl->base + REG_EDP_MAINLINK_CTRL, data); in edp_mainlink_ctrl()
903 static void edp_ctrl_phy_aux_enable(struct edp_ctrl *ctrl, int enable) in edp_ctrl_phy_aux_enable() argument
906 edp_regulator_enable(ctrl); in edp_ctrl_phy_aux_enable()
907 edp_clk_enable(ctrl, EDP_CLK_MASK_AUX_CHAN); in edp_ctrl_phy_aux_enable()
908 msm_edp_phy_ctrl(ctrl->phy, 1); in edp_ctrl_phy_aux_enable()
909 msm_edp_aux_ctrl(ctrl->aux, 1); in edp_ctrl_phy_aux_enable()
910 gpiod_set_value(ctrl->panel_en_gpio, 1); in edp_ctrl_phy_aux_enable()
912 gpiod_set_value(ctrl->panel_en_gpio, 0); in edp_ctrl_phy_aux_enable()
913 msm_edp_aux_ctrl(ctrl->aux, 0); in edp_ctrl_phy_aux_enable()
914 msm_edp_phy_ctrl(ctrl->phy, 0); in edp_ctrl_phy_aux_enable()
915 edp_clk_disable(ctrl, EDP_CLK_MASK_AUX_CHAN); in edp_ctrl_phy_aux_enable()
916 edp_regulator_disable(ctrl); in edp_ctrl_phy_aux_enable()
920 static void edp_ctrl_link_enable(struct edp_ctrl *ctrl, int enable) in edp_ctrl_link_enable() argument
926 edp_clk_enable(ctrl, EDP_CLK_MASK_LINK_CHAN); in edp_ctrl_link_enable()
928 msm_edp_phy_lane_power_ctrl(ctrl->phy, true, ctrl->lane_cnt); in edp_ctrl_link_enable()
930 msm_edp_phy_vm_pe_init(ctrl->phy); in edp_ctrl_link_enable()
934 msm_edp_phy_ready(ctrl->phy); in edp_ctrl_link_enable()
936 edp_config_ctrl(ctrl); in edp_ctrl_link_enable()
937 msm_edp_ctrl_pixel_clock_valid(ctrl, ctrl->pixel_rate, &m, &n); in edp_ctrl_link_enable()
938 edp_sw_mvid_nvid(ctrl, m, n); in edp_ctrl_link_enable()
939 edp_mainlink_ctrl(ctrl, 1); in edp_ctrl_link_enable()
941 edp_mainlink_ctrl(ctrl, 0); in edp_ctrl_link_enable()
943 msm_edp_phy_lane_power_ctrl(ctrl->phy, false, 0); in edp_ctrl_link_enable()
944 edp_clk_disable(ctrl, EDP_CLK_MASK_LINK_CHAN); in edp_ctrl_link_enable()
948 static int edp_ctrl_training(struct edp_ctrl *ctrl) in edp_ctrl_training() argument
953 if (!ctrl->power_on) in edp_ctrl_training()
957 ret = edp_do_link_train(ctrl); in edp_ctrl_training()
960 edp_ctrl_irq_enable(ctrl, 0); in edp_ctrl_training()
961 edp_ctrl_link_enable(ctrl, 0); in edp_ctrl_training()
962 msm_edp_phy_ctrl(ctrl->phy, 0); in edp_ctrl_training()
968 msm_edp_phy_ctrl(ctrl->phy, 1); in edp_ctrl_training()
969 edp_ctrl_link_enable(ctrl, 1); in edp_ctrl_training()
970 edp_ctrl_irq_enable(ctrl, 1); in edp_ctrl_training()
979 struct edp_ctrl *ctrl = container_of( in edp_ctrl_on_worker() local
983 mutex_lock(&ctrl->dev_mutex); in edp_ctrl_on_worker()
985 if (ctrl->power_on) { in edp_ctrl_on_worker()
990 edp_ctrl_phy_aux_enable(ctrl, 1); in edp_ctrl_on_worker()
991 edp_ctrl_link_enable(ctrl, 1); in edp_ctrl_on_worker()
993 edp_ctrl_irq_enable(ctrl, 1); in edp_ctrl_on_worker()
994 ret = drm_dp_link_power_up(ctrl->drm_aux, &ctrl->dp_link); in edp_ctrl_on_worker()
998 ctrl->power_on = true; in edp_ctrl_on_worker()
1001 ret = edp_ctrl_training(ctrl); in edp_ctrl_on_worker()
1009 edp_ctrl_irq_enable(ctrl, 0); in edp_ctrl_on_worker()
1010 edp_ctrl_link_enable(ctrl, 0); in edp_ctrl_on_worker()
1011 edp_ctrl_phy_aux_enable(ctrl, 0); in edp_ctrl_on_worker()
1012 ctrl->power_on = false; in edp_ctrl_on_worker()
1014 mutex_unlock(&ctrl->dev_mutex); in edp_ctrl_on_worker()
1019 struct edp_ctrl *ctrl = container_of( in edp_ctrl_off_worker() local
1023 mutex_lock(&ctrl->dev_mutex); in edp_ctrl_off_worker()
1025 if (!ctrl->power_on) { in edp_ctrl_off_worker()
1030 reinit_completion(&ctrl->idle_comp); in edp_ctrl_off_worker()
1031 edp_state_ctrl(ctrl, EDP_STATE_CTRL_PUSH_IDLE); in edp_ctrl_off_worker()
1033 ret = wait_for_completion_timeout(&ctrl->idle_comp, in edp_ctrl_off_worker()
1039 edp_state_ctrl(ctrl, 0); in edp_ctrl_off_worker()
1041 drm_dp_link_power_down(ctrl->drm_aux, &ctrl->dp_link); in edp_ctrl_off_worker()
1043 edp_ctrl_irq_enable(ctrl, 0); in edp_ctrl_off_worker()
1045 edp_ctrl_link_enable(ctrl, 0); in edp_ctrl_off_worker()
1047 edp_ctrl_phy_aux_enable(ctrl, 0); in edp_ctrl_off_worker()
1049 ctrl->power_on = false; in edp_ctrl_off_worker()
1052 mutex_unlock(&ctrl->dev_mutex); in edp_ctrl_off_worker()
1055 irqreturn_t msm_edp_ctrl_irq(struct edp_ctrl *ctrl) in msm_edp_ctrl_irq() argument
1061 spin_lock(&ctrl->irq_lock); in msm_edp_ctrl_irq()
1062 isr1 = edp_read(ctrl->base + REG_EDP_INTERRUPT_REG_1); in msm_edp_ctrl_irq()
1063 isr2 = edp_read(ctrl->base + REG_EDP_INTERRUPT_REG_2); in msm_edp_ctrl_irq()
1077 edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_1, ack); in msm_edp_ctrl_irq()
1082 edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_2, ack); in msm_edp_ctrl_irq()
1083 spin_unlock(&ctrl->irq_lock); in msm_edp_ctrl_irq()
1093 complete(&ctrl->idle_comp); in msm_edp_ctrl_irq()
1096 msm_edp_aux_irq(ctrl->aux, isr1); in msm_edp_ctrl_irq()
1101 void msm_edp_ctrl_power(struct edp_ctrl *ctrl, bool on) in msm_edp_ctrl_power() argument
1104 queue_work(ctrl->workqueue, &ctrl->on_work); in msm_edp_ctrl_power()
1106 queue_work(ctrl->workqueue, &ctrl->off_work); in msm_edp_ctrl_power()
1111 struct edp_ctrl *ctrl = NULL; in msm_edp_ctrl_init() local
1120 ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL); in msm_edp_ctrl_init()
1121 if (!ctrl) in msm_edp_ctrl_init()
1124 edp->ctrl = ctrl; in msm_edp_ctrl_init()
1125 ctrl->pdev = edp->pdev; in msm_edp_ctrl_init()
1127 ctrl->base = msm_ioremap(ctrl->pdev, "edp", "eDP"); in msm_edp_ctrl_init()
1128 if (IS_ERR(ctrl->base)) in msm_edp_ctrl_init()
1129 return PTR_ERR(ctrl->base); in msm_edp_ctrl_init()
1132 ret = edp_regulator_init(ctrl); in msm_edp_ctrl_init()
1137 ret = edp_clk_init(ctrl); in msm_edp_ctrl_init()
1142 ret = edp_gpio_config(ctrl); in msm_edp_ctrl_init()
1149 ctrl->aux = msm_edp_aux_init(dev, ctrl->base, &ctrl->drm_aux); in msm_edp_ctrl_init()
1150 if (!ctrl->aux || !ctrl->drm_aux) { in msm_edp_ctrl_init()
1155 ctrl->phy = msm_edp_phy_init(dev, ctrl->base); in msm_edp_ctrl_init()
1156 if (!ctrl->phy) { in msm_edp_ctrl_init()
1162 spin_lock_init(&ctrl->irq_lock); in msm_edp_ctrl_init()
1163 mutex_init(&ctrl->dev_mutex); in msm_edp_ctrl_init()
1164 init_completion(&ctrl->idle_comp); in msm_edp_ctrl_init()
1167 ctrl->workqueue = alloc_ordered_workqueue("edp_drm_work", 0); in msm_edp_ctrl_init()
1168 INIT_WORK(&ctrl->on_work, edp_ctrl_on_worker); in msm_edp_ctrl_init()
1169 INIT_WORK(&ctrl->off_work, edp_ctrl_off_worker); in msm_edp_ctrl_init()
1174 msm_edp_aux_destroy(dev, ctrl->aux); in msm_edp_ctrl_init()
1175 ctrl->aux = NULL; in msm_edp_ctrl_init()
1179 void msm_edp_ctrl_destroy(struct edp_ctrl *ctrl) in msm_edp_ctrl_destroy() argument
1181 if (!ctrl) in msm_edp_ctrl_destroy()
1184 if (ctrl->workqueue) { in msm_edp_ctrl_destroy()
1185 flush_workqueue(ctrl->workqueue); in msm_edp_ctrl_destroy()
1186 destroy_workqueue(ctrl->workqueue); in msm_edp_ctrl_destroy()
1187 ctrl->workqueue = NULL; in msm_edp_ctrl_destroy()
1190 if (ctrl->aux) { in msm_edp_ctrl_destroy()
1191 msm_edp_aux_destroy(&ctrl->pdev->dev, ctrl->aux); in msm_edp_ctrl_destroy()
1192 ctrl->aux = NULL; in msm_edp_ctrl_destroy()
1195 kfree(ctrl->edid); in msm_edp_ctrl_destroy()
1196 ctrl->edid = NULL; in msm_edp_ctrl_destroy()
1198 mutex_destroy(&ctrl->dev_mutex); in msm_edp_ctrl_destroy()
1201 bool msm_edp_ctrl_panel_connected(struct edp_ctrl *ctrl) in msm_edp_ctrl_panel_connected() argument
1203 mutex_lock(&ctrl->dev_mutex); in msm_edp_ctrl_panel_connected()
1204 DBG("connect status = %d", ctrl->edp_connected); in msm_edp_ctrl_panel_connected()
1205 if (ctrl->edp_connected) { in msm_edp_ctrl_panel_connected()
1206 mutex_unlock(&ctrl->dev_mutex); in msm_edp_ctrl_panel_connected()
1210 if (!ctrl->power_on) { in msm_edp_ctrl_panel_connected()
1211 edp_ctrl_phy_aux_enable(ctrl, 1); in msm_edp_ctrl_panel_connected()
1212 edp_ctrl_irq_enable(ctrl, 1); in msm_edp_ctrl_panel_connected()
1215 if (drm_dp_dpcd_read(ctrl->drm_aux, DP_DPCD_REV, ctrl->dpcd, in msm_edp_ctrl_panel_connected()
1218 memset(ctrl->dpcd, 0, DP_RECEIVER_CAP_SIZE); in msm_edp_ctrl_panel_connected()
1220 ctrl->edp_connected = true; in msm_edp_ctrl_panel_connected()
1223 if (!ctrl->power_on) { in msm_edp_ctrl_panel_connected()
1224 edp_ctrl_irq_enable(ctrl, 0); in msm_edp_ctrl_panel_connected()
1225 edp_ctrl_phy_aux_enable(ctrl, 0); in msm_edp_ctrl_panel_connected()
1228 DBG("exit: connect status=%d", ctrl->edp_connected); in msm_edp_ctrl_panel_connected()
1230 mutex_unlock(&ctrl->dev_mutex); in msm_edp_ctrl_panel_connected()
1232 return ctrl->edp_connected; in msm_edp_ctrl_panel_connected()
1235 int msm_edp_ctrl_get_panel_info(struct edp_ctrl *ctrl, in msm_edp_ctrl_get_panel_info() argument
1240 mutex_lock(&ctrl->dev_mutex); in msm_edp_ctrl_get_panel_info()
1242 if (ctrl->edid) { in msm_edp_ctrl_get_panel_info()
1245 *edid = ctrl->edid; in msm_edp_ctrl_get_panel_info()
1250 if (!ctrl->power_on) { in msm_edp_ctrl_get_panel_info()
1251 edp_ctrl_phy_aux_enable(ctrl, 1); in msm_edp_ctrl_get_panel_info()
1252 edp_ctrl_irq_enable(ctrl, 1); in msm_edp_ctrl_get_panel_info()
1255 ret = drm_dp_link_probe(ctrl->drm_aux, &ctrl->dp_link); in msm_edp_ctrl_get_panel_info()
1262 ctrl->link_rate = drm_dp_link_rate_to_bw_code(ctrl->dp_link.rate); in msm_edp_ctrl_get_panel_info()
1264 ctrl->edid = drm_get_edid(connector, &ctrl->drm_aux->ddc); in msm_edp_ctrl_get_panel_info()
1265 if (!ctrl->edid) { in msm_edp_ctrl_get_panel_info()
1271 *edid = ctrl->edid; in msm_edp_ctrl_get_panel_info()
1274 if (!ctrl->power_on) { in msm_edp_ctrl_get_panel_info()
1275 edp_ctrl_irq_enable(ctrl, 0); in msm_edp_ctrl_get_panel_info()
1276 edp_ctrl_phy_aux_enable(ctrl, 0); in msm_edp_ctrl_get_panel_info()
1279 mutex_unlock(&ctrl->dev_mutex); in msm_edp_ctrl_get_panel_info()
1283 int msm_edp_ctrl_timing_cfg(struct edp_ctrl *ctrl, in msm_edp_ctrl_timing_cfg() argument
1291 mutex_lock(&ctrl->dev_mutex); in msm_edp_ctrl_timing_cfg()
1296 ctrl->color_depth = info->bpc; in msm_edp_ctrl_timing_cfg()
1297 ctrl->pixel_rate = mode->clock; in msm_edp_ctrl_timing_cfg()
1298 ctrl->interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE); in msm_edp_ctrl_timing_cfg()
1301 edp_fill_link_cfg(ctrl); in msm_edp_ctrl_timing_cfg()
1303 if (edp_clk_enable(ctrl, EDP_CLK_MASK_AHB)) { in msm_edp_ctrl_timing_cfg()
1308 edp_clock_synchrous(ctrl, 1); in msm_edp_ctrl_timing_cfg()
1311 edp_write(ctrl->base + REG_EDP_TOTAL_HOR_VER, in msm_edp_ctrl_timing_cfg()
1317 edp_write(ctrl->base + REG_EDP_START_HOR_VER_FROM_SYNC, in msm_edp_ctrl_timing_cfg()
1329 edp_write(ctrl->base + REG_EDP_HSYNC_VSYNC_WIDTH_POLARITY, data); in msm_edp_ctrl_timing_cfg()
1331 edp_write(ctrl->base + REG_EDP_ACTIVE_HOR_VER, in msm_edp_ctrl_timing_cfg()
1335 edp_clk_disable(ctrl, EDP_CLK_MASK_AHB); in msm_edp_ctrl_timing_cfg()
1338 mutex_unlock(&ctrl->dev_mutex); in msm_edp_ctrl_timing_cfg()
1342 bool msm_edp_ctrl_pixel_clock_valid(struct edp_ctrl *ctrl, in msm_edp_ctrl_pixel_clock_valid() argument
1350 if (ctrl->link_rate == DP_LINK_BW_1_62) { in msm_edp_ctrl_pixel_clock_valid()
1352 } else if (ctrl->link_rate == DP_LINK_BW_2_7) { in msm_edp_ctrl_pixel_clock_valid()
1355 pr_err("%s: Invalid link rate,%d\n", __func__, ctrl->link_rate); in msm_edp_ctrl_pixel_clock_valid()