162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2013 Red Hat
462306a36Sopenharmony_ci * Author: Rob Clark <robdclark@gmail.com>
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#ifndef __MDP_KMS_H__
862306a36Sopenharmony_ci#define __MDP_KMS_H__
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <linux/clk.h>
1162306a36Sopenharmony_ci#include <linux/platform_device.h>
1262306a36Sopenharmony_ci#include <linux/regulator/consumer.h>
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include "msm_drv.h"
1562306a36Sopenharmony_ci#include "msm_kms.h"
1662306a36Sopenharmony_ci#include "mdp_common.xml.h"
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_cistruct mdp_kms;
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_cistruct mdp_kms_funcs {
2162306a36Sopenharmony_ci	struct msm_kms_funcs base;
2262306a36Sopenharmony_ci	void (*set_irqmask)(struct mdp_kms *mdp_kms, uint32_t irqmask,
2362306a36Sopenharmony_ci		uint32_t old_irqmask);
2462306a36Sopenharmony_ci};
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_cistruct mdp_kms {
2762306a36Sopenharmony_ci	struct msm_kms base;
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci	const struct mdp_kms_funcs *funcs;
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci	/* irq handling: */
3262306a36Sopenharmony_ci	bool in_irq;
3362306a36Sopenharmony_ci	struct list_head irq_list;    /* list of mdp4_irq */
3462306a36Sopenharmony_ci	uint32_t vblank_mask;         /* irq bits set for userspace vblank */
3562306a36Sopenharmony_ci	uint32_t cur_irq_mask;        /* current irq mask */
3662306a36Sopenharmony_ci};
3762306a36Sopenharmony_ci#define to_mdp_kms(x) container_of(x, struct mdp_kms, base)
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_cistatic inline int mdp_kms_init(struct mdp_kms *mdp_kms,
4062306a36Sopenharmony_ci		const struct mdp_kms_funcs *funcs)
4162306a36Sopenharmony_ci{
4262306a36Sopenharmony_ci	mdp_kms->funcs = funcs;
4362306a36Sopenharmony_ci	INIT_LIST_HEAD(&mdp_kms->irq_list);
4462306a36Sopenharmony_ci	return msm_kms_init(&mdp_kms->base, &funcs->base);
4562306a36Sopenharmony_ci}
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_cistatic inline void mdp_kms_destroy(struct mdp_kms *mdp_kms)
4862306a36Sopenharmony_ci{
4962306a36Sopenharmony_ci	msm_kms_destroy(&mdp_kms->base);
5062306a36Sopenharmony_ci}
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci/*
5362306a36Sopenharmony_ci * irq helpers:
5462306a36Sopenharmony_ci */
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci/* For transiently registering for different MDP irqs that various parts
5762306a36Sopenharmony_ci * of the KMS code need during setup/configuration.  These are not
5862306a36Sopenharmony_ci * necessarily the same as what drm_vblank_get/put() are requesting, and
5962306a36Sopenharmony_ci * the hysteresis in drm_vblank_put() is not necessarily desirable for
6062306a36Sopenharmony_ci * internal housekeeping related irq usage.
6162306a36Sopenharmony_ci */
6262306a36Sopenharmony_cistruct mdp_irq {
6362306a36Sopenharmony_ci	struct list_head node;
6462306a36Sopenharmony_ci	uint32_t irqmask;
6562306a36Sopenharmony_ci	bool registered;
6662306a36Sopenharmony_ci	void (*irq)(struct mdp_irq *irq, uint32_t irqstatus);
6762306a36Sopenharmony_ci};
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_civoid mdp_dispatch_irqs(struct mdp_kms *mdp_kms, uint32_t status);
7062306a36Sopenharmony_civoid mdp_update_vblank_mask(struct mdp_kms *mdp_kms, uint32_t mask, bool enable);
7162306a36Sopenharmony_civoid mdp_irq_wait(struct mdp_kms *mdp_kms, uint32_t irqmask);
7262306a36Sopenharmony_civoid mdp_irq_register(struct mdp_kms *mdp_kms, struct mdp_irq *irq);
7362306a36Sopenharmony_civoid mdp_irq_unregister(struct mdp_kms *mdp_kms, struct mdp_irq *irq);
7462306a36Sopenharmony_civoid mdp_irq_update(struct mdp_kms *mdp_kms);
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci/*
7762306a36Sopenharmony_ci * pixel format helpers:
7862306a36Sopenharmony_ci */
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_cistruct mdp_format {
8162306a36Sopenharmony_ci	struct msm_format base;
8262306a36Sopenharmony_ci	enum mdp_bpc bpc_r, bpc_g, bpc_b;
8362306a36Sopenharmony_ci	enum mdp_bpc_alpha bpc_a;
8462306a36Sopenharmony_ci	uint8_t unpack[4];
8562306a36Sopenharmony_ci	bool alpha_enable, unpack_tight;
8662306a36Sopenharmony_ci	uint8_t cpp, unpack_count;
8762306a36Sopenharmony_ci	enum mdp_fetch_type fetch_type;
8862306a36Sopenharmony_ci	enum mdp_chroma_samp_type chroma_sample;
8962306a36Sopenharmony_ci	bool is_yuv;
9062306a36Sopenharmony_ci};
9162306a36Sopenharmony_ci#define to_mdp_format(x) container_of(x, struct mdp_format, base)
9262306a36Sopenharmony_ci#define MDP_FORMAT_IS_YUV(mdp_format) ((mdp_format)->is_yuv)
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ciuint32_t mdp_get_formats(uint32_t *formats, uint32_t max_formats, bool rgb_only);
9562306a36Sopenharmony_ciconst struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format, uint64_t modifier);
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci/* MDP capabilities */
9862306a36Sopenharmony_ci#define MDP_CAP_SMP		BIT(0)	/* Shared Memory Pool                 */
9962306a36Sopenharmony_ci#define MDP_CAP_DSC		BIT(1)	/* VESA Display Stream Compression    */
10062306a36Sopenharmony_ci#define MDP_CAP_CDM		BIT(2)	/* Chroma Down Module (HDMI 2.0 YUV)  */
10162306a36Sopenharmony_ci#define MDP_CAP_SRC_SPLIT	BIT(3)	/* Source Split of SSPPs */
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci/* MDP pipe capabilities */
10462306a36Sopenharmony_ci#define MDP_PIPE_CAP_HFLIP			BIT(0)
10562306a36Sopenharmony_ci#define MDP_PIPE_CAP_VFLIP			BIT(1)
10662306a36Sopenharmony_ci#define MDP_PIPE_CAP_SCALE			BIT(2)
10762306a36Sopenharmony_ci#define MDP_PIPE_CAP_CSC			BIT(3)
10862306a36Sopenharmony_ci#define MDP_PIPE_CAP_DECIMATION			BIT(4)
10962306a36Sopenharmony_ci#define MDP_PIPE_CAP_SW_PIX_EXT			BIT(5)
11062306a36Sopenharmony_ci#define MDP_PIPE_CAP_CURSOR			BIT(6)
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci/* MDP layer mixer caps */
11362306a36Sopenharmony_ci#define MDP_LM_CAP_DISPLAY			BIT(0)
11462306a36Sopenharmony_ci#define MDP_LM_CAP_WB				BIT(1)
11562306a36Sopenharmony_ci#define MDP_LM_CAP_PAIR				BIT(2)
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_cistatic inline bool pipe_supports_yuv(uint32_t pipe_caps)
11862306a36Sopenharmony_ci{
11962306a36Sopenharmony_ci	return (pipe_caps & MDP_PIPE_CAP_SCALE) &&
12062306a36Sopenharmony_ci		(pipe_caps & MDP_PIPE_CAP_CSC);
12162306a36Sopenharmony_ci}
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_cienum csc_type {
12462306a36Sopenharmony_ci	CSC_RGB2RGB = 0,
12562306a36Sopenharmony_ci	CSC_YUV2RGB,
12662306a36Sopenharmony_ci	CSC_RGB2YUV,
12762306a36Sopenharmony_ci	CSC_YUV2YUV,
12862306a36Sopenharmony_ci	CSC_MAX
12962306a36Sopenharmony_ci};
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_cistruct csc_cfg {
13262306a36Sopenharmony_ci	enum csc_type type;
13362306a36Sopenharmony_ci	uint32_t matrix[9];
13462306a36Sopenharmony_ci	uint32_t pre_bias[3];
13562306a36Sopenharmony_ci	uint32_t post_bias[3];
13662306a36Sopenharmony_ci	uint32_t pre_clamp[6];
13762306a36Sopenharmony_ci	uint32_t post_clamp[6];
13862306a36Sopenharmony_ci};
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_cistruct csc_cfg *mdp_get_default_csc_cfg(enum csc_type);
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci#endif /* __MDP_KMS_H__ */
143