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

#define pr_fmt(fmt) "dprx: " fmt

#include "mtk_srccap_dprx.h"
#include "hwreg_srccap_dprx_dsc.h"

int mtk_dprx_dsc_enable(struct dprx_device *dev,
			enum v4l2_srccap_input_source port,
			enum dprx_dsc_hw_mux dsc_hw_select,
			bool enable)
{
	DPRx_ID dprx_id;
	DP_DSC_HW_SELECT hw_select;

	if (!mtk_dprx_is_valid_input_port(dev, port))
		return -1;

	switch (dsc_hw_select) {
	case DPRX_DSC_0:
		hw_select = DP_DSC0_8K;
		break;
	case DPRX_DSC_1:
		hw_select = DP_DSC1_4K;
		break;
	case DPRX_DSC_MAX:
	default:
		hw_select = DP_DSC_MAX;
		break;
	}

	/* currently we does not support DSC_0 */
	if (hw_select == DP_DSC0_8K || hw_select == DP_DSC_MAX)
		return -1;

	dprx_id = mtk_dprx_input_to_dprx_id(dev, port);

	KDrv_SRCCAP_DPRx_dsc_enable(dprx_id, hw_select, enable);

	return 0;
}
EXPORT_SYMBOL(mtk_dprx_dsc_enable);

int mtk_dprx_dsc_get_output_crc(struct dprx_device *dev,
				enum v4l2_srccap_input_source port,
				u8 *crc)
{
	DPRx_ID dprx_id;

	if (!mtk_dprx_is_valid_input_port(dev, port))
		return -1;

	if (!crc)
		return -1;

	dprx_id = mtk_dprx_input_to_dprx_id(dev, port);

	// u8 crc[6] output_crc * 3
	KDrv_SRCCAP_DPRx_dsc_get_video_stream_crc(dprx_id, crc);

	return 0;
}
EXPORT_SYMBOL(mtk_dprx_dsc_get_output_crc);

int mtk_dprx_dsc_get_input_crc(struct dprx_device *dev,
			       enum dprx_dsc_hw_mux dsc_hw_select,
			       u16 *crc)
{
	DP_DSC_HW_SELECT hw_select;

	if (!crc)
		return -1;

	switch (dsc_hw_select) {
	case DPRX_DSC_0:
		hw_select = DP_DSC0_8K;
		break;
	case DPRX_DSC_1:
		hw_select = DP_DSC1_4K;
		break;
	case DPRX_DSC_MAX:
	default:
		hw_select = DP_DSC_MAX;
		break;
	}

	/* currently we does not support DSC_0 */
	if (hw_select == DP_DSC0_8K || hw_select == DP_DSC_MAX)
		return -1;

	// u16 crc[3] input_crc * 3, only valid with dsc stream
	KDrv_SRCCAP_DPRx_dsc_get_input_crc_value(hw_select, crc);

	return 0;
}
EXPORT_SYMBOL(mtk_dprx_dsc_get_input_crc);

int mtk_dprx_dsc_get_pps(struct dprx_device *dev,
			 enum v4l2_srccap_input_source port)
{
	DPRx_ID dprx_id;

	if (!mtk_dprx_is_valid_input_port(dev, port))
		return -1;

	dprx_id = mtk_dprx_input_to_dprx_id(dev, port);

	// TODO:

	return 0;
}
EXPORT_SYMBOL(mtk_dprx_dsc_get_pps);

bool mtk_dprx_dsc_inputsignal_enable_dsc(struct dprx_device *dev,
			 enum v4l2_srccap_input_source port)
{
	DPRx_ID dprx_id;

	if (!mtk_dprx_is_valid_input_port(dev, port))
		return false;

	dprx_id = mtk_dprx_input_to_dprx_id(dev, port);

	return KDrv_SRCCAP_DPRx_dsc_is_inputsignal_enable_dsc(dprx_id);
}
EXPORT_SYMBOL(mtk_dprx_dsc_inputsignal_enable_dsc);
