// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2016 BayLibre, SAS
 * Author: Neil Armstrong <narmstrong@baylibre.com>
 * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
 */

#include <linux/clk.h>
#include <linux/component.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>

#include <media/cec-notifier.h>

#include <drm/drm_atomic_helper.h>
#include <drm/drm_bridge.h>
#include <drm/drm_bridge_connector.h>
#include <drm/drm_device.h>
#include <drm/drm_edid.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_simple_kms_helper.h>

#include <linux/media-bus-format.h>
#include <linux/videodev2.h>

#include "meson_drv.h"
#include "meson_registers.h"
#include "meson_vclk.h"
#include "meson_venc.h"
#include "meson_encoder_hdmi.h"

struct meson_encoder_hdmi {
	struct drm_encoder encoder;
	struct drm_bridge bridge;
	struct drm_bridge *next_bridge;
	struct drm_connector *connector;
	struct meson_drm *priv;
	unsigned long output_bus_fmt;
	struct cec_notifier *cec_notifier;
};

#define bridge_to_meson_encoder_hdmi(x) \
	container_of(x, struct meson_encoder_hdmi, bridge)

static int meson_encoder_hdmi_attach(struct drm_bridge *bridge,
				     enum drm_bridge_attach_flags flags)
{
	struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge);

	return drm_bridge_attach(bridge->encoder, encoder_hdmi->next_bridge,
				 &encoder_hdmi->bridge, flags);
}

static void meson_encoder_hdmi_detach(struct drm_bridge *bridge)
{
	struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge);

	cec_notifier_conn_unregister(encoder_hdmi->cec_notifier);
	encoder_hdmi->cec_notifier = NULL;
}

static void meson_encoder_hdmi_set_vclk(struct meson_encoder_hdmi *encoder_hdmi,
					const struct drm_display_mode *mode)
{
	struct meson_drm *priv = encoder_hdmi->priv;
	int vic = drm_match_cea_mode(mode);
	unsigned int phy_freq;
	unsigned int vclk_freq;
	unsigned int venc_freq;
	unsigned int hdmi_freq;

	vclk_freq = mode->clock;

	/* For 420, pixel clock is half unlike venc clock */
	if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24)
		vclk_freq /= 2;

	/* TMDS clock is pixel_clock * 10 */
	phy_freq = vclk_freq * 10;

	if (!vic) {
		meson_vclk_setup(priv, MESON_VCLK_TARGET_DMT, phy_freq,
				 vclk_freq, vclk_freq, vclk_freq, false);
		return;
	}

	/* 480i/576i needs global pixel doubling */
	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
		vclk_freq *= 2;

	venc_freq = vclk_freq;
	hdmi_freq = vclk_freq;

	/* VENC double pixels for 1080i, 720p and YUV420 modes */
	if (meson_venc_hdmi_venc_repeat(vic) ||
	    encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24)
		venc_freq *= 2;

	vclk_freq = max(venc_freq, hdmi_freq);

	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
		venc_freq /= 2;

	dev_dbg(priv->dev, "vclk:%d phy=%d venc=%d hdmi=%d enci=%d\n",
		phy_freq, vclk_freq, venc_freq, hdmi_freq,
		priv->venc.hdmi_use_enci);

	meson_vclk_setup(priv, MESON_VCLK_TARGET_HDMI, phy_freq, vclk_freq,
			 venc_freq, hdmi_freq, priv->venc.hdmi_use_enci);
}

static enum drm_mode_status meson_encoder_hdmi_mode_valid(struct drm_bridge *bridge,
					const struct drm_display_info *display_info,
					const struct drm_display_mode *mode)
{
	struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge);
	struct meson_drm *priv = encoder_hdmi->priv;
	bool is_hdmi2_sink = display_info->hdmi.scdc.supported;
	unsigned int phy_freq;
	unsigned int vclk_freq;
	unsigned int venc_freq;
	unsigned int hdmi_freq;
	int vic = drm_match_cea_mode(mode);
	enum drm_mode_status status;

	dev_dbg(priv->dev, "Modeline " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode));

	/* If sink does not support 540MHz, reject the non-420 HDMI2 modes */
	if (display_info->max_tmds_clock &&
	    mode->clock > display_info->max_tmds_clock &&
	    !drm_mode_is_420_only(display_info, mode) &&
	    !drm_mode_is_420_also(display_info, mode))
		return MODE_BAD;

	/* Check against non-VIC supported modes */
	if (!vic) {
		status = meson_venc_hdmi_supported_mode(mode);
		if (status != MODE_OK)
			return status;

		return meson_vclk_dmt_supported_freq(priv, mode->clock);
	/* Check against supported VIC modes */
	} else if (!meson_venc_hdmi_supported_vic(vic))
		return MODE_BAD;

	vclk_freq = mode->clock;

	/* For 420, pixel clock is half unlike venc clock */
	if (drm_mode_is_420_only(display_info, mode) ||
	    (!is_hdmi2_sink &&
	     drm_mode_is_420_also(display_info, mode)))
		vclk_freq /= 2;

	/* TMDS clock is pixel_clock * 10 */
	phy_freq = vclk_freq * 10;

	/* 480i/576i needs global pixel doubling */
	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
		vclk_freq *= 2;

	venc_freq = vclk_freq;
	hdmi_freq = vclk_freq;

	/* VENC double pixels for 1080i, 720p and YUV420 modes */
	if (meson_venc_hdmi_venc_repeat(vic) ||
	    drm_mode_is_420_only(display_info, mode) ||
	    (!is_hdmi2_sink &&
	     drm_mode_is_420_also(display_info, mode)))
		venc_freq *= 2;

	vclk_freq = max(venc_freq, hdmi_freq);

	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
		venc_freq /= 2;

	dev_dbg(priv->dev, "%s: vclk:%d phy=%d venc=%d hdmi=%d\n",
		__func__, phy_freq, vclk_freq, venc_freq, hdmi_freq);

	return meson_vclk_vic_supported_freq(priv, phy_freq, vclk_freq);
}

static void meson_encoder_hdmi_atomic_enable(struct drm_bridge *bridge,
					     struct drm_bridge_state *bridge_state)
{
	struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge);
	struct drm_atomic_state *state = bridge_state->base.state;
	unsigned int ycrcb_map = VPU_HDMI_OUTPUT_CBYCR;
	struct meson_drm *priv = encoder_hdmi->priv;
	struct drm_connector_state *conn_state;
	const struct drm_display_mode *mode;
	struct drm_crtc_state *crtc_state;
	struct drm_connector *connector;
	bool yuv420_mode = false;
	int vic;

	connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
	if (WARN_ON(!connector))
		return;

	conn_state = drm_atomic_get_new_connector_state(state, connector);
	if (WARN_ON(!conn_state))
		return;

	crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
	if (WARN_ON(!crtc_state))
		return;

	mode = &crtc_state->adjusted_mode;

	vic = drm_match_cea_mode(mode);

	dev_dbg(priv->dev, "\"%s\" vic %d\n", mode->name, vic);

	if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) {
		ycrcb_map = VPU_HDMI_OUTPUT_CRYCB;
		yuv420_mode = true;
	} else if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYVY8_1X16)
		ycrcb_map = VPU_HDMI_OUTPUT_CRYCB;

	/* VENC + VENC-DVI Mode setup */
	meson_venc_hdmi_mode_set(priv, vic, ycrcb_map, yuv420_mode, mode);

	/* VCLK Set clock */
	meson_encoder_hdmi_set_vclk(encoder_hdmi, mode);

	if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24)
		/* Setup YUV420 to HDMI-TX, no 10bit diphering */
		writel_relaxed(2 | (2 << 2),
			       priv->io_base + _REG(VPU_HDMI_FMT_CTRL));
	else if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYVY8_1X16)
		/* Setup YUV422 to HDMI-TX, no 10bit diphering */
		writel_relaxed(1 | (2 << 2),
				priv->io_base + _REG(VPU_HDMI_FMT_CTRL));
	else
		/* Setup YUV444 to HDMI-TX, no 10bit diphering */
		writel_relaxed(0, priv->io_base + _REG(VPU_HDMI_FMT_CTRL));

	dev_dbg(priv->dev, "%s\n", priv->venc.hdmi_use_enci ? "VENCI" : "VENCP");

	if (priv->venc.hdmi_use_enci)
		writel_relaxed(1, priv->io_base + _REG(ENCI_VIDEO_EN));
	else
		writel_relaxed(1, priv->io_base + _REG(ENCP_VIDEO_EN));
}

static void meson_encoder_hdmi_atomic_disable(struct drm_bridge *bridge,
					     struct drm_bridge_state *bridge_state)
{
	struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge);
	struct meson_drm *priv = encoder_hdmi->priv;

	writel_bits_relaxed(0x3, 0,
			    priv->io_base + _REG(VPU_HDMI_SETTING));

	writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN));
	writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN));
}

static const u32 meson_encoder_hdmi_out_bus_fmts[] = {
	MEDIA_BUS_FMT_YUV8_1X24,
	MEDIA_BUS_FMT_UYVY8_1X16,
	MEDIA_BUS_FMT_UYYVYY8_0_5X24,
};

static u32 *
meson_encoder_hdmi_get_inp_bus_fmts(struct drm_bridge *bridge,
					struct drm_bridge_state *bridge_state,
					struct drm_crtc_state *crtc_state,
					struct drm_connector_state *conn_state,
					u32 output_fmt,
					unsigned int *num_input_fmts)
{
	u32 *input_fmts = NULL;
	int i;

	*num_input_fmts = 0;

	for (i = 0 ; i < ARRAY_SIZE(meson_encoder_hdmi_out_bus_fmts) ; ++i) {
		if (output_fmt == meson_encoder_hdmi_out_bus_fmts[i]) {
			*num_input_fmts = 1;
			input_fmts = kcalloc(*num_input_fmts,
					     sizeof(*input_fmts),
					     GFP_KERNEL);
			if (!input_fmts)
				return NULL;

			input_fmts[0] = output_fmt;

			break;
		}
	}

	return input_fmts;
}

static int meson_encoder_hdmi_atomic_check(struct drm_bridge *bridge,
					struct drm_bridge_state *bridge_state,
					struct drm_crtc_state *crtc_state,
					struct drm_connector_state *conn_state)
{
	struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge);
	struct drm_connector_state *old_conn_state =
		drm_atomic_get_old_connector_state(conn_state->state, conn_state->connector);
	struct meson_drm *priv = encoder_hdmi->priv;

	encoder_hdmi->output_bus_fmt = bridge_state->output_bus_cfg.format;

	dev_dbg(priv->dev, "output_bus_fmt %lx\n", encoder_hdmi->output_bus_fmt);

	if (!drm_connector_atomic_hdr_metadata_equal(old_conn_state, conn_state))
		crtc_state->mode_changed = true;

	return 0;
}

static void meson_encoder_hdmi_hpd_notify(struct drm_bridge *bridge,
					  enum drm_connector_status status)
{
	struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge);

	if (!encoder_hdmi->cec_notifier)
		return;

	if (status == connector_status_connected) {
		const struct drm_edid *drm_edid;
		const struct edid *edid;

		drm_edid = drm_bridge_edid_read(encoder_hdmi->next_bridge,
						encoder_hdmi->connector);
		if (!drm_edid)
			return;

		/*
		 * FIXME: The CEC physical address should be set using
		 * cec_notifier_set_phys_addr(encoder_hdmi->cec_notifier,
		 * connector->display_info.source_physical_address) from a path
		 * that has read the EDID and called
		 * drm_edid_connector_update().
		 */
		edid = drm_edid_raw(drm_edid);

		cec_notifier_set_phys_addr_from_edid(encoder_hdmi->cec_notifier, edid);

		drm_edid_free(drm_edid);
	} else
		cec_notifier_phys_addr_invalidate(encoder_hdmi->cec_notifier);
}

static const struct drm_bridge_funcs meson_encoder_hdmi_bridge_funcs = {
	.attach = meson_encoder_hdmi_attach,
	.detach = meson_encoder_hdmi_detach,
	.mode_valid = meson_encoder_hdmi_mode_valid,
	.hpd_notify = meson_encoder_hdmi_hpd_notify,
	.atomic_enable = meson_encoder_hdmi_atomic_enable,
	.atomic_disable = meson_encoder_hdmi_atomic_disable,
	.atomic_get_input_bus_fmts = meson_encoder_hdmi_get_inp_bus_fmts,
	.atomic_check = meson_encoder_hdmi_atomic_check,
	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
	.atomic_reset = drm_atomic_helper_bridge_reset,
};

