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:
parent
16e3ac406c
commit
f0b8cc9283
8 changed files with 118 additions and 84 deletions
|
@ -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);
|
||||||
|
|
|
@ -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__);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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__);
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Reference in a new issue