drm/msm/sde: simplify encoder display probe logic
Cleanup the display probing logic now that the common display interface is available. Change-Id: I3a6f815d8e7ab7f22e719eaf7ef4c8150470d54f Signed-off-by: Lloyd Atkinson <latkinso@codeaurora.org> Signed-off-by: Krishna Srinivas Kundurthi <kskund@codeaurora.org>
This commit is contained in:
parent
0190e3c975
commit
643f961532
1 changed files with 79 additions and 144 deletions
|
@ -279,7 +279,7 @@ static const struct drm_encoder_funcs sde_encoder_funcs = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static enum sde_intf sde_encoder_get_intf(struct sde_mdss_cfg *catalog,
|
static enum sde_intf sde_encoder_get_intf(struct sde_mdss_cfg *catalog,
|
||||||
enum sde_intf_type type, u32 instance)
|
enum sde_intf_type type, u32 controller_id)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
@ -287,7 +287,7 @@ static enum sde_intf sde_encoder_get_intf(struct sde_mdss_cfg *catalog,
|
||||||
|
|
||||||
for (i = 0; i < catalog->intf_count; i++) {
|
for (i = 0; i < catalog->intf_count; i++) {
|
||||||
if (catalog->intf[i].type == type
|
if (catalog->intf[i].type == type
|
||||||
&& catalog->intf[i].controller_id == instance) {
|
&& catalog->intf[i].controller_id == controller_id) {
|
||||||
return catalog->intf[i].id;
|
return catalog->intf[i].id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -348,52 +348,49 @@ static int sde_encoder_virt_add_phys_vid_enc(struct sde_encoder_virt *sde_enc,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sde_encoder_setup_hdmi(struct sde_encoder_virt *sde_enc,
|
static int sde_encoder_setup_display(struct sde_encoder_virt *sde_enc,
|
||||||
struct sde_kms *sde_kms, int *hdmi_info)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
enum sde_intf intf_idx = INTF_MAX;
|
|
||||||
enum sde_ctl ctl_idx = CTL_2;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
intf_idx = sde_encoder_get_intf(sde_kms->catalog, INTF_HDMI, 0);
|
|
||||||
if (intf_idx == INTF_MAX)
|
|
||||||
ret = -EINVAL;
|
|
||||||
|
|
||||||
if (!ret)
|
|
||||||
ret =
|
|
||||||
sde_encoder_virt_add_phys_vid_enc(sde_enc, sde_kms,
|
|
||||||
intf_idx, ctl_idx);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sde_encoder_setup_dsi(struct sde_encoder_virt *sde_enc,
|
|
||||||
struct sde_kms *sde_kms,
|
struct sde_kms *sde_kms,
|
||||||
struct display_info *disp_info)
|
struct display_info *disp_info,
|
||||||
|
int *drm_enc_mode)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
enum sde_intf_type intf_type = INTF_NONE;
|
||||||
|
|
||||||
DBG("");
|
DBG("");
|
||||||
|
|
||||||
|
if (disp_info->intf == DISPLAY_INTF_DSI) {
|
||||||
|
*drm_enc_mode = DRM_MODE_ENCODER_DSI;
|
||||||
|
intf_type = INTF_DSI;
|
||||||
|
} else if (disp_info->intf == DISPLAY_INTF_HDMI) {
|
||||||
|
*drm_enc_mode = DRM_MODE_ENCODER_TMDS;
|
||||||
|
intf_type = INTF_HDMI;
|
||||||
|
} else {
|
||||||
|
DRM_ERROR("Unsupported display interface type");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
WARN_ON(disp_info->num_of_h_tiles < 1);
|
WARN_ON(disp_info->num_of_h_tiles < 1);
|
||||||
|
|
||||||
if (disp_info->num_of_h_tiles == 0)
|
DBG("dsi_info->num_of_h_tiles %d", disp_info->num_of_h_tiles);
|
||||||
disp_info->num_of_h_tiles = 1;
|
|
||||||
|
|
||||||
DBG("num_of_h_tiles %d h_tile_instance_0 %d h_tile_instance_1 %d\n",
|
|
||||||
disp_info->num_of_h_tiles, disp_info->h_tile_instance[0],
|
|
||||||
disp_info->h_tile_instance[1]);
|
|
||||||
|
|
||||||
for (i = 0; i < disp_info->num_of_h_tiles && !ret; i++) {
|
for (i = 0; i < disp_info->num_of_h_tiles && !ret; i++) {
|
||||||
|
/*
|
||||||
|
* Left-most tile is at index 0, content is controller id
|
||||||
|
* h_tile_instance_ids[2] = {0, 1}; DSI0 = left, DSI1 = right
|
||||||
|
* h_tile_instance_ids[2] = {1, 0}; DSI1 = left, DSI0 = right
|
||||||
|
*/
|
||||||
enum sde_intf intf_idx = INTF_MAX;
|
enum sde_intf intf_idx = INTF_MAX;
|
||||||
enum sde_ctl ctl_idx = CTL_0;
|
enum sde_ctl ctl_idx = CTL_0;
|
||||||
|
u32 controller_id = disp_info->h_tile_instance[i];
|
||||||
|
|
||||||
|
if (intf_type == INTF_HDMI)
|
||||||
|
ctl_idx = CTL_2;
|
||||||
|
|
||||||
|
DBG("h_tile_instance %d = %d", i, controller_id);
|
||||||
|
|
||||||
intf_idx = sde_encoder_get_intf(sde_kms->catalog,
|
intf_idx = sde_encoder_get_intf(sde_kms->catalog,
|
||||||
INTF_DSI,
|
intf_type, controller_id);
|
||||||
disp_info->h_tile_instance[i]);
|
|
||||||
if (intf_idx == INTF_MAX) {
|
if (intf_idx == INTF_MAX) {
|
||||||
DBG("Error: could not get the interface id");
|
DBG("Error: could not get the interface id");
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
|
@ -401,29 +398,22 @@ static int sde_encoder_setup_dsi(struct sde_encoder_virt *sde_enc,
|
||||||
|
|
||||||
/* Create both VID and CMD Phys Encoders here */
|
/* Create both VID and CMD Phys Encoders here */
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret =
|
ret = sde_encoder_virt_add_phys_vid_enc(
|
||||||
sde_encoder_virt_add_phys_vid_enc(sde_enc, sde_kms,
|
sde_enc, sde_kms, intf_idx, ctl_idx);
|
||||||
intf_idx,
|
|
||||||
ctl_idx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct display_probe_info {
|
static struct drm_encoder *sde_encoder_virt_init(
|
||||||
enum sde_intf_type type;
|
struct drm_device *dev, struct display_info *disp_info)
|
||||||
struct display_info disp_info;
|
|
||||||
int hdmi_info;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct drm_encoder *sde_encoder_virt_init(struct drm_device *dev,
|
|
||||||
struct display_probe_info *display)
|
|
||||||
{
|
{
|
||||||
struct msm_drm_private *priv = dev->dev_private;
|
struct msm_drm_private *priv = dev->dev_private;
|
||||||
struct sde_kms *sde_kms = to_sde_kms(to_mdp_kms(priv->kms));
|
struct sde_kms *sde_kms = to_sde_kms(to_mdp_kms(priv->kms));
|
||||||
struct drm_encoder *drm_enc = NULL;
|
struct drm_encoder *drm_enc = NULL;
|
||||||
struct sde_encoder_virt *sde_enc = NULL;
|
struct sde_encoder_virt *sde_enc = NULL;
|
||||||
int drm_encoder_mode = DRM_MODE_ENCODER_NONE;
|
int drm_enc_mode = DRM_MODE_ENCODER_NONE;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
DBG("");
|
DBG("");
|
||||||
|
@ -434,28 +424,14 @@ static struct drm_encoder *sde_encoder_virt_init(struct drm_device *dev,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (display->type == INTF_DSI) {
|
ret = sde_encoder_setup_display(sde_enc, sde_kms, disp_info,
|
||||||
drm_encoder_mode = DRM_MODE_ENCODER_DSI;
|
&drm_enc_mode);
|
||||||
ret = sde_encoder_setup_dsi(sde_enc,
|
|
||||||
sde_kms,
|
|
||||||
&display->disp_info);
|
|
||||||
|
|
||||||
} else if (display->type == INTF_HDMI) {
|
|
||||||
drm_encoder_mode = DRM_MODE_ENCODER_TMDS;
|
|
||||||
ret =
|
|
||||||
sde_encoder_setup_hdmi(sde_enc, sde_kms,
|
|
||||||
&display->hdmi_info);
|
|
||||||
} else {
|
|
||||||
DRM_ERROR("No valid displays found\n");
|
|
||||||
ret = -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
spin_lock_init(&sde_enc->spin_lock);
|
spin_lock_init(&sde_enc->spin_lock);
|
||||||
drm_enc = &sde_enc->base;
|
drm_enc = &sde_enc->base;
|
||||||
drm_encoder_init(dev, drm_enc, &sde_encoder_funcs, drm_encoder_mode);
|
drm_encoder_init(dev, drm_enc, &sde_encoder_funcs, drm_enc_mode);
|
||||||
drm_encoder_helper_add(drm_enc, &sde_encoder_helper_funcs);
|
drm_encoder_helper_add(drm_enc, &sde_encoder_helper_funcs);
|
||||||
bs_init(sde_enc);
|
bs_init(sde_enc);
|
||||||
|
|
||||||
|
@ -471,76 +447,6 @@ fail:
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sde_encoder_probe_hdmi(struct drm_device *dev)
|
|
||||||
{
|
|
||||||
struct msm_drm_private *priv = dev->dev_private;
|
|
||||||
struct drm_encoder *enc = NULL;
|
|
||||||
struct display_probe_info probe_info = { 0 };
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
probe_info.type = INTF_HDMI;
|
|
||||||
|
|
||||||
enc = sde_encoder_virt_init(dev, &probe_info);
|
|
||||||
if (IS_ERR(enc))
|
|
||||||
ret = PTR_ERR(enc);
|
|
||||||
|
|
||||||
if (!ret) {
|
|
||||||
/* Register new encoder with the upper layer */
|
|
||||||
priv->encoders[priv->num_encoders++] = enc;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sde_encoder_probe_dsi(struct drm_device *dev)
|
|
||||||
{
|
|
||||||
struct msm_drm_private *priv = dev->dev_private;
|
|
||||||
u32 ret = 0;
|
|
||||||
u32 i = 0;
|
|
||||||
u32 num_displays = 0;
|
|
||||||
struct display_manager *dm = priv->dm;
|
|
||||||
struct display_probe_info probe_info = { 0 };
|
|
||||||
|
|
||||||
DBG("");
|
|
||||||
|
|
||||||
num_displays = display_manager_get_count(dm);
|
|
||||||
DBG("num_displays %d", num_displays);
|
|
||||||
|
|
||||||
if (priv->num_encoders + num_displays > ARRAY_SIZE(priv->encoders)) {
|
|
||||||
DBG("Too many displays found in probe");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < num_displays; i++) {
|
|
||||||
struct drm_encoder *enc;
|
|
||||||
|
|
||||||
ret = display_manager_get_info_by_index(dm, i,
|
|
||||||
&probe_info.disp_info);
|
|
||||||
if (ret) {
|
|
||||||
pr_err("Failed to get display info, %d\n", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
enc = sde_encoder_virt_init(dev, &probe_info);
|
|
||||||
if (IS_ERR_OR_NULL(enc)) {
|
|
||||||
pr_err("encoder virt init failed\n");
|
|
||||||
return PTR_ERR(enc);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = display_manager_drm_init_by_index(dm, i, enc);
|
|
||||||
if (ret) {
|
|
||||||
pr_err("display drm init failed\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
priv->encoders[priv->num_encoders++] = enc;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sde_encoder_register_vblank_callback(struct drm_encoder *drm_enc,
|
void sde_encoder_register_vblank_callback(struct drm_encoder *drm_enc,
|
||||||
void (*cb)(void *), void *data)
|
void (*cb)(void *), void *data)
|
||||||
{
|
{
|
||||||
|
@ -561,7 +467,9 @@ void sde_encoder_register_vblank_callback(struct drm_encoder *drm_enc,
|
||||||
void sde_encoders_init(struct drm_device *dev)
|
void sde_encoders_init(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
struct msm_drm_private *priv = NULL;
|
struct msm_drm_private *priv = NULL;
|
||||||
int ret = 0;
|
struct display_manager *disp_man = NULL;
|
||||||
|
u32 i = 0;
|
||||||
|
u32 num_displays = 0;
|
||||||
|
|
||||||
DBG("");
|
DBG("");
|
||||||
|
|
||||||
|
@ -571,18 +479,45 @@ void sde_encoders_init(struct drm_device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
priv = dev->dev_private;
|
priv = dev->dev_private;
|
||||||
if (!priv->kms) {
|
priv->num_encoders = 0;
|
||||||
|
if (!priv->kms || !priv->dm) {
|
||||||
DRM_ERROR("Invalid pointer");
|
DRM_ERROR("Invalid pointer");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Start num_encoders at 0, probe functions will increment */
|
disp_man = priv->dm;
|
||||||
priv->num_encoders = 0;
|
|
||||||
ret = sde_encoder_probe_dsi(dev);
|
num_displays = display_manager_get_count(disp_man);
|
||||||
if (ret)
|
DBG("num_displays %d", num_displays);
|
||||||
DRM_ERROR("Error probing DSI, %d\n", ret);
|
|
||||||
else {
|
if (num_displays > ARRAY_SIZE(priv->encoders)) {
|
||||||
ret = sde_encoder_probe_hdmi(dev);
|
num_displays = ARRAY_SIZE(priv->encoders);
|
||||||
if (ret)
|
DRM_ERROR("Too many displays found, capping to %d",
|
||||||
DRM_ERROR("Error probing HDMI, %d\n", ret);
|
num_displays);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < num_displays; i++) {
|
||||||
|
struct display_info info = { 0 };
|
||||||
|
struct drm_encoder *enc = NULL;
|
||||||
|
u32 ret = 0;
|
||||||
|
|
||||||
|
ret = display_manager_get_info_by_index(disp_man, i, &info);
|
||||||
|
if (ret) {
|
||||||
|
DRM_ERROR("Failed to get display info, %d", ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
enc = sde_encoder_virt_init(dev, &info);
|
||||||
|
if (IS_ERR_OR_NULL(enc)) {
|
||||||
|
DRM_ERROR("Encoder initialization failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = display_manager_drm_init_by_index(disp_man, i, enc);
|
||||||
|
if (ret) {
|
||||||
|
DRM_ERROR("Display drm_init failed, %d", ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->encoders[priv->num_encoders++] = enc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue