Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+13 −122
Original line number Diff line number Diff line
@@ -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,9 +40,7 @@ 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
@@ -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)
{
	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,
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 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 −14
Original line number Diff line number Diff line
@@ -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,16 +272,34 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder,
				  struct drm_display_mode *mode,
				  struct drm_display_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)
{
	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)
{
	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);
}

+6 −14
Original line number Diff line number Diff line
@@ -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);

	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;
+26 −6
Original line number Diff line number Diff line
@@ -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);
#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)