Commit b3a94705 authored by Archit Taneja's avatar Archit Taneja Committed by Rob Clark

drm/msm/mdp5: Create single encoder per interface (INTF)

For the DSI interfaces, the mdp5_kms core creates 2 encoders for video
and command modes.

Create only a single encoder per interface. When creating the encoder, set
the interface type to MDP5_INTF_MODE_NONE. It's the bridge (DSI/HDMI/eDP)
driver's responsibility to set a different interface type. It can use the
the kms func op set_encoder_mode to change the mode of operation, which
in turn would configure the interface type for the INTF.

In mdp5_cmd_encoder.c, we remove the redundant code, and make the commmand
mode funcs as helpers that are used in mdp5_encoder.c
Signed-off-by: default avatarArchit Taneja <architt@codeaurora.org>
Signed-off-by: default avatarRob Clark <robdclark@gmail.com>
parent df8a71d2
...@@ -16,16 +16,6 @@ ...@@ -16,16 +16,6 @@
#include "drm_crtc.h" #include "drm_crtc.h"
#include "drm_crtc_helper.h" #include "drm_crtc_helper.h"
struct mdp5_cmd_encoder {
struct drm_encoder base;
struct mdp5_interface intf;
bool enabled;
uint32_t bsc;
struct mdp5_ctl *ctl;
};
#define to_mdp5_cmd_encoder(x) container_of(x, struct mdp5_cmd_encoder, base)
static struct mdp5_kms *get_kms(struct drm_encoder *encoder) static struct mdp5_kms *get_kms(struct drm_encoder *encoder)
{ {
struct msm_drm_private *priv = encoder->dev->dev_private; struct msm_drm_private *priv = encoder->dev->dev_private;
...@@ -36,47 +26,8 @@ static struct mdp5_kms *get_kms(struct drm_encoder *encoder) ...@@ -36,47 +26,8 @@ static struct mdp5_kms *get_kms(struct drm_encoder *encoder)
#include <mach/board.h> #include <mach/board.h>
#include <linux/msm-bus.h> #include <linux/msm-bus.h>
#include <linux/msm-bus-board.h> #include <linux/msm-bus-board.h>
#define MDP_BUS_VECTOR_ENTRY(ab_val, ib_val) \
{ \
.src = MSM_BUS_MASTER_MDP_PORT0, \
.dst = MSM_BUS_SLAVE_EBI_CH0, \
.ab = (ab_val), \
.ib = (ib_val), \
}
static struct msm_bus_vectors mdp_bus_vectors[] = {
MDP_BUS_VECTOR_ENTRY(0, 0),
MDP_BUS_VECTOR_ENTRY(2000000000, 2000000000),
};
static struct msm_bus_paths mdp_bus_usecases[] = { {
.num_paths = 1,
.vectors = &mdp_bus_vectors[0],
}, {
.num_paths = 1,
.vectors = &mdp_bus_vectors[1],
} };
static struct msm_bus_scale_pdata mdp_bus_scale_table = {
.usecase = mdp_bus_usecases,
.num_usecases = ARRAY_SIZE(mdp_bus_usecases),
.name = "mdss_mdp",
};
static void bs_init(struct mdp5_cmd_encoder *mdp5_cmd_enc)
{
mdp5_cmd_enc->bsc = msm_bus_scale_register_client(
&mdp_bus_scale_table);
DBG("bus scale client: %08x", mdp5_cmd_enc->bsc);
}
static void bs_fini(struct mdp5_cmd_encoder *mdp5_cmd_enc)
{
if (mdp5_cmd_enc->bsc) {
msm_bus_scale_unregister_client(mdp5_cmd_enc->bsc);
mdp5_cmd_enc->bsc = 0;
}
}
static void bs_set(struct mdp5_cmd_encoder *mdp5_cmd_enc, int idx) static void bs_set(struct mdp5_encoder *mdp5_cmd_enc, int idx)
{ {
if (mdp5_cmd_enc->bsc) { if (mdp5_cmd_enc->bsc) {
DBG("set bus scaling: %d", idx); DBG("set bus scaling: %d", idx);
...@@ -89,14 +40,12 @@ static void bs_set(struct mdp5_cmd_encoder *mdp5_cmd_enc, int idx) ...@@ -89,14 +40,12 @@ static void bs_set(struct mdp5_cmd_encoder *mdp5_cmd_enc, int idx)
} }
} }
#else #else
static void bs_init(struct mdp5_cmd_encoder *mdp5_cmd_enc) {} static void bs_set(struct mdp5_encoder *mdp5_cmd_enc, int idx) {}
static void bs_fini(struct mdp5_cmd_encoder *mdp5_cmd_enc) {}
static void bs_set(struct mdp5_cmd_encoder *mdp5_cmd_enc, int idx) {}
#endif #endif
#define VSYNC_CLK_RATE 19200000 #define VSYNC_CLK_RATE 19200000
static int pingpong_tearcheck_setup(struct drm_encoder *encoder, static int pingpong_tearcheck_setup(struct drm_encoder *encoder,
struct drm_display_mode *mode) struct drm_display_mode *mode)
{ {
struct mdp5_kms *mdp5_kms = get_kms(encoder); struct mdp5_kms *mdp5_kms = get_kms(encoder);
struct device *dev = encoder->dev->dev; struct device *dev = encoder->dev->dev;
...@@ -176,23 +125,11 @@ static void pingpong_tearcheck_disable(struct drm_encoder *encoder) ...@@ -176,23 +125,11 @@ static void pingpong_tearcheck_disable(struct drm_encoder *encoder)
clk_disable_unprepare(mdp5_kms->vsync_clk); clk_disable_unprepare(mdp5_kms->vsync_clk);
} }
static void mdp5_cmd_encoder_destroy(struct drm_encoder *encoder) void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder,
{ struct drm_display_mode *mode,
struct mdp5_cmd_encoder *mdp5_cmd_enc = to_mdp5_cmd_encoder(encoder); struct drm_display_mode *adjusted_mode)
bs_fini(mdp5_cmd_enc);
drm_encoder_cleanup(encoder);
kfree(mdp5_cmd_enc);
}
static const struct drm_encoder_funcs mdp5_cmd_encoder_funcs = {
.destroy = mdp5_cmd_encoder_destroy,
};
static void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{ {
struct mdp5_cmd_encoder *mdp5_cmd_enc = to_mdp5_cmd_encoder(encoder); struct mdp5_encoder *mdp5_cmd_enc = to_mdp5_encoder(encoder);
mode = adjusted_mode; mode = adjusted_mode;
...@@ -209,9 +146,9 @@ static void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder, ...@@ -209,9 +146,9 @@ static void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder,
mdp5_cmd_enc->ctl); mdp5_cmd_enc->ctl);
} }
static void mdp5_cmd_encoder_disable(struct drm_encoder *encoder) void mdp5_cmd_encoder_disable(struct drm_encoder *encoder)
{ {
struct mdp5_cmd_encoder *mdp5_cmd_enc = to_mdp5_cmd_encoder(encoder); struct mdp5_encoder *mdp5_cmd_enc = to_mdp5_encoder(encoder);
struct mdp5_ctl *ctl = mdp5_cmd_enc->ctl; struct mdp5_ctl *ctl = mdp5_cmd_enc->ctl;
struct mdp5_interface *intf = &mdp5_cmd_enc->intf; struct mdp5_interface *intf = &mdp5_cmd_enc->intf;
...@@ -228,9 +165,9 @@ static void mdp5_cmd_encoder_disable(struct drm_encoder *encoder) ...@@ -228,9 +165,9 @@ static void mdp5_cmd_encoder_disable(struct drm_encoder *encoder)
mdp5_cmd_enc->enabled = false; mdp5_cmd_enc->enabled = false;
} }
static void mdp5_cmd_encoder_enable(struct drm_encoder *encoder) void mdp5_cmd_encoder_enable(struct drm_encoder *encoder)
{ {
struct mdp5_cmd_encoder *mdp5_cmd_enc = to_mdp5_cmd_encoder(encoder); struct mdp5_encoder *mdp5_cmd_enc = to_mdp5_encoder(encoder);
struct mdp5_ctl *ctl = mdp5_cmd_enc->ctl; struct mdp5_ctl *ctl = mdp5_cmd_enc->ctl;
struct mdp5_interface *intf = &mdp5_cmd_enc->intf; struct mdp5_interface *intf = &mdp5_cmd_enc->intf;
...@@ -248,16 +185,10 @@ static void mdp5_cmd_encoder_enable(struct drm_encoder *encoder) ...@@ -248,16 +185,10 @@ static void mdp5_cmd_encoder_enable(struct drm_encoder *encoder)
mdp5_cmd_enc->enabled = true; mdp5_cmd_enc->enabled = true;
} }
static const struct drm_encoder_helper_funcs mdp5_cmd_encoder_helper_funcs = {
.mode_set = mdp5_cmd_encoder_mode_set,
.disable = mdp5_cmd_encoder_disable,
.enable = mdp5_cmd_encoder_enable,
};
int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder, int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder,
struct drm_encoder *slave_encoder) struct drm_encoder *slave_encoder)
{ {
struct mdp5_cmd_encoder *mdp5_cmd_enc = to_mdp5_cmd_encoder(encoder); struct mdp5_encoder *mdp5_cmd_enc = to_mdp5_encoder(encoder);
struct mdp5_kms *mdp5_kms; struct mdp5_kms *mdp5_kms;
int intf_num; int intf_num;
u32 data = 0; u32 data = 0;
...@@ -292,43 +223,3 @@ int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder, ...@@ -292,43 +223,3 @@ int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder,
return 0; return 0;
} }
/* initialize command mode encoder */
struct drm_encoder *mdp5_cmd_encoder_init(struct drm_device *dev,
struct mdp5_interface *intf, struct mdp5_ctl *ctl)
{
struct drm_encoder *encoder = NULL;
struct mdp5_cmd_encoder *mdp5_cmd_enc;
int ret;
if (WARN_ON((intf->type != INTF_DSI) &&
(intf->mode != MDP5_INTF_DSI_MODE_COMMAND))) {
ret = -EINVAL;
goto fail;
}
mdp5_cmd_enc = kzalloc(sizeof(*mdp5_cmd_enc), GFP_KERNEL);
if (!mdp5_cmd_enc) {
ret = -ENOMEM;
goto fail;
}
memcpy(&mdp5_cmd_enc->intf, intf, sizeof(mdp5_cmd_enc->intf));
encoder = &mdp5_cmd_enc->base;
mdp5_cmd_enc->ctl = ctl;
drm_encoder_init(dev, encoder, &mdp5_cmd_encoder_funcs,
DRM_MODE_ENCODER_DSI, NULL);
drm_encoder_helper_add(encoder, &mdp5_cmd_encoder_helper_funcs);
bs_init(mdp5_cmd_enc);
return encoder;
fail:
if (encoder)
mdp5_cmd_encoder_destroy(encoder);
return ERR_PTR(ret);
}
...@@ -21,17 +21,6 @@ ...@@ -21,17 +21,6 @@
#include "drm_crtc.h" #include "drm_crtc.h"
#include "drm_crtc_helper.h" #include "drm_crtc_helper.h"
struct mdp5_encoder {
struct drm_encoder base;
struct mdp5_interface intf;
spinlock_t intf_lock; /* protect REG_MDP5_INTF_* registers */
bool enabled;
uint32_t bsc;
struct mdp5_ctl *ctl;
};
#define to_mdp5_encoder(x) container_of(x, struct mdp5_encoder, base)
static struct mdp5_kms *get_kms(struct drm_encoder *encoder) static struct mdp5_kms *get_kms(struct drm_encoder *encoder)
{ {
struct msm_drm_private *priv = encoder->dev->dev_private; struct msm_drm_private *priv = encoder->dev->dev_private;
...@@ -283,17 +272,35 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder, ...@@ -283,17 +272,35 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode, struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode) struct drm_display_mode *adjusted_mode)
{ {
mdp5_vid_encoder_mode_set(encoder, mode, adjusted_mode); struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
struct mdp5_interface *intf = &mdp5_encoder->intf;
if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND)
mdp5_cmd_encoder_mode_set(encoder, mode, adjusted_mode);
else
mdp5_vid_encoder_mode_set(encoder, mode, adjusted_mode);
} }
static void mdp5_encoder_disable(struct drm_encoder *encoder) static void mdp5_encoder_disable(struct drm_encoder *encoder)
{ {
mdp5_vid_encoder_disable(encoder); struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
struct mdp5_interface *intf = &mdp5_encoder->intf;
if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND)
mdp5_cmd_encoder_disable(encoder);
else
mdp5_vid_encoder_disable(encoder);
} }
static void mdp5_encoder_enable(struct drm_encoder *encoder) static void mdp5_encoder_enable(struct drm_encoder *encoder)
{ {
mdp5_vid_encoder_enable(encoder); struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
struct mdp5_interface *intf = &mdp5_encoder->intf;
if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND)
mdp5_cmd_encoder_disable(encoder);
else
mdp5_vid_encoder_enable(encoder);
} }
static const struct drm_encoder_helper_funcs mdp5_encoder_helper_funcs = { static const struct drm_encoder_helper_funcs mdp5_encoder_helper_funcs = {
......
...@@ -276,7 +276,7 @@ int mdp5_enable(struct mdp5_kms *mdp5_kms) ...@@ -276,7 +276,7 @@ int mdp5_enable(struct mdp5_kms *mdp5_kms)
static struct drm_encoder *construct_encoder(struct mdp5_kms *mdp5_kms, static struct drm_encoder *construct_encoder(struct mdp5_kms *mdp5_kms,
enum mdp5_intf_type intf_type, int intf_num, enum mdp5_intf_type intf_type, int intf_num,
enum mdp5_intf_mode intf_mode, struct mdp5_ctl *ctl) struct mdp5_ctl *ctl)
{ {
struct drm_device *dev = mdp5_kms->dev; struct drm_device *dev = mdp5_kms->dev;
struct msm_drm_private *priv = dev->dev_private; struct msm_drm_private *priv = dev->dev_private;
...@@ -284,15 +284,10 @@ static struct drm_encoder *construct_encoder(struct mdp5_kms *mdp5_kms, ...@@ -284,15 +284,10 @@ static struct drm_encoder *construct_encoder(struct mdp5_kms *mdp5_kms,
struct mdp5_interface intf = { struct mdp5_interface intf = {
.num = intf_num, .num = intf_num,
.type = intf_type, .type = intf_type,
.mode = intf_mode, .mode = MDP5_INTF_MODE_NONE,
}; };
if ((intf_type == INTF_DSI) && encoder = mdp5_encoder_init(dev, &intf, ctl);
(intf_mode == MDP5_INTF_DSI_MODE_COMMAND))
encoder = mdp5_cmd_encoder_init(dev, &intf, ctl);
else
encoder = mdp5_encoder_init(dev, &intf, ctl);
if (IS_ERR(encoder)) { if (IS_ERR(encoder)) {
dev_err(dev->dev, "failed to construct encoder\n"); dev_err(dev->dev, "failed to construct encoder\n");
return encoder; return encoder;
...@@ -347,8 +342,7 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num) ...@@ -347,8 +342,7 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num)
break; break;
} }
encoder = construct_encoder(mdp5_kms, INTF_eDP, intf_num, encoder = construct_encoder(mdp5_kms, INTF_eDP, intf_num, ctl);
MDP5_INTF_MODE_NONE, ctl);
if (IS_ERR(encoder)) { if (IS_ERR(encoder)) {
ret = PTR_ERR(encoder); ret = PTR_ERR(encoder);
break; break;
...@@ -366,8 +360,7 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num) ...@@ -366,8 +360,7 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num)
break; break;
} }
encoder = construct_encoder(mdp5_kms, INTF_HDMI, intf_num, encoder = construct_encoder(mdp5_kms, INTF_HDMI, intf_num, ctl);
MDP5_INTF_MODE_NONE, ctl);
if (IS_ERR(encoder)) { if (IS_ERR(encoder)) {
ret = PTR_ERR(encoder); ret = PTR_ERR(encoder);
break; break;
...@@ -395,8 +388,7 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num) ...@@ -395,8 +388,7 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num)
break; break;
} }
encoder = construct_encoder(mdp5_kms, INTF_DSI, intf_num, encoder = construct_encoder(mdp5_kms, INTF_DSI, intf_num, ctl);
MDP5_INTF_DSI_MODE_VIDEO, ctl);
if (IS_ERR(encoder)) { if (IS_ERR(encoder)) {
ret = PTR_ERR(encoder); ret = PTR_ERR(encoder);
break; break;
......
...@@ -126,6 +126,17 @@ struct mdp5_interface { ...@@ -126,6 +126,17 @@ struct mdp5_interface {
enum mdp5_intf_mode mode; enum mdp5_intf_mode mode;
}; };
struct mdp5_encoder {
struct drm_encoder base;
struct mdp5_interface intf;
spinlock_t intf_lock; /* protect REG_MDP5_INTF_* registers */
bool enabled;
uint32_t bsc;
struct mdp5_ctl *ctl;
};
#define to_mdp5_encoder(x) container_of(x, struct mdp5_encoder, base)
static inline void mdp5_write(struct mdp5_kms *mdp5_kms, u32 reg, u32 data) static inline void mdp5_write(struct mdp5_kms *mdp5_kms, u32 reg, u32 data)
{ {
msm_writel(data, mdp5_kms->mmio + reg); msm_writel(data, mdp5_kms->mmio + reg);
...@@ -251,15 +262,24 @@ int mdp5_encoder_get_linecount(struct drm_encoder *encoder); ...@@ -251,15 +262,24 @@ int mdp5_encoder_get_linecount(struct drm_encoder *encoder);
u32 mdp5_encoder_get_framecount(struct drm_encoder *encoder); u32 mdp5_encoder_get_framecount(struct drm_encoder *encoder);
#ifdef CONFIG_DRM_MSM_DSI #ifdef CONFIG_DRM_MSM_DSI
struct drm_encoder *mdp5_cmd_encoder_init(struct drm_device *dev, void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder,
struct mdp5_interface *intf, struct mdp5_ctl *ctl); struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
void mdp5_cmd_encoder_disable(struct drm_encoder *encoder);
void mdp5_cmd_encoder_enable(struct drm_encoder *encoder);
int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder, int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder,
struct drm_encoder *slave_encoder); struct drm_encoder *slave_encoder);
#else #else
static inline struct drm_encoder *mdp5_cmd_encoder_init(struct drm_device *dev, static inline void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder,
struct mdp5_interface *intf, struct mdp5_ctl *ctl) struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
}
static inline void mdp5_cmd_encoder_disable(struct drm_encoder *encoder)
{
}
static inline void mdp5_cmd_encoder_enable(struct drm_encoder *encoder)
{ {
return ERR_PTR(-EINVAL);
} }
static inline int mdp5_cmd_encoder_set_split_display( static inline int mdp5_cmd_encoder_set_split_display(
struct drm_encoder *encoder, struct drm_encoder *slave_encoder) struct drm_encoder *encoder, struct drm_encoder *slave_encoder)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment