msm: mdss: make hdcp 1.x data part of fb panel

hdcp 1.x can be used by different interfaces attached to
different frame buffers. Add hdcp 1.x data to the panel
specific data so that hdcp 1.x module can access the
corresponding data.

Change-Id: I19917582aa1a52b11eb04e2031403c09bc0aba9b
CRs-Fixed: 1050304
Signed-off-by: Tatenda Chipeperekwa <tatendac@codeaurora.org>
This commit is contained in:
Tatenda Chipeperekwa 2016-09-08 13:51:04 -07:00
parent 16e3ac406c
commit f0b8cc9283
8 changed files with 118 additions and 84 deletions

View file

@ -1394,6 +1394,8 @@ static int mdss_dp_hdcp_init(struct mdss_panel_data *pdata)
goto error; goto error;
} }
dp_drv->panel_data.panel_info.hdcp_1x_data = dp_drv->hdcp_data;
pr_debug("HDCP 1.3 initialized\n"); pr_debug("HDCP 1.3 initialized\n");
dp_drv->hdcp_ops = hdcp_1x_start(dp_drv->hdcp_data); dp_drv->hdcp_ops = hdcp_1x_start(dp_drv->hdcp_data);

View file

@ -19,6 +19,7 @@
#include <soc/qcom/scm.h> #include <soc/qcom/scm.h>
#include <linux/hdcp_qseecom.h> #include <linux/hdcp_qseecom.h>
#include "mdss_hdcp_1x.h" #include "mdss_hdcp_1x.h"
#include "mdss_fb.h"
#include "mdss_dp_util.h" #include "mdss_dp_util.h"
#include "video/msm_hdmi_hdcp_mgr.h" #include "video/msm_hdmi_hdcp_mgr.h"
@ -1630,12 +1631,45 @@ error:
return rc; return rc;
} /* hdcp_1x_isr */ } /* hdcp_1x_isr */
static struct hdcp_1x_ctrl *hdcp_1x_get_ctrl(struct device *dev)
{
struct fb_info *fbi;
struct msm_fb_data_type *mfd;
struct mdss_panel_info *pinfo;
if (!dev) {
pr_err("invalid input\n");
goto error;
}
fbi = dev_get_drvdata(dev);
if (!fbi) {
pr_err("invalid fbi\n");
goto error;
}
mfd = fbi->par;
if (!mfd) {
pr_err("invalid mfd\n");
goto error;
}
pinfo = mfd->panel_info;
if (!pinfo) {
pr_err("invalid pinfo\n");
goto error;
}
return pinfo->hdcp_1x_data;
error:
return NULL;
}
static ssize_t hdcp_1x_sysfs_rda_status(struct device *dev, static ssize_t hdcp_1x_sysfs_rda_status(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
ssize_t ret; ssize_t ret;
struct hdcp_1x_ctrl *hdcp_ctrl = struct hdcp_1x_ctrl *hdcp_ctrl = hdcp_1x_get_ctrl(dev);
hdmi_get_featuredata_from_sysfs_dev(dev, HDMI_TX_FEAT_HDCP);
if (!hdcp_ctrl) { if (!hdcp_ctrl) {
DEV_ERR("%s: invalid input\n", __func__); DEV_ERR("%s: invalid input\n", __func__);
@ -1654,8 +1688,7 @@ static ssize_t hdcp_1x_sysfs_rda_tp(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
ssize_t ret = 0; ssize_t ret = 0;
struct hdcp_1x_ctrl *hdcp_ctrl = struct hdcp_1x_ctrl *hdcp_ctrl = hdcp_1x_get_ctrl(dev);
hdmi_get_featuredata_from_sysfs_dev(dev, HDMI_TX_FEAT_HDCP);
if (!hdcp_ctrl) { if (!hdcp_ctrl) {
DEV_ERR("%s: invalid input\n", __func__); DEV_ERR("%s: invalid input\n", __func__);
@ -1689,8 +1722,7 @@ static ssize_t hdcp_1x_sysfs_wta_tp(struct device *dev,
{ {
int msgid = 0; int msgid = 0;
ssize_t ret = count; ssize_t ret = count;
struct hdcp_1x_ctrl *hdcp_ctrl = struct hdcp_1x_ctrl *hdcp_ctrl = hdcp_1x_get_ctrl(dev);
hdmi_get_featuredata_from_sysfs_dev(dev, HDMI_TX_FEAT_HDCP);
if (!hdcp_ctrl || !buf) { if (!hdcp_ctrl || !buf) {
DEV_ERR("%s: invalid input\n", __func__); DEV_ERR("%s: invalid input\n", __func__);

View file

@ -150,74 +150,6 @@ enum hdmi_scaling_info {
HDMI_SCALING_HORZ_VERT, HDMI_SCALING_HORZ_VERT,
}; };
int hdmi_panel_get_vic(struct mdss_panel_info *pinfo,
struct hdmi_util_ds_data *ds_data)
{
int new_vic = -1;
u32 h_total, v_total;
struct msm_hdmi_mode_timing_info timing;
if (!pinfo) {
pr_err("invalid panel data\n");
return -EINVAL;
}
if (pinfo->vic) {
struct msm_hdmi_mode_timing_info info = {0};
u32 ret = hdmi_get_supported_mode(&info, ds_data, pinfo->vic);
u32 supported = info.supported;
if (!ret && supported) {
new_vic = pinfo->vic;
} else {
pr_err("invalid or not supported vic %d\n",
pinfo->vic);
return -EPERM;
}
} else {
timing.active_h = pinfo->xres;
timing.back_porch_h = pinfo->lcdc.h_back_porch;
timing.front_porch_h = pinfo->lcdc.h_front_porch;
timing.pulse_width_h = pinfo->lcdc.h_pulse_width;
h_total = timing.active_h + timing.back_porch_h +
timing.front_porch_h + timing.pulse_width_h;
pr_debug("ah=%d bph=%d fph=%d pwh=%d ht=%d\n",
timing.active_h, timing.back_porch_h,
timing.front_porch_h, timing.pulse_width_h,
h_total);
timing.active_v = pinfo->yres;
timing.back_porch_v = pinfo->lcdc.v_back_porch;
timing.front_porch_v = pinfo->lcdc.v_front_porch;
timing.pulse_width_v = pinfo->lcdc.v_pulse_width;
v_total = timing.active_v + timing.back_porch_v +
timing.front_porch_v + timing.pulse_width_v;
pr_debug("av=%d bpv=%d fpv=%d pwv=%d vt=%d\n",
timing.active_v, timing.back_porch_v,
timing.front_porch_v, timing.pulse_width_v, v_total);
timing.pixel_freq = ((unsigned long int)pinfo->clk_rate / 1000);
if (h_total && v_total) {
timing.refresh_rate = ((timing.pixel_freq * 1000) /
(h_total * v_total)) * 1000;
} else {
pr_err("cannot cal refresh rate\n");
return -EPERM;
}
pr_debug("pixel_freq=%d refresh_rate=%d\n",
timing.pixel_freq, timing.refresh_rate);
new_vic = hdmi_get_video_id_code(&timing, ds_data);
}
return new_vic;
}
static void hdmi_panel_update_dfps_data(struct hdmi_panel *panel) static void hdmi_panel_update_dfps_data(struct hdmi_panel *panel)
{ {
struct mdss_panel_info *pinfo = panel->data->pinfo; struct mdss_panel_info *pinfo = panel->data->pinfo;
@ -916,7 +848,6 @@ void *hdmi_panel_init(struct hdmi_panel_init_data *data)
if (data->ops) { if (data->ops) {
data->ops->on = hdmi_panel_power_on; data->ops->on = hdmi_panel_power_on;
data->ops->off = hdmi_panel_power_off; data->ops->off = hdmi_panel_power_off;
data->ops->get_vic = hdmi_panel_get_vic;
data->ops->vendor = hdmi_panel_set_vendor_specific_infoframe; data->ops->vendor = hdmi_panel_set_vendor_specific_infoframe;
data->ops->update_fps = hdmi_panel_update_fps; data->ops->update_fps = hdmi_panel_update_fps;
} }

View file

@ -48,15 +48,12 @@ struct hdmi_panel_data {
* @off: pointer to a function which powers off the panel * @off: pointer to a function which powers off the panel
* @vendor: pointer to a function which programs vendor specific infoframe * @vendor: pointer to a function which programs vendor specific infoframe
* @update_fps: pointer to a function which updates fps * @update_fps: pointer to a function which updates fps
* @get_vic: pointer to a function which get the vic from panel information.
*/ */
struct hdmi_panel_ops { struct hdmi_panel_ops {
int (*on)(void *input); int (*on)(void *input);
int (*off)(void *input); int (*off)(void *input);
void (*vendor)(void *input); void (*vendor)(void *input);
int (*update_fps)(void *input, u32 fps); int (*update_fps)(void *input, u32 fps);
int (*get_vic)(struct mdss_panel_info *pinfo,
struct hdmi_util_ds_data *ds_data);
}; };
/** /**

View file

@ -1814,6 +1814,8 @@ static int hdmi_tx_init_hdcp(struct hdmi_tx_ctrl *hdmi_ctrl)
goto end; goto end;
} else { } else {
hdmi_tx_set_fd(HDMI_TX_FEAT_HDCP, hdcp_data); hdmi_tx_set_fd(HDMI_TX_FEAT_HDCP, hdcp_data);
hdmi_ctrl->panel_data.panel_info.hdcp_1x_data =
hdcp_data;
DEV_DBG("%s: HDCP 1.4 initialized\n", __func__); DEV_DBG("%s: HDCP 1.4 initialized\n", __func__);
} }
} }
@ -3115,9 +3117,8 @@ static int hdmi_tx_power_on(struct hdmi_tx_ctrl *hdmi_ctrl)
void *pdata = hdmi_tx_get_fd(HDMI_TX_FEAT_PANEL); void *pdata = hdmi_tx_get_fd(HDMI_TX_FEAT_PANEL);
void *edata = hdmi_tx_get_fd(HDMI_TX_FEAT_EDID); void *edata = hdmi_tx_get_fd(HDMI_TX_FEAT_EDID);
if (hdmi_ctrl->panel_ops.get_vic) hdmi_panel_get_vic(&panel_data->panel_info,
hdmi_ctrl->vic = hdmi_ctrl->panel_ops.get_vic( &hdmi_ctrl->ds_data);
&panel_data->panel_info, &hdmi_ctrl->ds_data);
if (hdmi_ctrl->vic <= 0) { if (hdmi_ctrl->vic <= 0) {
DEV_ERR("%s: invalid vic\n", __func__); DEV_ERR("%s: invalid vic\n", __func__);
@ -3703,9 +3704,7 @@ static int hdmi_tx_evt_handle_check_param(struct hdmi_tx_ctrl *hdmi_ctrl)
int new_vic = -1; int new_vic = -1;
int rc = 0; int rc = 0;
if (hdmi_ctrl->panel_ops.get_vic) new_vic = hdmi_panel_get_vic(hdmi_ctrl->evt_arg, &hdmi_ctrl->ds_data);
new_vic = hdmi_ctrl->panel_ops.get_vic(
hdmi_ctrl->evt_arg, &hdmi_ctrl->ds_data);
if ((new_vic < 0) || (new_vic > HDMI_VFRMT_MAX)) { if ((new_vic < 0) || (new_vic > HDMI_VFRMT_MAX)) {
DEV_ERR("%s: invalid or not supported vic\n", __func__); DEV_ERR("%s: invalid or not supported vic\n", __func__);

View file

@ -33,6 +33,74 @@ enum trigger_mode {
TRIGGER_READ TRIGGER_READ
}; };
int hdmi_panel_get_vic(struct mdss_panel_info *pinfo,
struct hdmi_util_ds_data *ds_data)
{
int new_vic = -1;
u32 h_total, v_total;
struct msm_hdmi_mode_timing_info timing;
if (!pinfo) {
pr_err("invalid panel data\n");
return -EINVAL;
}
if (pinfo->vic) {
struct msm_hdmi_mode_timing_info info = {0};
u32 ret = hdmi_get_supported_mode(&info, ds_data, pinfo->vic);
u32 supported = info.supported;
if (!ret && supported) {
new_vic = pinfo->vic;
} else {
pr_err("invalid or not supported vic %d\n",
pinfo->vic);
return -EPERM;
}
} else {
timing.active_h = pinfo->xres;
timing.back_porch_h = pinfo->lcdc.h_back_porch;
timing.front_porch_h = pinfo->lcdc.h_front_porch;
timing.pulse_width_h = pinfo->lcdc.h_pulse_width;
h_total = timing.active_h + timing.back_porch_h +
timing.front_porch_h + timing.pulse_width_h;
pr_debug("ah=%d bph=%d fph=%d pwh=%d ht=%d\n",
timing.active_h, timing.back_porch_h,
timing.front_porch_h, timing.pulse_width_h,
h_total);
timing.active_v = pinfo->yres;
timing.back_porch_v = pinfo->lcdc.v_back_porch;
timing.front_porch_v = pinfo->lcdc.v_front_porch;
timing.pulse_width_v = pinfo->lcdc.v_pulse_width;
v_total = timing.active_v + timing.back_porch_v +
timing.front_porch_v + timing.pulse_width_v;
pr_debug("av=%d bpv=%d fpv=%d pwv=%d vt=%d\n",
timing.active_v, timing.back_porch_v,
timing.front_porch_v, timing.pulse_width_v, v_total);
timing.pixel_freq = ((unsigned long int)pinfo->clk_rate / 1000);
if (h_total && v_total) {
timing.refresh_rate = ((timing.pixel_freq * 1000) /
(h_total * v_total)) * 1000;
} else {
pr_err("cannot cal refresh rate\n");
return -EPERM;
}
pr_debug("pixel_freq=%d refresh_rate=%d\n",
timing.pixel_freq, timing.refresh_rate);
new_vic = hdmi_get_video_id_code(&timing, ds_data);
}
return new_vic;
}
int hdmi_utils_get_timeout_in_hysnc(struct msm_hdmi_mode_timing_info *timing, int hdmi_utils_get_timeout_in_hysnc(struct msm_hdmi_mode_timing_info *timing,
u32 timeout_ms) u32 timeout_ms)
{ {

View file

@ -15,6 +15,8 @@
#include <linux/mdss_io_util.h> #include <linux/mdss_io_util.h>
#include "video/msm_hdmi_modes.h" #include "video/msm_hdmi_modes.h"
#include "mdss_panel.h"
/* HDMI_TX Registers */ /* HDMI_TX Registers */
#define HDMI_CTRL (0x00000000) #define HDMI_CTRL (0x00000000)
#define HDMI_TEST_PATTERN (0x00000010) #define HDMI_TEST_PATTERN (0x00000010)
@ -489,6 +491,8 @@ const char *msm_hdmi_mode_2string(u32 mode);
int hdmi_set_resv_timing_info(struct msm_hdmi_mode_timing_info *mode); int hdmi_set_resv_timing_info(struct msm_hdmi_mode_timing_info *mode);
bool hdmi_is_valid_resv_timing(int mode); bool hdmi_is_valid_resv_timing(int mode);
void hdmi_reset_resv_timing_info(void); void hdmi_reset_resv_timing_info(void);
int hdmi_panel_get_vic(struct mdss_panel_info *pinfo,
struct hdmi_util_ds_data *ds_data);
/* todo: Fix this. Right now this is defined in mdss_hdmi_tx.c */ /* todo: Fix this. Right now this is defined in mdss_hdmi_tx.c */
void *hdmi_get_featuredata_from_sysfs_dev(struct device *device, u32 type); void *hdmi_get_featuredata_from_sysfs_dev(struct device *device, u32 type);

View file

@ -688,6 +688,7 @@ struct mdss_panel_info {
void *edid_data; void *edid_data;
void *dba_data; void *dba_data;
void *cec_data; void *cec_data;
void *hdcp_1x_data;
char panel_name[MDSS_MAX_PANEL_LEN]; char panel_name[MDSS_MAX_PANEL_LEN];
struct mdss_mdp_pp_tear_check te; struct mdss_mdp_pp_tear_check te;