forked from Minki/linux
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: Archit Taneja <architt@codeaurora.org> Signed-off-by: Rob Clark <robdclark@gmail.com>
This commit is contained in:
parent
df8a71d2b2
commit
b3a94705a0
@ -16,16 +16,6 @@
|
||||
#include "drm_crtc.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)
|
||||
{
|
||||
struct msm_drm_private *priv = encoder->dev->dev_private;
|
||||
@ -36,47 +26,8 @@ static struct mdp5_kms *get_kms(struct drm_encoder *encoder)
|
||||
#include <mach/board.h>
|
||||
#include <linux/msm-bus.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) {
|
||||
DBG("set bus scaling: %d", idx);
|
||||
@ -89,14 +40,12 @@ static void bs_set(struct mdp5_cmd_encoder *mdp5_cmd_enc, int idx)
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void bs_init(struct mdp5_cmd_encoder *mdp5_cmd_enc) {}
|
||||
static void bs_fini(struct mdp5_cmd_encoder *mdp5_cmd_enc) {}
|
||||
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) {}
|
||||
#endif
|
||||
|
||||
#define VSYNC_CLK_RATE 19200000
|
||||
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 device *dev = encoder->dev->dev;
|
||||
@ -176,23 +125,11 @@ static void pingpong_tearcheck_disable(struct drm_encoder *encoder)
|
||||
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 drm_display_mode *adjusted_mode)
|
||||
{
|
||||
struct mdp5_cmd_encoder *mdp5_cmd_enc = to_mdp5_cmd_encoder(encoder);
|
||||
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;
|
||||
|
||||
@ -209,9 +146,9 @@ static void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder,
|
||||
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_interface *intf = &mdp5_cmd_enc->intf;
|
||||
|
||||
@ -228,9 +165,9 @@ static void mdp5_cmd_encoder_disable(struct drm_encoder *encoder)
|
||||
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_interface *intf = &mdp5_cmd_enc->intf;
|
||||
|
||||
@ -248,16 +185,10 @@ static void mdp5_cmd_encoder_enable(struct drm_encoder *encoder)
|
||||
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,
|
||||
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;
|
||||
int intf_num;
|
||||
u32 data = 0;
|
||||
@ -292,43 +223,3 @@ int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder,
|
||||
|
||||
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 @@
|
||||
#include "drm_crtc.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)
|
||||
{
|
||||
struct msm_drm_private *priv = encoder->dev->dev_private;
|
||||
@ -283,17 +272,35 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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 = {
|
||||
|
@ -276,7 +276,7 @@ int mdp5_enable(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_mode intf_mode, struct mdp5_ctl *ctl)
|
||||
struct mdp5_ctl *ctl)
|
||||
{
|
||||
struct drm_device *dev = mdp5_kms->dev;
|
||||
struct msm_drm_private *priv = dev->dev_private;
|
||||
@ -284,15 +284,10 @@ static struct drm_encoder *construct_encoder(struct mdp5_kms *mdp5_kms,
|
||||
struct mdp5_interface intf = {
|
||||
.num = intf_num,
|
||||
.type = intf_type,
|
||||
.mode = intf_mode,
|
||||
.mode = MDP5_INTF_MODE_NONE,
|
||||
};
|
||||
|
||||
if ((intf_type == INTF_DSI) &&
|
||||
(intf_mode == MDP5_INTF_DSI_MODE_COMMAND))
|
||||
encoder = mdp5_cmd_encoder_init(dev, &intf, ctl);
|
||||
else
|
||||
encoder = mdp5_encoder_init(dev, &intf, ctl);
|
||||
|
||||
encoder = mdp5_encoder_init(dev, &intf, ctl);
|
||||
if (IS_ERR(encoder)) {
|
||||
dev_err(dev->dev, "failed to construct encoder\n");
|
||||
return encoder;
|
||||
@ -347,8 +342,7 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num)
|
||||
break;
|
||||
}
|
||||
|
||||
encoder = construct_encoder(mdp5_kms, INTF_eDP, intf_num,
|
||||
MDP5_INTF_MODE_NONE, ctl);
|
||||
encoder = construct_encoder(mdp5_kms, INTF_eDP, intf_num, ctl);
|
||||
if (IS_ERR(encoder)) {
|
||||
ret = PTR_ERR(encoder);
|
||||
break;
|
||||
@ -366,8 +360,7 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num)
|
||||
break;
|
||||
}
|
||||
|
||||
encoder = construct_encoder(mdp5_kms, INTF_HDMI, intf_num,
|
||||
MDP5_INTF_MODE_NONE, ctl);
|
||||
encoder = construct_encoder(mdp5_kms, INTF_HDMI, intf_num, ctl);
|
||||
if (IS_ERR(encoder)) {
|
||||
ret = PTR_ERR(encoder);
|
||||
break;
|
||||
@ -395,8 +388,7 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num)
|
||||
break;
|
||||
}
|
||||
|
||||
encoder = construct_encoder(mdp5_kms, INTF_DSI, intf_num,
|
||||
MDP5_INTF_DSI_MODE_VIDEO, ctl);
|
||||
encoder = construct_encoder(mdp5_kms, INTF_DSI, intf_num, ctl);
|
||||
if (IS_ERR(encoder)) {
|
||||
ret = PTR_ERR(encoder);
|
||||
break;
|
||||
|
@ -126,6 +126,17 @@ struct mdp5_interface {
|
||||
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)
|
||||
{
|
||||
msm_writel(data, mdp5_kms->mmio + reg);
|
||||
@ -251,15 +262,24 @@ int mdp5_encoder_get_linecount(struct drm_encoder *encoder);
|
||||
u32 mdp5_encoder_get_framecount(struct drm_encoder *encoder);
|
||||
|
||||
#ifdef CONFIG_DRM_MSM_DSI
|
||||
struct drm_encoder *mdp5_cmd_encoder_init(struct drm_device *dev,
|
||||
struct mdp5_interface *intf, struct mdp5_ctl *ctl);
|
||||
void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder,
|
||||
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,
|
||||
struct drm_encoder *slave_encoder);
|
||||
struct drm_encoder *slave_encoder);
|
||||
#else
|
||||
static inline struct drm_encoder *mdp5_cmd_encoder_init(struct drm_device *dev,
|
||||
struct mdp5_interface *intf, struct mdp5_ctl *ctl)
|
||||
static inline void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder,
|
||||
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(
|
||||
struct drm_encoder *encoder, struct drm_encoder *slave_encoder)
|
||||
|
Loading…
Reference in New Issue
Block a user