int meson_encoder_hdmi_probe(struct meson_drm *priv)
{
	struct meson_encoder_hdmi *meson_encoder_hdmi;
	struct platform_device *pdev;
	struct device_node *remote;
	int ret;

	meson_encoder_hdmi = devm_kzalloc(priv->dev, sizeof(*meson_encoder_hdmi), GFP_KERNEL);
	if (!meson_encoder_hdmi)
		return -ENOMEM;

	/* HDMI Transceiver Bridge */
	remote = of_graph_get_remote_node(priv->dev->of_node, 1, 0);
	if (!remote) {
		dev_err(priv->dev, "HDMI transceiver device is disabled");
		return 0;
	}

	meson_encoder_hdmi->next_bridge = of_drm_find_bridge(remote);
	if (!meson_encoder_hdmi->next_bridge) {
		ret = dev_err_probe(priv->dev, -EPROBE_DEFER,
				    "Failed to find HDMI transceiver bridge\n");
		goto err_put_node;
	}

	/* HDMI Encoder Bridge */
	meson_encoder_hdmi->bridge.funcs = &meson_encoder_hdmi_bridge_funcs;
	meson_encoder_hdmi->bridge.of_node = priv->dev->of_node;
	meson_encoder_hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
	meson_encoder_hdmi->bridge.interlace_allowed = true;

	drm_bridge_add(&meson_encoder_hdmi->bridge);

	meson_encoder_hdmi->priv = priv;

	/* Encoder */
	ret = drm_simple_encoder_init(priv->drm, &meson_encoder_hdmi->encoder,
				      DRM_MODE_ENCODER_TMDS);
	if (ret) {
		dev_err_probe(priv->dev, ret, "Failed to init HDMI encoder\n");
		goto err_put_node;
	}

	meson_encoder_hdmi->encoder.possible_crtcs = BIT(0);

	/* Attach HDMI Encoder Bridge to Encoder */
	ret = drm_bridge_attach(&meson_encoder_hdmi->encoder, &meson_encoder_hdmi->bridge, NULL,
				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
	if (ret) {
		dev_err_probe(priv->dev, ret, "Failed to attach bridge\n");
		goto err_put_node;
	}

	/* Initialize & attach Bridge Connector */
	meson_encoder_hdmi->connector = drm_bridge_connector_init(priv->drm,
							&meson_encoder_hdmi->encoder);
	if (IS_ERR(meson_encoder_hdmi->connector)) {
		ret = dev_err_probe(priv->dev,
				    PTR_ERR(meson_encoder_hdmi->connector),
				    "Unable to create HDMI bridge connector\n");
		goto err_put_node;
	}
	drm_connector_attach_encoder(meson_encoder_hdmi->connector,
				     &meson_encoder_hdmi->encoder);

	/*
	 * We should have now in place:
	 * encoder->[hdmi encoder bridge]->[dw-hdmi bridge]->[display connector bridge]->[display connector]
	 */

	/*
	 * drm_connector_attach_max_bpc_property() requires the
	 * connector to have a state.
	 */
	drm_atomic_helper_connector_reset(meson_encoder_hdmi->connector);

	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL) ||
	    meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
	    meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
		drm_connector_attach_hdr_output_metadata_property(meson_encoder_hdmi->connector);

	drm_connector_attach_max_bpc_property(meson_encoder_hdmi->connector, 8, 8);

	/* Handle this here until handled by drm_bridge_connector_init() */
	meson_encoder_hdmi->connector->ycbcr_420_allowed = true;

	pdev = of_find_device_by_node(remote);
	of_node_put(remote);
	if (pdev) {
		struct cec_connector_info conn_info;
		struct cec_notifier *notifier;

		cec_fill_conn_info_from_drm(&conn_info, meson_encoder_hdmi->connector);

		notifier = cec_notifier_conn_register(&pdev->dev, NULL, &conn_info);
		if (!notifier) {
			put_device(&pdev->dev);
			return -ENOMEM;
		}

		meson_encoder_hdmi->cec_notifier = notifier;
	}

	priv->encoders[MESON_ENC_HDMI] = meson_encoder_hdmi;

	dev_dbg(priv->dev, "HDMI encoder initialized\n");

	return 0;

err_put_node:
	of_node_put(remote);
	return ret;
}

void meson_encoder_hdmi_remove(struct meson_drm *priv)
{
	struct meson_encoder_hdmi *meson_encoder_hdmi;

	if (priv->encoders[MESON_ENC_HDMI]) {
		meson_encoder_hdmi = priv->encoders[MESON_ENC_HDMI];
		drm_bridge_remove(&meson_encoder_hdmi->bridge);
	}
}
