/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/* * Copyright (c) 2020 MediaTek Inc. */

#ifndef _MTK_DRM_LOG_H_
#define _MTK_DRM_LOG_H_

#include <linux/module.h>
#include <linux/version.h>
#include <linux/jiffies.h>
#include <linux/compiler.h>
#include <drm/drm_print.h>

//-------------------------------------------------------------------------------------------------
//  Defines
//-------------------------------------------------------------------------------------------------
/* How to use
 * 1. Include this header, ex: #include "mtk_tv_drm_log.h"
 * 2. Define this model type, ex #define MTK_DRM_MODEL MTK_DRM_MODEL_COMMON
 */

/* Redefine DRM_INFO to MTK version */
#ifdef DRM_INFO
#undef DRM_INFO
#endif
#define DRM_INFO(fmt, ...) do {					\
	if (mtk_drm_log_level & MTK_DRM_MODEL) {		\
		_DRM_PRINTK(, INFO, fmt, ##__VA_ARGS__);	\
	}							\
} while (0)

#define MTK_DRM_MODEL_COMMON		BIT(0)
#define MTK_DRM_MODEL_DISPLAY		BIT(1)
#define MTK_DRM_MODEL_PANEL		BIT(2)
#define MTK_DRM_MODEL_CONNECTOR		BIT(3)
#define MTK_DRM_MODEL_CRTC		BIT(4)
#define MTK_DRM_MODEL_DRV		BIT(5)
#define MTK_DRM_MODEL_ENCODER		BIT(6)
#define MTK_DRM_MODEL_FB		BIT(7)
#define MTK_DRM_MODEL_GEM		BIT(8)
#define MTK_DRM_MODEL_KMS		BIT(9)
#define MTK_DRM_MODEL_PATTERN		BIT(10)
#define MTK_DRM_MODEL_PLANE		BIT(11)
#define MTK_DRM_MODEL_VIDEO		BIT(12)
#define MTK_DRM_MODEL_GOP		BIT(13)
#define MTK_DRM_MODEL_DEMURA		BIT(14)
#define MTK_DRM_MODEL_PNLGAMMA		BIT(15)
#define MTK_DRM_MODEL_PQMAP		BIT(16)
#define MTK_DRM_MODEL_AUTOGEN		BIT(17)
#define MTK_DRM_MODEL_TVDAC		BIT(18)
#define MTK_DRM_MODEL_METABUF		BIT(19)
#define MTK_DRM_MODEL_FENCE		BIT(20)
#define MTK_DRM_MODEL_PQU_METADATA	BIT(21)
#define MTK_DRM_MODEL_OLED		BIT(22)
#define MTK_DRM_MODEL_LD		BIT(23)
#define MTK_DRM_MODEL_GLOBAL_PQ		BIT(24)
#define MTK_DRM_MODEL_SCRIPTMGT_ML	BIT(25)
#define MTK_DRM_MODEL_FRC		BIT(26)
#define MTK_DRM_MODEL_VRR		BIT(27)

#define SYSFS_PRCONT(len, buf, fmt, ...) ({ \
	if (len < PAGE_SIZE) { \
		int __ret = snprintf(buf + len, PAGE_SIZE - len, fmt, ##__VA_ARGS__); \
		len += (__ret > 0 && __ret < PAGE_SIZE - len) ? __ret : 0; \
	} \
	len; })

#define SYSFS_PRINT(len, buf, fmt, ...) SYSFS_PRCONT(len, buf, fmt "\n", ##__VA_ARGS__)

//-------------------------------------------------------------------------------------------------
//  Enum
//-------------------------------------------------------------------------------------------------
enum MTK_TV_DRM_LOGREC_TYPE {
	MTK_TV_DRM_LOGREC_BACKLIGHT,
	MTK_TV_DRM_LOGREC_PQ_GAMMA,
	MTK_TV_DRM_LOGREC_PANEL_GAMMA,
	MTK_TV_DRM_LOGREC_VIDEO_MUTE_USER,
	MTK_TV_DRM_LOGREC_VIDEO_MUTE_DUMMY,
	MTK_TV_DRM_LOGREC_VIDEO_MUTE_HWREG,
	MTK_TV_DRM_LOGREC_VIDEO_PLANE_PROP_INPUT,
	MTK_TV_DRM_LOGREC_VIDEO_FRAME_BUFFER,
	MTK_TV_DRM_LOGREC_PANEL,
	MTK_TV_DRM_LOGREC_FRAMESYNC,
	MTK_TV_DRM_LOGREC_PANEL_MUTE,
	MTK_TV_DRM_LOGREC_PANEL_POWER_SEQ,
	MTK_TV_DRM_LOGREC_TYPE_MAX,
};

//-------------------------------------------------------------------------------------------------
//  Structures
//-------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------
//  Global Variables
//-------------------------------------------------------------------------------------------------
extern uint32_t mtk_drm_log_level;

//-------------------------------------------------------------------------------------------------
//  Global Functions
//-------------------------------------------------------------------------------------------------
extern int boottime_print(const char *s);

ssize_t log_level_show(struct device *dev,
	struct device_attribute *attr, char *buf);

ssize_t log_level_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count);

int mtk_tv_drm_logrec_write(enum MTK_TV_DRM_LOGREC_TYPE type,
	const char *format, ...) __printf(2, 3);

int mtk_tv_drm_logrec_read(enum MTK_TV_DRM_LOGREC_TYPE type,
	char *buffer, uint32_t *length);

#endif

