Loading drivers/video/fbdev/msm/mdss_hdmi_tx.c +109 −0 Original line number Diff line number Diff line Loading @@ -120,6 +120,8 @@ static int hdmi_tx_get_audio_edid_blk(struct platform_device *pdev, struct msm_ext_disp_audio_edid_blk *blk); static int hdmi_tx_get_cable_status(struct platform_device *pdev, u32 vote); static int hdmi_tx_update_ppm(struct hdmi_tx_ctrl *hdmi_ctrl, s32 ppm); static int hdmi_tx_enable_pll_update(struct hdmi_tx_ctrl *hdmi_ctrl, int enable); static struct mdss_hw hdmi_tx_hw = { .hw_ndx = MDSS_HW_HDMI, Loading Loading @@ -1368,6 +1370,59 @@ end: return ret; } static ssize_t hdmi_tx_sysfs_rda_pll_enable(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t ret; struct hdmi_tx_ctrl *hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev); if (!hdmi_ctrl) { pr_err("invalid input\n"); return -EINVAL; } mutex_lock(&hdmi_ctrl->tx_lock); ret = snprintf(buf, PAGE_SIZE, "%d\n", hdmi_ctrl->pll_update_enable); pr_debug("HDMI PLL update: %s\n", hdmi_ctrl->pll_update_enable ? "enable" : "disable"); mutex_unlock(&hdmi_ctrl->tx_lock); return ret; } /* hdmi_tx_sysfs_rda_pll_enable */ static ssize_t hdmi_tx_sysfs_wta_pll_enable(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int enable, rc; struct hdmi_tx_ctrl *hdmi_ctrl = NULL; hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev); if (!hdmi_ctrl) { DEV_ERR("%s: invalid input\n", __func__); return -EINVAL; } mutex_lock(&hdmi_ctrl->tx_lock); rc = kstrtoint(buf, 10, &enable); if (rc) { DEV_ERR("%s: kstrtoint failed. rc=%d\n", __func__, rc); goto end; } hdmi_tx_enable_pll_update(hdmi_ctrl, enable); rc = strnlen(buf, PAGE_SIZE); end: mutex_unlock(&hdmi_ctrl->tx_lock); return rc; } /* hdmi_tx_sysfs_wta_pll_enable */ static DEVICE_ATTR(connected, S_IRUGO, hdmi_tx_sysfs_rda_connected, NULL); static DEVICE_ATTR(hot_plug, S_IWUSR, NULL, hdmi_tx_sysfs_wta_hot_plug); static DEVICE_ATTR(sim_mode, S_IRUGO | S_IWUSR, hdmi_tx_sysfs_rda_sim_mode, Loading @@ -1390,6 +1445,9 @@ static DEVICE_ATTR(5v, S_IWUSR, NULL, hdmi_tx_sysfs_wta_5v); static DEVICE_ATTR(hdr_stream, S_IWUSR, NULL, hdmi_tx_sysfs_wta_hdr_stream); static DEVICE_ATTR(hdmi_ppm, S_IRUGO | S_IWUSR, NULL, hdmi_tx_sysfs_wta_hdmi_ppm); static DEVICE_ATTR(pll_enable, S_IRUGO | S_IWUSR, hdmi_tx_sysfs_rda_pll_enable, hdmi_tx_sysfs_wta_pll_enable); static struct attribute *hdmi_tx_fs_attrs[] = { &dev_attr_connected.attr, Loading @@ -1406,6 +1464,7 @@ static struct attribute *hdmi_tx_fs_attrs[] = { &dev_attr_5v.attr, &dev_attr_hdr_stream.attr, &dev_attr_hdmi_ppm.attr, &dev_attr_pll_enable.attr, NULL, }; static struct attribute_group hdmi_tx_fs_attrs_group = { Loading Loading @@ -3628,6 +3687,7 @@ static int hdmi_tx_dev_init(struct hdmi_tx_ctrl *hdmi_ctrl) hdmi_ctrl->hpd_state = false; hdmi_ctrl->hpd_initialized = false; hdmi_ctrl->hpd_off_pending = false; hdmi_ctrl->pll_update_enable = false; init_completion(&hdmi_ctrl->hpd_int_done); INIT_WORK(&hdmi_ctrl->hpd_int_work, hdmi_tx_hpd_int_work); Loading Loading @@ -3801,6 +3861,11 @@ static int hdmi_tx_update_ppm(struct hdmi_tx_ctrl *hdmi_ctrl, s32 ppm) return -EINVAL; } if (!hdmi_ctrl->pll_update_enable) { pr_err("PLL update feature not enabled\n"); return -EINVAL; } /* get current pclk */ cur_pclk = pinfo->clk_rate; /* get desired pclk */ Loading @@ -3824,6 +3889,49 @@ static int hdmi_tx_update_ppm(struct hdmi_tx_ctrl *hdmi_ctrl, s32 ppm) return rc; } static int hdmi_tx_enable_pll_update(struct hdmi_tx_ctrl *hdmi_ctrl, int enable) { struct mdss_panel_info *pinfo = NULL; int rc = 0; if (!hdmi_ctrl) { pr_err("invalid input\n"); return -EINVAL; } /* only available in case HDMI is up */ if (!hdmi_tx_is_panel_on(hdmi_ctrl)) { pr_err("hdmi is not on\n"); return -EINVAL; } enable = !!enable; if (hdmi_ctrl->pll_update_enable == enable) { pr_warn("HDMI PLL update already %s\n", hdmi_ctrl->pll_update_enable ? "enabled" : "disabled"); return -EINVAL; } pinfo = &hdmi_ctrl->panel_data.panel_info; if (!enable && hdmi_ctrl->actual_clk_rate != pinfo->clk_rate) { if (hdmi_ctrl->actual_clk_rate) { /* reset pixel clock when disable */ pinfo->clk_rate = hdmi_ctrl->actual_clk_rate; rc = hdmi_tx_update_pixel_clk(hdmi_ctrl); } } hdmi_ctrl->actual_clk_rate = pinfo->clk_rate; hdmi_ctrl->pll_update_enable = enable; pr_debug("HDMI PLL update: %s\n", hdmi_ctrl->pll_update_enable ? "enable" : "disable"); return rc; } static int hdmi_tx_evt_handle_register(struct hdmi_tx_ctrl *hdmi_ctrl) { int rc = 0; Loading Loading @@ -3996,6 +4104,7 @@ static int hdmi_tx_evt_handle_panel_off(struct hdmi_tx_ctrl *hdmi_ctrl) } hdmi_ctrl->timing_gen_on = false; hdmi_ctrl->pll_update_enable = false; end: return rc; } Loading drivers/video/fbdev/msm/mdss_hdmi_tx.h +3 −0 Original line number Diff line number Diff line Loading @@ -143,6 +143,9 @@ struct hdmi_tx_ctrl { char disp_switch_name[MAX_SWITCH_NAME_SIZE]; u64 actual_clk_rate; bool pll_update_enable; /* pre/post is done in the context without tx_lock */ hdmi_tx_evt_handler pre_evt_handler[MDSS_EVENT_MAX - 1]; hdmi_tx_evt_handler evt_handler[MDSS_EVENT_MAX - 1]; Loading Loading
drivers/video/fbdev/msm/mdss_hdmi_tx.c +109 −0 Original line number Diff line number Diff line Loading @@ -120,6 +120,8 @@ static int hdmi_tx_get_audio_edid_blk(struct platform_device *pdev, struct msm_ext_disp_audio_edid_blk *blk); static int hdmi_tx_get_cable_status(struct platform_device *pdev, u32 vote); static int hdmi_tx_update_ppm(struct hdmi_tx_ctrl *hdmi_ctrl, s32 ppm); static int hdmi_tx_enable_pll_update(struct hdmi_tx_ctrl *hdmi_ctrl, int enable); static struct mdss_hw hdmi_tx_hw = { .hw_ndx = MDSS_HW_HDMI, Loading Loading @@ -1368,6 +1370,59 @@ end: return ret; } static ssize_t hdmi_tx_sysfs_rda_pll_enable(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t ret; struct hdmi_tx_ctrl *hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev); if (!hdmi_ctrl) { pr_err("invalid input\n"); return -EINVAL; } mutex_lock(&hdmi_ctrl->tx_lock); ret = snprintf(buf, PAGE_SIZE, "%d\n", hdmi_ctrl->pll_update_enable); pr_debug("HDMI PLL update: %s\n", hdmi_ctrl->pll_update_enable ? "enable" : "disable"); mutex_unlock(&hdmi_ctrl->tx_lock); return ret; } /* hdmi_tx_sysfs_rda_pll_enable */ static ssize_t hdmi_tx_sysfs_wta_pll_enable(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int enable, rc; struct hdmi_tx_ctrl *hdmi_ctrl = NULL; hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev); if (!hdmi_ctrl) { DEV_ERR("%s: invalid input\n", __func__); return -EINVAL; } mutex_lock(&hdmi_ctrl->tx_lock); rc = kstrtoint(buf, 10, &enable); if (rc) { DEV_ERR("%s: kstrtoint failed. rc=%d\n", __func__, rc); goto end; } hdmi_tx_enable_pll_update(hdmi_ctrl, enable); rc = strnlen(buf, PAGE_SIZE); end: mutex_unlock(&hdmi_ctrl->tx_lock); return rc; } /* hdmi_tx_sysfs_wta_pll_enable */ static DEVICE_ATTR(connected, S_IRUGO, hdmi_tx_sysfs_rda_connected, NULL); static DEVICE_ATTR(hot_plug, S_IWUSR, NULL, hdmi_tx_sysfs_wta_hot_plug); static DEVICE_ATTR(sim_mode, S_IRUGO | S_IWUSR, hdmi_tx_sysfs_rda_sim_mode, Loading @@ -1390,6 +1445,9 @@ static DEVICE_ATTR(5v, S_IWUSR, NULL, hdmi_tx_sysfs_wta_5v); static DEVICE_ATTR(hdr_stream, S_IWUSR, NULL, hdmi_tx_sysfs_wta_hdr_stream); static DEVICE_ATTR(hdmi_ppm, S_IRUGO | S_IWUSR, NULL, hdmi_tx_sysfs_wta_hdmi_ppm); static DEVICE_ATTR(pll_enable, S_IRUGO | S_IWUSR, hdmi_tx_sysfs_rda_pll_enable, hdmi_tx_sysfs_wta_pll_enable); static struct attribute *hdmi_tx_fs_attrs[] = { &dev_attr_connected.attr, Loading @@ -1406,6 +1464,7 @@ static struct attribute *hdmi_tx_fs_attrs[] = { &dev_attr_5v.attr, &dev_attr_hdr_stream.attr, &dev_attr_hdmi_ppm.attr, &dev_attr_pll_enable.attr, NULL, }; static struct attribute_group hdmi_tx_fs_attrs_group = { Loading Loading @@ -3628,6 +3687,7 @@ static int hdmi_tx_dev_init(struct hdmi_tx_ctrl *hdmi_ctrl) hdmi_ctrl->hpd_state = false; hdmi_ctrl->hpd_initialized = false; hdmi_ctrl->hpd_off_pending = false; hdmi_ctrl->pll_update_enable = false; init_completion(&hdmi_ctrl->hpd_int_done); INIT_WORK(&hdmi_ctrl->hpd_int_work, hdmi_tx_hpd_int_work); Loading Loading @@ -3801,6 +3861,11 @@ static int hdmi_tx_update_ppm(struct hdmi_tx_ctrl *hdmi_ctrl, s32 ppm) return -EINVAL; } if (!hdmi_ctrl->pll_update_enable) { pr_err("PLL update feature not enabled\n"); return -EINVAL; } /* get current pclk */ cur_pclk = pinfo->clk_rate; /* get desired pclk */ Loading @@ -3824,6 +3889,49 @@ static int hdmi_tx_update_ppm(struct hdmi_tx_ctrl *hdmi_ctrl, s32 ppm) return rc; } static int hdmi_tx_enable_pll_update(struct hdmi_tx_ctrl *hdmi_ctrl, int enable) { struct mdss_panel_info *pinfo = NULL; int rc = 0; if (!hdmi_ctrl) { pr_err("invalid input\n"); return -EINVAL; } /* only available in case HDMI is up */ if (!hdmi_tx_is_panel_on(hdmi_ctrl)) { pr_err("hdmi is not on\n"); return -EINVAL; } enable = !!enable; if (hdmi_ctrl->pll_update_enable == enable) { pr_warn("HDMI PLL update already %s\n", hdmi_ctrl->pll_update_enable ? "enabled" : "disabled"); return -EINVAL; } pinfo = &hdmi_ctrl->panel_data.panel_info; if (!enable && hdmi_ctrl->actual_clk_rate != pinfo->clk_rate) { if (hdmi_ctrl->actual_clk_rate) { /* reset pixel clock when disable */ pinfo->clk_rate = hdmi_ctrl->actual_clk_rate; rc = hdmi_tx_update_pixel_clk(hdmi_ctrl); } } hdmi_ctrl->actual_clk_rate = pinfo->clk_rate; hdmi_ctrl->pll_update_enable = enable; pr_debug("HDMI PLL update: %s\n", hdmi_ctrl->pll_update_enable ? "enable" : "disable"); return rc; } static int hdmi_tx_evt_handle_register(struct hdmi_tx_ctrl *hdmi_ctrl) { int rc = 0; Loading Loading @@ -3996,6 +4104,7 @@ static int hdmi_tx_evt_handle_panel_off(struct hdmi_tx_ctrl *hdmi_ctrl) } hdmi_ctrl->timing_gen_on = false; hdmi_ctrl->pll_update_enable = false; end: return rc; } Loading
drivers/video/fbdev/msm/mdss_hdmi_tx.h +3 −0 Original line number Diff line number Diff line Loading @@ -143,6 +143,9 @@ struct hdmi_tx_ctrl { char disp_switch_name[MAX_SWITCH_NAME_SIZE]; u64 actual_clk_rate; bool pll_update_enable; /* pre/post is done in the context without tx_lock */ hdmi_tx_evt_handler pre_evt_handler[MDSS_EVENT_MAX - 1]; hdmi_tx_evt_handler evt_handler[MDSS_EVENT_MAX - 1]; Loading