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

Commit 58b19db5 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: mdss: Add atomic commit support for MDP3 driver"

parents 003806be 9945a157
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@ ccflags-y += -I$(src)

obj-$(CONFIG_FB_MSM_MDSS_MHL3) += mhl3/

mdss-mdp3-objs = mdp3.o mdp3_dma.o mdp3_ctrl.o dsi_status_v2.o
mdss-mdp3-objs = mdp3.o mdp3_layer.o mdp3_dma.o mdp3_ctrl.o dsi_status_v2.o
mdss-mdp3-objs += mdp3_ppp.o mdp3_ppp_hwio.o mdp3_ppp_data.o
obj-$(CONFIG_FB_MSM_MDSS_MDP3) += mdss-mdp3.o
ifeq ($(CONFIG_FB_MSM_MDSS_MDP3), y)
+95 −1
Original line number Diff line number Diff line
@@ -78,6 +78,13 @@ struct mdp3_hw_resource *mdp3_res;
		.ib = (ib_val),				\
	}

#define SET_BIT(value, bit_num) \
{ \
	value[bit_num >> 3] |= (1 << (bit_num & 7)); \
}

#define MAX_BPP_SUPPORTED 4

static struct msm_bus_vectors mdp_bus_vectors[] = {
	MDP_BUS_VECTOR_ENTRY(0, 0),
	MDP_BUS_VECTOR_ENTRY(SZ_128M, SZ_256M),
@@ -2271,6 +2278,14 @@ splash_on_err:
static int mdp3_panel_register_done(struct mdss_panel_data *pdata)
{
	int rc = 0;
	u64 ab = 0; u64 ib = 0;
	u64 mdp_clk_rate = 0;

	/* Store max bandwidth supported in mdp res */
	mdp3_calc_dma_res(&pdata->panel_info, &mdp_clk_rate, &ab, &ib,
			MAX_BPP_SUPPORTED);
	do_div(ab, 1024);
	mdp3_res->max_bw = ab+1;

	/*
	* If idle pc feature is not enabled, then get a reference to the
@@ -2428,6 +2443,61 @@ static void mdp3_dma_underrun_intr_handler(int type, void *arg)
	}
}

uint32_t ppp_formats_supported[] = {
	MDP_RGB_565,
	MDP_BGR_565,
	MDP_RGB_888,
	MDP_BGR_888,
	MDP_XRGB_8888,
	MDP_ARGB_8888,
	MDP_RGBA_8888,
	MDP_BGRA_8888,
	MDP_RGBX_8888,
	MDP_Y_CBCR_H2V1,
	MDP_Y_CBCR_H2V2,
	MDP_Y_CBCR_H2V2_ADRENO,
	MDP_Y_CBCR_H2V2_VENUS,
	MDP_Y_CRCB_H2V1,
	MDP_Y_CRCB_H2V2,
	MDP_YCRYCB_H2V1,
	MDP_BGRX_8888,
};

uint32_t dma_formats_supported[] = {
	MDP_RGB_565,
	MDP_RGB_888,
	MDP_XRGB_8888,
};

static void __mdp3_set_supported_formats(void)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(ppp_formats_supported); i++)
		SET_BIT(mdp3_res->ppp_formats, ppp_formats_supported[i]);

	for (i = 0; i < ARRAY_SIZE(dma_formats_supported); i++)
		SET_BIT(mdp3_res->dma_formats, dma_formats_supported[i]);
}

static void __update_format_supported_info(char *buf, int *cnt)
{
	int j;
	size_t len = PAGE_SIZE;
	int num_bytes = BITS_TO_BYTES(MDP_IMGTYPE_LIMIT1);
#define SPRINT(fmt, ...) \
	(*cnt += scnprintf(buf + *cnt, len - *cnt, fmt, ##__VA_ARGS__))

	SPRINT("ppp_input_fmts=");
	for (j = 0; j < num_bytes; j++)
		SPRINT("%d,", mdp3_res->ppp_formats[j]);
	SPRINT("\ndma_output_fmts=");
	for (j = 0; j < num_bytes; j++)
		SPRINT("%d,", mdp3_res->dma_formats[j]);
	SPRINT("\n");
#undef SPRINT
}

static ssize_t mdp3_show_capabilities(struct device *dev,
		struct device_attribute *attr, char *buf)
{
@@ -2437,10 +2507,32 @@ static ssize_t mdp3_show_capabilities(struct device *dev,
#define SPRINT(fmt, ...) \
		(cnt += scnprintf(buf + cnt, len - cnt, fmt, ##__VA_ARGS__))

	SPRINT("dma_pipes=%d\n", 1);
	SPRINT("mdp_version=3\n");
	SPRINT("hw_rev=%d\n", 305);
	SPRINT("pipe_count:%d\n", 1);
	SPRINT("pipe_num:%d pipe_type:dma pipe_ndx:%d rects:%d ", 0, 1, 1);
	SPRINT("pipe_is_handoff:%d display_id:%d\n", 0, 0);
	__update_format_supported_info(buf, &cnt);
	SPRINT("rgb_pipes=%d\n", 0);
	SPRINT("vig_pipes=%d\n", 0);
	SPRINT("dma_pipes=%d\n", 1);
	SPRINT("\n");
	SPRINT("blending_stages=%d\n", 1);
	SPRINT("cursor_pipes=%d\n", 0);
	SPRINT("max_cursor_size=%d\n", 0);
	SPRINT("smp_count=%d\n", 0);
	SPRINT("smp_size=%d\n", 0);
	SPRINT("smp_mb_per_pipe=%d\n", 0);
	SPRINT("max_downscale_ratio=%d\n", PPP_DOWNSCALE_MAX);
	SPRINT("max_upscale_ratio=%d\n", PPP_UPSCALE_MAX);
	SPRINT("max_pipe_bw=%u\n", mdp3_res->max_bw);
	SPRINT("max_bandwidth_low=%u\n", mdp3_res->max_bw);
	SPRINT("max_bandwidth_high=%u\n", mdp3_res->max_bw);
	SPRINT("max_mdp_clk=%u\n", MDP_CORE_CLK_RATE_MAX);
	SPRINT("clk_fudge_factor=%u,%u\n", CLK_FUDGE_NUM, CLK_FUDGE_DEN);
	SPRINT("features=has_ppp\n");

#undef SPRINT

	return cnt;
}
@@ -2812,6 +2904,8 @@ static int mdp3_probe(struct platform_device *pdev)
	if (rc)
		pr_err("mdss smmu init failed\n");

	__mdp3_set_supported_formats();

	mdp3_res->mdss_util->mdp_probe_done = true;
	pr_debug("%s: END\n", __func__);

+16 −0
Original line number Diff line number Diff line
@@ -31,6 +31,9 @@
#define MDP_CORE_CLK_RATE_SUPER_SVS	200000000
#define MDP_CORE_CLK_RATE_MAX	307200000

#define CLK_FUDGE_NUM		12
#define CLK_FUDGE_DEN		10

/* PPP cant work at SVS for panel res above qHD */
#define SVS_MAX_PIXEL		(540 * 960)

@@ -44,6 +47,9 @@
 */
#define MDP_SMART_BLIT                 0xC0000000

#define BITS_PER_BYTE 8
#define MDP_IMGTYPE_LIMIT1 0x100
#define BITS_TO_BYTES(x) DIV_ROUND_UP(x, BITS_PER_BYTE)

enum  {
	MDP3_CLK_AHB,
@@ -204,6 +210,11 @@ struct mdp3_hw_resource {
	bool solid_fill_vote_en;
	struct list_head reg_bus_clist;
	struct mutex reg_bus_lock;

	u32 max_bw;

	u8 ppp_formats[BITS_TO_BYTES(MDP_IMGTYPE_LIMIT1)];
	u8 dma_formats[BITS_TO_BYTES(MDP_IMGTYPE_LIMIT1)];
};

struct mdp3_img_data {
@@ -269,6 +280,11 @@ void mdp3_calc_dma_res(struct mdss_panel_info *panel_info, u64 *clk_rate,
void mdp3_clear_irq(u32 interrupt_mask);
int mdp3_enable_panic_ctrl(void);

int mdp3_layer_pre_commit(struct msm_fb_data_type *mfd,
	struct file *file, struct mdp_layer_commit_v1 *commit);
int mdp3_layer_atomic_validate(struct msm_fb_data_type *mfd,
	struct file *file, struct mdp_layer_commit_v1 *commit);

#define MDP3_REG_WRITE(addr, val) writel_relaxed(val, mdp3_res->mdp_base + addr)
#define MDP3_REG_READ(addr) readl_relaxed(mdp3_res->mdp_base + addr)
#define VBIF_REG_WRITE(off, val) writel_relaxed(val, mdp3_res->vbif_base + off)
+83 −7
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <linux/delay.h>
#include <linux/dma-buf.h>
#include <linux/pm_runtime.h>
#include <linux/sw_sync.h>

#include "mdp3_ctrl.h"
#include "mdp3.h"
@@ -42,8 +43,6 @@ static int mdp3_ctrl_lut_read(struct msm_fb_data_type *mfd,
static int mdp3_ctrl_lut_config(struct msm_fb_data_type *mfd,
				struct mdp_rgb_lut_data *cfg);
static void mdp3_ctrl_pp_resume(struct msm_fb_data_type *mfd);
static int mdp3_ctrl_reset(struct msm_fb_data_type *mfd);
static int mdp3_ctrl_get_pack_pattern(u32 imgType);

u32 mdp_lut_inverse16[MDP_LUT_SIZE] = {
0, 65536, 32768, 21845, 16384, 13107, 10923, 9362, 8192, 7282, 6554, 5958,
@@ -72,7 +71,7 @@ static void mdp3_bufq_init(struct mdp3_buffer_queue *bufq)
	bufq->pop_idx = 0;
}

static void mdp3_bufq_deinit(struct mdp3_buffer_queue *bufq)
void mdp3_bufq_deinit(struct mdp3_buffer_queue *bufq)
{
	int count = bufq->count;

@@ -89,7 +88,7 @@ static void mdp3_bufq_deinit(struct mdp3_buffer_queue *bufq)
	bufq->pop_idx = 0;
}

static int mdp3_bufq_push(struct mdp3_buffer_queue *bufq,
int mdp3_bufq_push(struct mdp3_buffer_queue *bufq,
			struct mdp3_img_data *data)
{
	if (bufq->count >= MDP3_MAX_BUF_QUEUE) {
@@ -206,6 +205,45 @@ retry_dma_done:
	mutex_unlock(&session->lock);
}

static void mdp3_vsync_retire_handle_vsync(void *arg)
{
	struct mdp3_session_data *mdp3_session;

	mdp3_session = (struct mdp3_session_data *)arg;

	if (!mdp3_session) {
		pr_warn("Invalid handle for vsync\n");
		return;
	}

	schedule_work(&mdp3_session->retire_work);
}

static void mdp3_vsync_retire_signal(struct msm_fb_data_type *mfd, int val)
{
	struct mdp3_session_data *mdp3_session;

	mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1;

	mutex_lock(&mfd->mdp_sync_pt_data.sync_mutex);
	if (mdp3_session->retire_cnt > 0) {
		sw_sync_timeline_inc(mdp3_session->vsync_timeline, val);
		mdp3_session->retire_cnt -= min(val, mdp3_session->retire_cnt);
	}
	mutex_unlock(&mfd->mdp_sync_pt_data.sync_mutex);
}

static void mdp3_vsync_retire_work_handler(struct work_struct *work)
{
	struct mdp3_session_data *mdp3_session =
		container_of(work, struct mdp3_session_data, retire_work);

	if (!mdp3_session)
		return;

	mdp3_vsync_retire_signal(mdp3_session->mfd, 1);
}

void vsync_notify_handler(void *arg)
{
	struct mdp3_session_data *session = (struct mdp3_session_data *)arg;
@@ -553,7 +591,7 @@ static int mdp3_ctrl_get_intf_type(struct msm_fb_data_type *mfd)
	return type;
}

static int mdp3_ctrl_get_source_format(u32 imgType)
int mdp3_ctrl_get_source_format(u32 imgType)
{
	int format;
	switch (imgType) {
@@ -573,7 +611,7 @@ static int mdp3_ctrl_get_source_format(u32 imgType)
	return format;
}

static int mdp3_ctrl_get_pack_pattern(u32 imgType)
int mdp3_ctrl_get_pack_pattern(u32 imgType)
{
	int packPattern = MDP3_DMA_OUTPUT_PACK_PATTERN_RGB;
	if (imgType == MDP_RGBA_8888 || imgType == MDP_RGB_888)
@@ -1052,7 +1090,7 @@ off_error:
	return 0;
}

static int mdp3_ctrl_reset(struct msm_fb_data_type *mfd)
int mdp3_ctrl_reset(struct msm_fb_data_type *mfd)
{
	int rc = 0;
	struct mdp3_session_data *mdp3_session;
@@ -2684,6 +2722,33 @@ static int mdp3_update_panel_info(struct msm_fb_data_type *mfd, int mode,
	return 0;
}

static int mdp3_vsync_retire_setup(struct msm_fb_data_type *mfd)
{
	struct mdp3_session_data *mdp3_session;
	struct mdp3_notification retire_client;
	char name[24];

	mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1;

	snprintf(name, sizeof(name), "mdss_fb%d_retire", mfd->index);
	mdp3_session->vsync_timeline = sw_sync_timeline_create(name);
	if (mdp3_session->vsync_timeline == NULL) {
		pr_err("cannot vsync create time line");
		return -ENOMEM;
	}

	/* Add retire vsync handler */
	retire_client.handler = mdp3_vsync_retire_handle_vsync;
	retire_client.arg = mdp3_session;

	if (mdp3_session->dma)
		mdp3_session->dma->retire_client = retire_client;

	INIT_WORK(&mdp3_session->retire_work, mdp3_vsync_retire_work_handler);

	return 0;
}

int mdp3_ctrl_init(struct msm_fb_data_type *mfd)
{
	struct device *dev = mfd->fbi->dev;
@@ -2705,6 +2770,8 @@ int mdp3_ctrl_init(struct msm_fb_data_type *mfd)
	mdp3_interface->dma_fnc = mdp3_ctrl_pan_display;
	mdp3_interface->ioctl_handler = mdp3_ctrl_ioctl_handler;
	mdp3_interface->kickoff_fnc = mdp3_ctrl_display_commit_kickoff;
	mdp3_interface->pre_commit = mdp3_layer_pre_commit;
	mdp3_interface->atomic_validate = mdp3_layer_atomic_validate;
	mdp3_interface->lut_update = NULL;
	mdp3_interface->configure_panel = mdp3_update_panel_info;

@@ -2812,6 +2879,15 @@ int mdp3_ctrl_init(struct msm_fb_data_type *mfd)

	mdp3_session->vsync_before_commit = true;
	mdp3_session->dyn_pu_state = mfd->panel_info->partial_update_enabled;

	if (mfd->panel_info->mipi.dms_mode ||
			mfd->panel_info->type == MIPI_CMD_PANEL) {
		rc = mdp3_vsync_retire_setup(mfd);
		if (IS_ERR_VALUE(rc)) {
			pr_err("unable to create vsync timeline\n");
			goto init_done;
		}
	}
init_done:
	if (IS_ERR_VALUE(rc))
		kfree(mdp3_session);
+11 −0
Original line number Diff line number Diff line
@@ -70,8 +70,19 @@ struct mdp3_session_data {
	bool dma_active;
	struct completion dma_completion;
	int (*wait_for_dma_done)(struct mdp3_session_data *session);

	/* For retire fence */
	struct sw_sync_timeline *vsync_timeline;
	int retire_cnt;
	struct work_struct retire_work;
};

void mdp3_bufq_deinit(struct mdp3_buffer_queue *bufq);
int mdp3_ctrl_init(struct msm_fb_data_type *mfd);
int mdp3_bufq_push(struct mdp3_buffer_queue *bufq,
			struct mdp3_img_data *data);
int mdp3_ctrl_get_source_format(u32 imgType);
int mdp3_ctrl_get_pack_pattern(u32 imgType);
int mdp3_ctrl_reset(struct msm_fb_data_type *mfd);

#endif /* MDP3_CTRL_H */
Loading