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

Commit 0626974e authored by Gopikrishnaiah Anandan's avatar Gopikrishnaiah Anandan Committed by Gerrit - the friendly Code Review server
Browse files

msm: mdss: Add support for mdss v3 ops



Msmcobalt mdss hardware revision has changed to 3.0.
This change adds support for mdp v3 post processing drivers ops.

CRs-Fixed: 985286
Change-Id: Ib098d1e06660c89aa528af3c257dda6b293ca780
Signed-off-by: default avatarGopikrishnaiah Anandan <agopik@codeaurora.org>
Signed-off-by: default avatarPing Li <pingli@codeaurora.org>
parent e3f107e9
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ obj-$(CONFIG_FB_MSM_MDSS) += mdss-mdp.o
obj-$(CONFIG_FB_MSM_MDSS) += mdss_mdp_debug.o

mdss-mdp-objs += mdss_mdp_pp_v1_7.o
mdss-mdp-objs += mdss_mdp_pp_v3.o

ifeq ($(CONFIG_FB_MSM_MDSS),y)
obj-$(CONFIG_DEBUG_FS) += mdss_debug.o mdss_debug_xlog.o
+30 −16
Original line number Diff line number Diff line
@@ -506,7 +506,7 @@ static inline int pp_validate_dspp_mfd_block(struct msm_fb_data_type *mfd,
static int pp_mfd_release_all(struct msm_fb_data_type *mfd);
static int pp_mfd_ad_release_all(struct msm_fb_data_type *mfd);
static int mdss_mdp_ad_ipc_reset(struct msm_fb_data_type *mfd);
static void *pp_get_driver_ops(struct mdp_pp_driver_ops *ops);
static int pp_get_driver_ops(struct mdp_pp_driver_ops *ops);

static u32 last_sts, last_state;

@@ -2773,7 +2773,6 @@ int mdss_mdp_pp_init(struct device *dev)
	struct mdss_data_type *mdata = mdss_mdp_get_mdata();
	struct mdss_mdp_pipe *vig;
	struct pp_hist_col_info *hist;
	void *ret_ptr = NULL;
	u32 ctl_off = 0;

	if (!mdata)
@@ -2795,17 +2794,13 @@ int mdss_mdp_pp_init(struct device *dev)
			if (mdss_mdp_pp_dt_parse(dev))
				pr_info("No PP info in device tree\n");

			ret_ptr = pp_get_driver_ops(&pp_driver_ops);
			if (IS_ERR(ret_ptr)) {
			ret = pp_get_driver_ops(&pp_driver_ops);
			if (ret) {
				pr_err("pp_get_driver_ops failed, ret=%d\n",
						(int) PTR_ERR(ret_ptr));
				ret = PTR_ERR(ret_ptr);
						ret);
				goto pp_exit;
			} else {
				mdss_pp_res->pp_data_v1_7 = ret_ptr;
				pp_ops = pp_driver_ops.pp_ops;
			}

			pp_ops = pp_driver_ops.pp_ops;
			hist = devm_kzalloc(dev,
					sizeof(struct pp_hist_col_info) *
					mdata->ndspp,
@@ -7308,9 +7303,10 @@ static inline int pp_validate_dspp_mfd_block(struct msm_fb_data_type *mfd,
	return 0;
}

static void *pp_get_driver_ops(struct mdp_pp_driver_ops *ops)
static int pp_get_driver_ops(struct mdp_pp_driver_ops *ops)
{
	struct mdss_data_type *mdata = mdss_mdp_get_mdata();
	int ret = 0;
	void *pp_cfg = NULL;

	switch (mdata->mdp_rev) {
@@ -7321,10 +7317,28 @@ static void *pp_get_driver_ops(struct mdp_pp_driver_ops *ops)
	case MDSS_MDP_HW_REV_115:
	case MDSS_MDP_HW_REV_116:
		pp_cfg = pp_get_driver_ops_v1_7(ops);
		if (IS_ERR_OR_NULL(pp_cfg))
			ret = -EINVAL;
		else
			mdss_pp_res->pp_data_v1_7 = pp_cfg;
		break;
	case MDSS_MDP_HW_REV_300:
	case MDSS_MDP_HW_REV_301:
		pp_cfg = pp_get_driver_ops_v3(ops);
		if (IS_ERR_OR_NULL(pp_cfg)) {
			ret = -EINVAL;
		} else {
			mdss_pp_res->pp_data_v1_7 = pp_cfg;
			/* Currently all caching data is used from v17 for V3
			 * hence setting the pointer to NULL. Will be used if we
			 * have to add any caching specific to V3.
			 */
			mdss_pp_res->pp_data_v3 = NULL;
		}
		break;
	default:
		memset(ops, 0, sizeof(struct mdp_pp_driver_ops));
		break;
	}
	return pp_cfg;
	return ret;
}
+2 −0
Original line number Diff line number Diff line
@@ -163,9 +163,11 @@ struct mdss_pp_res_type {
	 * struct.
	 */
	void *pp_data_v1_7;
	void *pp_data_v3;
};

void *pp_get_driver_ops_v1_7(struct mdp_pp_driver_ops *ops);
void *pp_get_driver_ops_v3(struct mdp_pp_driver_ops *ops);


static inline void pp_sts_set_split_bits(u32 *sts, u32 bits)
+141 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#define pr_fmt(fmt)	"%s: " fmt, __func__

#include <linux/uaccess.h>
#include "mdss_fb.h"
#include "mdss_mdp.h"
#include "mdss_mdp_pp.h"


#define IGC_DSPP_OP_MODE_EN BIT(0)

static int pp_pa_set_config(char __iomem *base_addr,
			struct pp_sts_type *pp_sts, void *cfg_data,
			u32 block_type);
static int pp_pa_get_config(char __iomem *base_addr, void *cfg_data,
				u32 block_type, u32 disp_num);
static int pp_pa_get_version(u32 *version);

static int pp_dither_get_config(char __iomem *base_addr, void *cfg_data,
			   u32 block_type, u32 disp_num);
static int pp_dither_set_config(char __iomem *base_addr,
		struct pp_sts_type *pp_sts, void *cfg_data,
		u32 block_type);
static int pp_dither_get_version(u32 *version);

static void pp_opmode_config(int location, struct pp_sts_type *pp_sts,
		u32 *opmode, int side);

void *pp_get_driver_ops_v3(struct mdp_pp_driver_ops *ops)
{
	void *pp_cfg = NULL;

	if (!ops) {
		pr_err("PP driver ops invalid %p\n", ops);
		return ERR_PTR(-EINVAL);
	}

	pp_cfg = pp_get_driver_ops_v1_7(ops);
	if (IS_ERR_OR_NULL(pp_cfg))
		return NULL;
	/* PA ops */
	ops->pp_ops[PA].pp_set_config = pp_pa_set_config;
	ops->pp_ops[PA].pp_get_config = pp_pa_get_config;
	ops->pp_ops[PA].pp_get_version = pp_pa_get_version;

	/* Dither ops */
	ops->pp_ops[DITHER].pp_set_config = pp_dither_set_config;
	ops->pp_ops[DITHER].pp_get_config = pp_dither_get_config;
	ops->pp_ops[DITHER].pp_get_version = pp_dither_get_version;

	/* Set opmode pointers */
	ops->pp_opmode_config = pp_opmode_config;

	ops->gamut_clk_gate_en = NULL;
	return pp_cfg;
}

static int pp_pa_set_config(char __iomem *base_addr,
		struct pp_sts_type *pp_sts, void *cfg_data,
		u32 block_type)
{
	return -EINVAL;
}

static int pp_pa_get_config(char __iomem *base_addr, void *cfg_data,
		u32 block_type, u32 disp_num)
{
	return -EINVAL;
}

static int pp_pa_get_version(u32 *version)
{
	if (!version) {
		pr_err("invalid param version");
		return -EINVAL;
	}
	*version = mdp_pa_v1_7;
	return 0;
}

static int pp_dither_get_config(char __iomem *base_addr, void *cfg_data,
			   u32 block_type, u32 disp_num)
{
	return -EINVAL;
}

static int pp_dither_set_config(char __iomem *base_addr,
		struct pp_sts_type *pp_sts, void *cfg_data,
		u32 block_type)
{
	return -EINVAL;
}

static int pp_dither_get_version(u32 *version)
{
	if (!version) {
		pr_err("invalid param version");
		return -EINVAL;
	}
	*version = mdp_dither_v1_7;
	return 0;
}

static void pp_opmode_config(int location, struct pp_sts_type *pp_sts,
		u32 *opmode, int side)
{
	if (!pp_sts || !opmode) {
		pr_err("Invalid pp_sts %p or opmode %p\n", pp_sts, opmode);
		return;
	}
	switch (location) {
	case SSPP_DMA:
		break;
	case SSPP_VIG:
		break;
	case DSPP:
		if (pp_sts_is_enabled(pp_sts->igc_sts, side))
			*opmode |= IGC_DSPP_OP_MODE_EN;
		break;
	case LM:
		if (pp_sts->argc_sts & PP_STS_ENABLE)
			pr_debug("pgc in LM enabled\n");
		break;
	default:
		pr_err("Invalid block type %d\n", location);
		break;
	}
}