Lines Matching full:ctrl

142 static int edp_clk_init(struct edp_ctrl *ctrl)  in edp_clk_init()  argument
144 struct platform_device *pdev = ctrl->pdev; in edp_clk_init()
147 ctrl->aux_clk = msm_clk_get(pdev, "core"); in edp_clk_init()
148 if (IS_ERR(ctrl->aux_clk)) { in edp_clk_init()
149 ret = PTR_ERR(ctrl->aux_clk); in edp_clk_init()
151 ctrl->aux_clk = NULL; in edp_clk_init()
155 ctrl->pixel_clk = msm_clk_get(pdev, "pixel"); in edp_clk_init()
156 if (IS_ERR(ctrl->pixel_clk)) { in edp_clk_init()
157 ret = PTR_ERR(ctrl->pixel_clk); in edp_clk_init()
159 ctrl->pixel_clk = NULL; in edp_clk_init()
163 ctrl->ahb_clk = msm_clk_get(pdev, "iface"); in edp_clk_init()
164 if (IS_ERR(ctrl->ahb_clk)) { in edp_clk_init()
165 ret = PTR_ERR(ctrl->ahb_clk); in edp_clk_init()
167 ctrl->ahb_clk = NULL; in edp_clk_init()
171 ctrl->link_clk = msm_clk_get(pdev, "link"); in edp_clk_init()
172 if (IS_ERR(ctrl->link_clk)) { in edp_clk_init()
173 ret = PTR_ERR(ctrl->link_clk); in edp_clk_init()
175 ctrl->link_clk = NULL; in edp_clk_init()
180 ctrl->mdp_core_clk = msm_clk_get(pdev, "mdp_core"); in edp_clk_init()
181 if (IS_ERR(ctrl->mdp_core_clk)) { in edp_clk_init()
182 ret = PTR_ERR(ctrl->mdp_core_clk); in edp_clk_init()
184 ctrl->mdp_core_clk = NULL; in edp_clk_init()
191 static int edp_clk_enable(struct edp_ctrl *ctrl, u32 clk_mask) in edp_clk_enable() argument
198 ret = clk_prepare_enable(ctrl->ahb_clk); in edp_clk_enable()
205 ret = clk_set_rate(ctrl->aux_clk, 19200000); in edp_clk_enable()
210 ret = clk_prepare_enable(ctrl->aux_clk); in edp_clk_enable()
219 (unsigned long)ctrl->link_rate * 27000000); in edp_clk_enable()
220 ret = clk_set_rate(ctrl->link_clk, in edp_clk_enable()
221 (unsigned long)ctrl->link_rate * 27000000); in edp_clk_enable()
228 ret = clk_prepare_enable(ctrl->link_clk); in edp_clk_enable()
236 (unsigned long)ctrl->pixel_rate * 1000); in edp_clk_enable()
237 ret = clk_set_rate(ctrl->pixel_clk, in edp_clk_enable()
238 (unsigned long)ctrl->pixel_rate * 1000); in edp_clk_enable()
245 ret = clk_prepare_enable(ctrl->pixel_clk); in edp_clk_enable()
252 ret = clk_prepare_enable(ctrl->mdp_core_clk); in edp_clk_enable()
263 clk_disable_unprepare(ctrl->pixel_clk); in edp_clk_enable()
266 clk_disable_unprepare(ctrl->link_clk); in edp_clk_enable()
269 clk_disable_unprepare(ctrl->aux_clk); in edp_clk_enable()
272 clk_disable_unprepare(ctrl->ahb_clk); in edp_clk_enable()
277 static void edp_clk_disable(struct edp_ctrl *ctrl, u32 clk_mask) in edp_clk_disable() argument
280 clk_disable_unprepare(ctrl->mdp_core_clk); in edp_clk_disable()
282 clk_disable_unprepare(ctrl->pixel_clk); in edp_clk_disable()
284 clk_disable_unprepare(ctrl->link_clk); in edp_clk_disable()
286 clk_disable_unprepare(ctrl->aux_clk); in edp_clk_disable()
288 clk_disable_unprepare(ctrl->ahb_clk); in edp_clk_disable()
291 static int edp_regulator_init(struct edp_ctrl *ctrl) in edp_regulator_init() argument
293 struct device *dev = &ctrl->pdev->dev; in edp_regulator_init()
297 ctrl->vdda_vreg = devm_regulator_get(dev, "vdda"); in edp_regulator_init()
298 ret = PTR_ERR_OR_ZERO(ctrl->vdda_vreg); in edp_regulator_init()
302 ctrl->vdda_vreg = NULL; in edp_regulator_init()
305 ctrl->lvl_vreg = devm_regulator_get(dev, "lvl-vdd"); in edp_regulator_init()
306 ret = PTR_ERR_OR_ZERO(ctrl->lvl_vreg); in edp_regulator_init()
310 ctrl->lvl_vreg = NULL; in edp_regulator_init()
317 static int edp_regulator_enable(struct edp_ctrl *ctrl) in edp_regulator_enable() argument
321 ret = regulator_set_load(ctrl->vdda_vreg, VDDA_UA_ON_LOAD); in edp_regulator_enable()
327 ret = regulator_enable(ctrl->vdda_vreg); in edp_regulator_enable()
333 ret = regulator_enable(ctrl->lvl_vreg); in edp_regulator_enable()
343 regulator_disable(ctrl->vdda_vreg); in edp_regulator_enable()
345 regulator_set_load(ctrl->vdda_vreg, VDDA_UA_OFF_LOAD); in edp_regulator_enable()
350 static void edp_regulator_disable(struct edp_ctrl *ctrl) in edp_regulator_disable() argument
352 regulator_disable(ctrl->lvl_vreg); in edp_regulator_disable()
353 regulator_disable(ctrl->vdda_vreg); in edp_regulator_disable()
354 regulator_set_load(ctrl->vdda_vreg, VDDA_UA_OFF_LOAD); in edp_regulator_disable()
357 static int edp_gpio_config(struct edp_ctrl *ctrl) in edp_gpio_config() argument
359 struct device *dev = &ctrl->pdev->dev; in edp_gpio_config()
362 ctrl->panel_hpd_gpio = devm_gpiod_get(dev, "panel-hpd", GPIOD_IN); in edp_gpio_config()
363 if (IS_ERR(ctrl->panel_hpd_gpio)) { in edp_gpio_config()
364 ret = PTR_ERR(ctrl->panel_hpd_gpio); in edp_gpio_config()
365 ctrl->panel_hpd_gpio = NULL; in edp_gpio_config()
370 ctrl->panel_en_gpio = devm_gpiod_get(dev, "panel-en", GPIOD_OUT_LOW); in edp_gpio_config()
371 if (IS_ERR(ctrl->panel_en_gpio)) { in edp_gpio_config()
372 ret = PTR_ERR(ctrl->panel_en_gpio); in edp_gpio_config()
373 ctrl->panel_en_gpio = NULL; in edp_gpio_config()
383 static void edp_ctrl_irq_enable(struct edp_ctrl *ctrl, int enable) in edp_ctrl_irq_enable() argument
388 spin_lock_irqsave(&ctrl->irq_lock, flags); in edp_ctrl_irq_enable()
390 edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_1, EDP_INTR_MASK1); in edp_ctrl_irq_enable()
391 edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_2, EDP_INTR_MASK2); in edp_ctrl_irq_enable()
393 edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_1, 0x0); in edp_ctrl_irq_enable()
394 edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_2, 0x0); in edp_ctrl_irq_enable()
396 spin_unlock_irqrestore(&ctrl->irq_lock, flags); in edp_ctrl_irq_enable()
400 static void edp_fill_link_cfg(struct edp_ctrl *ctrl) in edp_fill_link_cfg() argument
405 u8 max_lane = drm_dp_max_lane_count(ctrl->dpcd); in edp_fill_link_cfg()
408 prate = ctrl->pixel_rate; in edp_fill_link_cfg()
409 bpp = ctrl->color_depth * 3; in edp_fill_link_cfg()
415 ctrl->link_rate = ctrl->dpcd[DP_MAX_LINK_RATE]; in edp_fill_link_cfg()
421 lrate *= ctrl->link_rate; in edp_fill_link_cfg()
430 ctrl->lane_cnt = lane; in edp_fill_link_cfg()
431 DBG("rate=%d lane=%d", ctrl->link_rate, ctrl->lane_cnt); in edp_fill_link_cfg()
434 static void edp_config_ctrl(struct edp_ctrl *ctrl) in edp_config_ctrl() argument
439 data = EDP_CONFIGURATION_CTRL_LANES(ctrl->lane_cnt - 1); in edp_config_ctrl()
441 if (drm_dp_enhanced_frame_cap(ctrl->dpcd)) in edp_config_ctrl()
445 if (ctrl->color_depth == 8) in edp_config_ctrl()
450 if (!ctrl->interlaced) /* progressive */ in edp_config_ctrl()
456 edp_write(ctrl->base + REG_EDP_CONFIGURATION_CTRL, data); in edp_config_ctrl()
459 static void edp_state_ctrl(struct edp_ctrl *ctrl, u32 state) in edp_state_ctrl() argument
461 edp_write(ctrl->base + REG_EDP_STATE_CTRL, state); in edp_state_ctrl()
466 static int edp_lane_set_write(struct edp_ctrl *ctrl, in edp_lane_set_write() argument
484 if (drm_dp_dpcd_write(ctrl->drm_aux, 0x103, buf, 4) < 4) { in edp_lane_set_write()
492 static int edp_train_pattern_set_write(struct edp_ctrl *ctrl, u8 pattern) in edp_train_pattern_set_write() argument
497 if (drm_dp_dpcd_write(ctrl->drm_aux, in edp_train_pattern_set_write()
506 static void edp_sink_train_set_adjust(struct edp_ctrl *ctrl, in edp_sink_train_set_adjust() argument
514 for (i = 0; i < ctrl->lane_cnt; i++) { in edp_sink_train_set_adjust()
521 ctrl->v_level = max >> DP_TRAIN_VOLTAGE_SWING_SHIFT; in edp_sink_train_set_adjust()
525 for (i = 0; i < ctrl->lane_cnt; i++) { in edp_sink_train_set_adjust()
532 ctrl->p_level = max >> DP_TRAIN_PRE_EMPHASIS_SHIFT; in edp_sink_train_set_adjust()
533 DBG("v_level=%d, p_level=%d", ctrl->v_level, ctrl->p_level); in edp_sink_train_set_adjust()
536 static void edp_host_train_set(struct edp_ctrl *ctrl, u32 train) in edp_host_train_set() argument
544 edp_state_ctrl(ctrl, EDP_STATE_CTRL_TRAIN_PATTERN_1 << shift); in edp_host_train_set()
546 data = edp_read(ctrl->base + REG_EDP_MAINLINK_READY); in edp_host_train_set()
570 static int edp_voltage_pre_emphasise_set(struct edp_ctrl *ctrl) in edp_voltage_pre_emphasise_set() argument
575 DBG("v=%d p=%d", ctrl->v_level, ctrl->p_level); in edp_voltage_pre_emphasise_set()
577 value0 = vm_pre_emphasis[(int)(ctrl->v_level)][(int)(ctrl->p_level)]; in edp_voltage_pre_emphasise_set()
578 value1 = vm_voltage_swing[(int)(ctrl->v_level)][(int)(ctrl->p_level)]; in edp_voltage_pre_emphasise_set()
582 msm_edp_phy_vm_pe_cfg(ctrl->phy, value0, value1); in edp_voltage_pre_emphasise_set()
583 return edp_lane_set_write(ctrl, ctrl->v_level, ctrl->p_level); in edp_voltage_pre_emphasise_set()
589 static int edp_start_link_train_1(struct edp_ctrl *ctrl) in edp_start_link_train_1() argument
599 edp_host_train_set(ctrl, DP_TRAINING_PATTERN_1); in edp_start_link_train_1()
600 ret = edp_voltage_pre_emphasise_set(ctrl); in edp_start_link_train_1()
603 ret = edp_train_pattern_set_write(ctrl, in edp_start_link_train_1()
609 old_v_level = ctrl->v_level; in edp_start_link_train_1()
611 drm_dp_link_train_clock_recovery_delay(ctrl->drm_aux, ctrl->dpcd); in edp_start_link_train_1()
613 rlen = drm_dp_dpcd_read_link_status(ctrl->drm_aux, link_status); in edp_start_link_train_1()
618 if (drm_dp_clock_recovery_ok(link_status, ctrl->lane_cnt)) { in edp_start_link_train_1()
623 if (ctrl->v_level == DPCD_LINK_VOLTAGE_MAX) { in edp_start_link_train_1()
628 if (old_v_level == ctrl->v_level) { in edp_start_link_train_1()
636 old_v_level = ctrl->v_level; in edp_start_link_train_1()
639 edp_sink_train_set_adjust(ctrl, link_status); in edp_start_link_train_1()
640 ret = edp_voltage_pre_emphasise_set(ctrl); in edp_start_link_train_1()
648 static int edp_start_link_train_2(struct edp_ctrl *ctrl) in edp_start_link_train_2() argument
657 edp_host_train_set(ctrl, DP_TRAINING_PATTERN_2); in edp_start_link_train_2()
658 ret = edp_voltage_pre_emphasise_set(ctrl); in edp_start_link_train_2()
662 ret = edp_train_pattern_set_write(ctrl, in edp_start_link_train_2()
668 drm_dp_link_train_channel_eq_delay(ctrl->drm_aux, ctrl->dpcd); in edp_start_link_train_2()
670 rlen = drm_dp_dpcd_read_link_status(ctrl->drm_aux, link_status); in edp_start_link_train_2()
675 if (drm_dp_channel_eq_ok(link_status, ctrl->lane_cnt)) { in edp_start_link_train_2()
686 edp_sink_train_set_adjust(ctrl, link_status); in edp_start_link_train_2()
687 ret = edp_voltage_pre_emphasise_set(ctrl); in edp_start_link_train_2()
695 static int edp_link_rate_down_shift(struct edp_ctrl *ctrl) in edp_link_rate_down_shift() argument
701 rate = ctrl->link_rate; in edp_link_rate_down_shift()
702 lane = ctrl->lane_cnt; in edp_link_rate_down_shift()
703 max_lane = drm_dp_max_lane_count(ctrl->dpcd); in edp_link_rate_down_shift()
705 bpp = ctrl->color_depth * 3; in edp_link_rate_down_shift()
706 prate = ctrl->pixel_rate; in edp_link_rate_down_shift()
726 ctrl->pixel_rate, in edp_link_rate_down_shift()
730 ctrl->link_rate = rate; in edp_link_rate_down_shift()
731 ctrl->lane_cnt = lane; in edp_link_rate_down_shift()
740 static int edp_clear_training_pattern(struct edp_ctrl *ctrl) in edp_clear_training_pattern() argument
744 ret = edp_train_pattern_set_write(ctrl, 0); in edp_clear_training_pattern()
746 drm_dp_link_train_channel_eq_delay(ctrl->drm_aux, ctrl->dpcd); in edp_clear_training_pattern()
751 static int edp_do_link_train(struct edp_ctrl *ctrl) in edp_do_link_train() argument
761 values[0] = ctrl->lane_cnt; in edp_do_link_train()
762 values[1] = ctrl->link_rate; in edp_do_link_train()
764 if (drm_dp_enhanced_frame_cap(ctrl->dpcd)) in edp_do_link_train()
767 if (drm_dp_dpcd_write(ctrl->drm_aux, DP_LINK_BW_SET, values, in edp_do_link_train()
771 ctrl->v_level = 0; /* start from default level */ in edp_do_link_train()
772 ctrl->p_level = 0; in edp_do_link_train()
774 edp_state_ctrl(ctrl, 0); in edp_do_link_train()
775 if (edp_clear_training_pattern(ctrl)) in edp_do_link_train()
778 ret = edp_start_link_train_1(ctrl); in edp_do_link_train()
780 if (edp_link_rate_down_shift(ctrl) == 0) { in edp_do_link_train()
792 edp_state_ctrl(ctrl, 0); in edp_do_link_train()
793 if (edp_clear_training_pattern(ctrl)) in edp_do_link_train()
796 ret = edp_start_link_train_2(ctrl); in edp_do_link_train()
798 if (edp_link_rate_down_shift(ctrl) == 0) { in edp_do_link_train()
810 edp_state_ctrl(ctrl, EDP_STATE_CTRL_SEND_VIDEO); in edp_do_link_train()
812 edp_clear_training_pattern(ctrl); in edp_do_link_train()
817 static void edp_clock_synchrous(struct edp_ctrl *ctrl, int sync) in edp_clock_synchrous() argument
822 data = edp_read(ctrl->base + REG_EDP_MISC1_MISC0); in edp_clock_synchrous()
831 if (ctrl->color_depth == 8) in edp_clock_synchrous()
833 else if (ctrl->color_depth == 10) in edp_clock_synchrous()
835 else if (ctrl->color_depth == 12) in edp_clock_synchrous()
837 else if (ctrl->color_depth == 16) in edp_clock_synchrous()
842 edp_write(ctrl->base + REG_EDP_MISC1_MISC0, data); in edp_clock_synchrous()
845 static int edp_sw_mvid_nvid(struct edp_ctrl *ctrl, u32 m, u32 n) in edp_sw_mvid_nvid() argument
849 if (ctrl->link_rate == DP_LINK_BW_1_62) { in edp_sw_mvid_nvid()
851 } else if (ctrl->link_rate == DP_LINK_BW_2_7) { in edp_sw_mvid_nvid()
855 ctrl->link_rate); in edp_sw_mvid_nvid()
859 edp_write(ctrl->base + REG_EDP_SOFTWARE_MVID, m * m_multi); in edp_sw_mvid_nvid()
860 edp_write(ctrl->base + REG_EDP_SOFTWARE_NVID, n * n_multi); in edp_sw_mvid_nvid()
865 static void edp_mainlink_ctrl(struct edp_ctrl *ctrl, int enable) in edp_mainlink_ctrl() argument
869 edp_write(ctrl->base + REG_EDP_MAINLINK_CTRL, EDP_MAINLINK_CTRL_RESET); in edp_mainlink_ctrl()
877 edp_write(ctrl->base + REG_EDP_MAINLINK_CTRL, data); in edp_mainlink_ctrl()
880 static void edp_ctrl_phy_aux_enable(struct edp_ctrl *ctrl, int enable) in edp_ctrl_phy_aux_enable() argument
883 edp_regulator_enable(ctrl); in edp_ctrl_phy_aux_enable()
884 edp_clk_enable(ctrl, EDP_CLK_MASK_AUX_CHAN); in edp_ctrl_phy_aux_enable()
885 msm_edp_phy_ctrl(ctrl->phy, 1); in edp_ctrl_phy_aux_enable()
886 msm_edp_aux_ctrl(ctrl->aux, 1); in edp_ctrl_phy_aux_enable()
887 gpiod_set_value(ctrl->panel_en_gpio, 1); in edp_ctrl_phy_aux_enable()
889 gpiod_set_value(ctrl->panel_en_gpio, 0); in edp_ctrl_phy_aux_enable()
890 msm_edp_aux_ctrl(ctrl->aux, 0); in edp_ctrl_phy_aux_enable()
891 msm_edp_phy_ctrl(ctrl->phy, 0); in edp_ctrl_phy_aux_enable()
892 edp_clk_disable(ctrl, EDP_CLK_MASK_AUX_CHAN); in edp_ctrl_phy_aux_enable()
893 edp_regulator_disable(ctrl); in edp_ctrl_phy_aux_enable()
897 static void edp_ctrl_link_enable(struct edp_ctrl *ctrl, int enable) in edp_ctrl_link_enable() argument
903 edp_clk_enable(ctrl, EDP_CLK_MASK_LINK_CHAN); in edp_ctrl_link_enable()
905 msm_edp_phy_lane_power_ctrl(ctrl->phy, true, ctrl->lane_cnt); in edp_ctrl_link_enable()
907 msm_edp_phy_vm_pe_init(ctrl->phy); in edp_ctrl_link_enable()
911 msm_edp_phy_ready(ctrl->phy); in edp_ctrl_link_enable()
913 edp_config_ctrl(ctrl); in edp_ctrl_link_enable()
914 msm_edp_ctrl_pixel_clock_valid(ctrl, ctrl->pixel_rate, &m, &n); in edp_ctrl_link_enable()
915 edp_sw_mvid_nvid(ctrl, m, n); in edp_ctrl_link_enable()
916 edp_mainlink_ctrl(ctrl, 1); in edp_ctrl_link_enable()
918 edp_mainlink_ctrl(ctrl, 0); in edp_ctrl_link_enable()
920 msm_edp_phy_lane_power_ctrl(ctrl->phy, false, 0); in edp_ctrl_link_enable()
921 edp_clk_disable(ctrl, EDP_CLK_MASK_LINK_CHAN); in edp_ctrl_link_enable()
925 static int edp_ctrl_training(struct edp_ctrl *ctrl) in edp_ctrl_training() argument
930 if (!ctrl->power_on) in edp_ctrl_training()
934 ret = edp_do_link_train(ctrl); in edp_ctrl_training()
937 edp_ctrl_irq_enable(ctrl, 0); in edp_ctrl_training()
938 edp_ctrl_link_enable(ctrl, 0); in edp_ctrl_training()
939 msm_edp_phy_ctrl(ctrl->phy, 0); in edp_ctrl_training()
945 msm_edp_phy_ctrl(ctrl->phy, 1); in edp_ctrl_training()
946 edp_ctrl_link_enable(ctrl, 1); in edp_ctrl_training()
947 edp_ctrl_irq_enable(ctrl, 1); in edp_ctrl_training()
956 struct edp_ctrl *ctrl = container_of( in edp_ctrl_on_worker() local
961 mutex_lock(&ctrl->dev_mutex); in edp_ctrl_on_worker()
963 if (ctrl->power_on) { in edp_ctrl_on_worker()
968 edp_ctrl_phy_aux_enable(ctrl, 1); in edp_ctrl_on_worker()
969 edp_ctrl_link_enable(ctrl, 1); in edp_ctrl_on_worker()
971 edp_ctrl_irq_enable(ctrl, 1); in edp_ctrl_on_worker()
974 if (ctrl->dpcd[DP_DPCD_REV] >= 0x11) { in edp_ctrl_on_worker()
975 ret = drm_dp_dpcd_readb(ctrl->drm_aux, DP_SET_POWER, &value); in edp_ctrl_on_worker()
982 ret = drm_dp_dpcd_writeb(ctrl->drm_aux, DP_SET_POWER, value); in edp_ctrl_on_worker()
994 ctrl->power_on = true; in edp_ctrl_on_worker()
997 ret = edp_ctrl_training(ctrl); in edp_ctrl_on_worker()
1005 edp_ctrl_irq_enable(ctrl, 0); in edp_ctrl_on_worker()
1006 edp_ctrl_link_enable(ctrl, 0); in edp_ctrl_on_worker()
1007 edp_ctrl_phy_aux_enable(ctrl, 0); in edp_ctrl_on_worker()
1008 ctrl->power_on = false; in edp_ctrl_on_worker()
1010 mutex_unlock(&ctrl->dev_mutex); in edp_ctrl_on_worker()
1015 struct edp_ctrl *ctrl = container_of( in edp_ctrl_off_worker() local
1019 mutex_lock(&ctrl->dev_mutex); in edp_ctrl_off_worker()
1021 if (!ctrl->power_on) { in edp_ctrl_off_worker()
1026 reinit_completion(&ctrl->idle_comp); in edp_ctrl_off_worker()
1027 edp_state_ctrl(ctrl, EDP_STATE_CTRL_PUSH_IDLE); in edp_ctrl_off_worker()
1029 time_left = wait_for_completion_timeout(&ctrl->idle_comp, in edp_ctrl_off_worker()
1034 edp_state_ctrl(ctrl, 0); in edp_ctrl_off_worker()
1037 if (ctrl->dpcd[DP_DPCD_REV] >= 0x11) { in edp_ctrl_off_worker()
1041 ret = drm_dp_dpcd_readb(ctrl->drm_aux, DP_SET_POWER, &value); in edp_ctrl_off_worker()
1046 drm_dp_dpcd_writeb(ctrl->drm_aux, DP_SET_POWER, value); in edp_ctrl_off_worker()
1050 edp_ctrl_irq_enable(ctrl, 0); in edp_ctrl_off_worker()
1052 edp_ctrl_link_enable(ctrl, 0); in edp_ctrl_off_worker()
1054 edp_ctrl_phy_aux_enable(ctrl, 0); in edp_ctrl_off_worker()
1056 ctrl->power_on = false; in edp_ctrl_off_worker()
1059 mutex_unlock(&ctrl->dev_mutex); in edp_ctrl_off_worker()
1062 irqreturn_t msm_edp_ctrl_irq(struct edp_ctrl *ctrl) in msm_edp_ctrl_irq() argument
1068 spin_lock(&ctrl->irq_lock); in msm_edp_ctrl_irq()
1069 isr1 = edp_read(ctrl->base + REG_EDP_INTERRUPT_REG_1); in msm_edp_ctrl_irq()
1070 isr2 = edp_read(ctrl->base + REG_EDP_INTERRUPT_REG_2); in msm_edp_ctrl_irq()
1084 edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_1, ack); in msm_edp_ctrl_irq()
1089 edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_2, ack); in msm_edp_ctrl_irq()
1090 spin_unlock(&ctrl->irq_lock); in msm_edp_ctrl_irq()
1100 complete(&ctrl->idle_comp); in msm_edp_ctrl_irq()
1103 msm_edp_aux_irq(ctrl->aux, isr1); in msm_edp_ctrl_irq()
1108 void msm_edp_ctrl_power(struct edp_ctrl *ctrl, bool on) in msm_edp_ctrl_power() argument
1111 queue_work(ctrl->workqueue, &ctrl->on_work); in msm_edp_ctrl_power()
1113 queue_work(ctrl->workqueue, &ctrl->off_work); in msm_edp_ctrl_power()
1118 struct edp_ctrl *ctrl = NULL; in msm_edp_ctrl_init() local
1128 ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL); in msm_edp_ctrl_init()
1129 if (!ctrl) in msm_edp_ctrl_init()
1132 edp->ctrl = ctrl; in msm_edp_ctrl_init()
1133 ctrl->pdev = edp->pdev; in msm_edp_ctrl_init()
1135 ctrl->base = msm_ioremap(ctrl->pdev, "edp", "eDP"); in msm_edp_ctrl_init()
1136 if (IS_ERR(ctrl->base)) in msm_edp_ctrl_init()
1137 return PTR_ERR(ctrl->base); in msm_edp_ctrl_init()
1140 ret = edp_regulator_init(ctrl); in msm_edp_ctrl_init()
1145 ret = edp_clk_init(ctrl); in msm_edp_ctrl_init()
1150 ret = edp_gpio_config(ctrl); in msm_edp_ctrl_init()
1157 ctrl->aux = msm_edp_aux_init(edp, ctrl->base, &ctrl->drm_aux); in msm_edp_ctrl_init()
1158 if (!ctrl->aux || !ctrl->drm_aux) { in msm_edp_ctrl_init()
1163 ctrl->phy = msm_edp_phy_init(dev, ctrl->base); in msm_edp_ctrl_init()
1164 if (!ctrl->phy) { in msm_edp_ctrl_init()
1170 spin_lock_init(&ctrl->irq_lock); in msm_edp_ctrl_init()
1171 mutex_init(&ctrl->dev_mutex); in msm_edp_ctrl_init()
1172 init_completion(&ctrl->idle_comp); in msm_edp_ctrl_init()
1175 ctrl->workqueue = alloc_ordered_workqueue("edp_drm_work", 0); in msm_edp_ctrl_init()
1176 INIT_WORK(&ctrl->on_work, edp_ctrl_on_worker); in msm_edp_ctrl_init()
1177 INIT_WORK(&ctrl->off_work, edp_ctrl_off_worker); in msm_edp_ctrl_init()
1182 msm_edp_aux_destroy(dev, ctrl->aux); in msm_edp_ctrl_init()
1183 ctrl->aux = NULL; in msm_edp_ctrl_init()
1187 void msm_edp_ctrl_destroy(struct edp_ctrl *ctrl) in msm_edp_ctrl_destroy() argument
1189 if (!ctrl) in msm_edp_ctrl_destroy()
1192 if (ctrl->workqueue) { in msm_edp_ctrl_destroy()
1193 flush_workqueue(ctrl->workqueue); in msm_edp_ctrl_destroy()
1194 destroy_workqueue(ctrl->workqueue); in msm_edp_ctrl_destroy()
1195 ctrl->workqueue = NULL; in msm_edp_ctrl_destroy()
1198 if (ctrl->aux) { in msm_edp_ctrl_destroy()
1199 msm_edp_aux_destroy(&ctrl->pdev->dev, ctrl->aux); in msm_edp_ctrl_destroy()
1200 ctrl->aux = NULL; in msm_edp_ctrl_destroy()
1203 kfree(ctrl->edid); in msm_edp_ctrl_destroy()
1204 ctrl->edid = NULL; in msm_edp_ctrl_destroy()
1206 mutex_destroy(&ctrl->dev_mutex); in msm_edp_ctrl_destroy()
1209 bool msm_edp_ctrl_panel_connected(struct edp_ctrl *ctrl) in msm_edp_ctrl_panel_connected() argument
1211 mutex_lock(&ctrl->dev_mutex); in msm_edp_ctrl_panel_connected()
1212 DBG("connect status = %d", ctrl->edp_connected); in msm_edp_ctrl_panel_connected()
1213 if (ctrl->edp_connected) { in msm_edp_ctrl_panel_connected()
1214 mutex_unlock(&ctrl->dev_mutex); in msm_edp_ctrl_panel_connected()
1218 if (!ctrl->power_on) { in msm_edp_ctrl_panel_connected()
1219 edp_ctrl_phy_aux_enable(ctrl, 1); in msm_edp_ctrl_panel_connected()
1220 edp_ctrl_irq_enable(ctrl, 1); in msm_edp_ctrl_panel_connected()
1223 if (drm_dp_dpcd_read(ctrl->drm_aux, DP_DPCD_REV, ctrl->dpcd, in msm_edp_ctrl_panel_connected()
1226 memset(ctrl->dpcd, 0, DP_RECEIVER_CAP_SIZE); in msm_edp_ctrl_panel_connected()
1228 ctrl->edp_connected = true; in msm_edp_ctrl_panel_connected()
1231 if (!ctrl->power_on) { in msm_edp_ctrl_panel_connected()
1232 edp_ctrl_irq_enable(ctrl, 0); in msm_edp_ctrl_panel_connected()
1233 edp_ctrl_phy_aux_enable(ctrl, 0); in msm_edp_ctrl_panel_connected()
1236 DBG("exit: connect status=%d", ctrl->edp_connected); in msm_edp_ctrl_panel_connected()
1238 mutex_unlock(&ctrl->dev_mutex); in msm_edp_ctrl_panel_connected()
1240 return ctrl->edp_connected; in msm_edp_ctrl_panel_connected()
1243 int msm_edp_ctrl_get_panel_info(struct edp_ctrl *ctrl, in msm_edp_ctrl_get_panel_info() argument
1248 mutex_lock(&ctrl->dev_mutex); in msm_edp_ctrl_get_panel_info()
1250 if (ctrl->edid) { in msm_edp_ctrl_get_panel_info()
1253 *edid = ctrl->edid; in msm_edp_ctrl_get_panel_info()
1258 if (!ctrl->power_on) { in msm_edp_ctrl_get_panel_info()
1259 edp_ctrl_phy_aux_enable(ctrl, 1); in msm_edp_ctrl_get_panel_info()
1260 edp_ctrl_irq_enable(ctrl, 1); in msm_edp_ctrl_get_panel_info()
1264 ctrl->link_rate = ctrl->dpcd[DP_MAX_LINK_RATE]; in msm_edp_ctrl_get_panel_info()
1266 ctrl->edid = drm_get_edid(connector, &ctrl->drm_aux->ddc); in msm_edp_ctrl_get_panel_info()
1267 if (!ctrl->edid) { in msm_edp_ctrl_get_panel_info()
1273 *edid = ctrl->edid; in msm_edp_ctrl_get_panel_info()
1276 if (!ctrl->power_on) { in msm_edp_ctrl_get_panel_info()
1277 edp_ctrl_irq_enable(ctrl, 0); in msm_edp_ctrl_get_panel_info()
1278 edp_ctrl_phy_aux_enable(ctrl, 0); in msm_edp_ctrl_get_panel_info()
1281 mutex_unlock(&ctrl->dev_mutex); in msm_edp_ctrl_get_panel_info()
1285 int msm_edp_ctrl_timing_cfg(struct edp_ctrl *ctrl, in msm_edp_ctrl_timing_cfg() argument
1293 mutex_lock(&ctrl->dev_mutex); in msm_edp_ctrl_timing_cfg()
1296 * interlaced information in ctrl context in msm_edp_ctrl_timing_cfg()
1298 ctrl->color_depth = info->bpc; in msm_edp_ctrl_timing_cfg()
1299 ctrl->pixel_rate = mode->clock; in msm_edp_ctrl_timing_cfg()
1300 ctrl->interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE); in msm_edp_ctrl_timing_cfg()
1303 edp_fill_link_cfg(ctrl); in msm_edp_ctrl_timing_cfg()
1305 if (edp_clk_enable(ctrl, EDP_CLK_MASK_AHB)) { in msm_edp_ctrl_timing_cfg()
1310 edp_clock_synchrous(ctrl, 1); in msm_edp_ctrl_timing_cfg()
1313 edp_write(ctrl->base + REG_EDP_TOTAL_HOR_VER, in msm_edp_ctrl_timing_cfg()
1319 edp_write(ctrl->base + REG_EDP_START_HOR_VER_FROM_SYNC, in msm_edp_ctrl_timing_cfg()
1331 edp_write(ctrl->base + REG_EDP_HSYNC_VSYNC_WIDTH_POLARITY, data); in msm_edp_ctrl_timing_cfg()
1333 edp_write(ctrl->base + REG_EDP_ACTIVE_HOR_VER, in msm_edp_ctrl_timing_cfg()
1337 edp_clk_disable(ctrl, EDP_CLK_MASK_AHB); in msm_edp_ctrl_timing_cfg()
1340 mutex_unlock(&ctrl->dev_mutex); in msm_edp_ctrl_timing_cfg()
1344 bool msm_edp_ctrl_pixel_clock_valid(struct edp_ctrl *ctrl, in msm_edp_ctrl_pixel_clock_valid() argument
1352 if (ctrl->link_rate == DP_LINK_BW_1_62) { in msm_edp_ctrl_pixel_clock_valid()
1354 } else if (ctrl->link_rate == DP_LINK_BW_2_7) { in msm_edp_ctrl_pixel_clock_valid()
1357 pr_err("%s: Invalid link rate,%d\n", __func__, ctrl->link_rate); in msm_edp_ctrl_pixel_clock_valid()