// SPDX-License-Identifier: GPL-2.0-only
/*
 * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved.
 *
 * Parts of this file were based on sources as follows:
 *
 * Copyright (c) 2006-2008 Intel Corporation
 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
 * Copyright (C) 2011 Texas Instruments
 */

#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/dma-buf.h>
#include <linux/media-bus-format.h>
#include <linux/of_graph.h>

#include <drm/drm_fb_dma_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_vblank.h>

#include "pl111_drm.h"

irqreturn_t pl111_irq(int irq, void *data)
{
	struct pl111_drm_dev_private *priv = data;
	u32 irq_stat;
	irqreturn_t status = IRQ_NONE;

	irq_stat = readl(priv->regs + CLCD_PL111_MIS);

	if (!irq_stat)
		return IRQ_NONE;

	if (irq_stat & CLCD_IRQ_NEXTBASE_UPDATE) {
		drm_crtc_handle_vblank(&priv->pipe.crtc);

		status = IRQ_HANDLED;
	}

	/* Clear the interrupt once done */
	writel(irq_stat, priv->regs + CLCD_PL111_ICR);

	return status;
}

static enum drm_mode_status
pl111_mode_valid(struct drm_simple_display_pipe *pipe,
		 const struct drm_display_mode *mode)
{
	struct drm_device *drm = pipe->crtc.dev;
	struct pl111_drm_dev_private *priv = drm->dev_private;
	u32 cpp = DIV_ROUND_UP(priv->variant->fb_depth, 8);
	u64 bw;

	/*
	 * We use the pixelclock to also account for interlaced modes, the
	 * resulting bandwidth is in bytes per second.
	 */
	bw = mode->clock * 1000ULL; /* In Hz */
	bw = bw * mode->hdisplay * mode->vdisplay * cpp;
	bw = div_u64(bw, mode->htotal * mode->vtotal);

	/*
	 * If no bandwidth constraints, anything goes, else
	 * check if we are too fast.
	 */
	if (priv->memory_bw && (bw > priv->memory_bw)) {
		DRM_DEBUG_KMS("%d x %d @ %d Hz, %d cpp, bw %llu too fast\n",
			      mode->hdisplay, mode->vdisplay,
			      mode->clock * 1000, cpp, bw);

		return MODE_BAD;
	}
	DRM_DEBUG_KMS("%d x %d @ %d Hz, %d cpp, bw %llu bytes/s OK\n",
		      mode->hdisplay, mode->vdisplay,
		      mode->clock * 1000, cpp, bw);

	return MODE_OK;
}

static int pl111_display_check(struct drm_simple_display_pipe *pipe,
			       struct drm_plane_state *pstate,
			       struct drm_crtc_state *cstate)
{
	const struct drm_display_mode *mode = &cstate->mode;
	struct drm_framebuffer *old_fb = pipe->plane.state->fb;
	struct drm_framebuffer *fb = pstate->fb;

	if (mode->hdisplay % 16)
		return -EINVAL;

	if (fb) {
		u32 offset = drm_fb_dma_get_gem_addr(fb, pstate, 0);

		/* FB base address must be dword aligned. */
		if (offset & 3)
			return -EINVAL;

		/* There's no pitch register -- the mode's hdisplay
		 * controls it.
		 */
		if (fb->pitches[0] != mode->hdisplay * fb->format->cpp[0])
			return -EINVAL;

		/* We can't change the FB format in a flicker-free
		 * manner (and only update it during CRTC enable).
		 */
		if (old_fb && old_fb->format != fb->format)
			cstate->mode_changed = true;
	}

	return 0;
}

static void pl111_display_enable(struct drm_simple_display_pipe *pipe,
				 struct drm_crtc_state *cstate,
				 struct drm_plane_state *plane_state)
{
	struct drm_crtc *crtc = &pipe->crtc;
	struct drm_plane *plane = &pipe->plane;
	struct drm_device *drm = crtc->dev;
	struct pl111_drm_dev_private *priv = drm->dev_private;
	const struct drm_display_mode *mode = &cstate->mode;
	struct drm_framebuffer *fb = plane->state->fb;
	struct drm_connector *connector = priv->connector;
	struct drm_bridge *bridge = priv->bridge;
	bool grayscale = false;
	u32 cntl;
	u32 ppl, hsw, hfp, hbp;
	u32 lpp, vsw, vfp, vbp;
	u32 cpl, tim2;
	int ret;

	ret = clk_set_rate(priv->clk, mode->clock * 1000);
	if (ret) {
		dev_err(drm->dev,
			"Failed to set pixel clock rate to %d: %d\n",
			mode->clock * 1000, ret);
	}

	clk_prepare_enable(priv->clk);

	ppl = (mode->hdisplay / 16) - 1;
	hsw = mode->hsync_end - mode->hsync_start - 1;
	hfp = mode->hsync_start - mode->hdisplay - 1;
	hbp = mode->htotal - mode->hsync_end - 1;

	lpp = mode->vdisplay - 1;
	vsw = mode->vsync_end - mode->vsync_start - 1;
	vfp = mode->vsync_start - mode->vdisplay;
	vbp = mode->vtotal - mode->vsync_end;

	cpl = mode->hdisplay - 1;

	writel((ppl << 2) |
	       (hsw << 8) |
	       (hfp << 16) |
	       (hbp << 24),
	       priv->regs + CLCD_TIM0);
	writel(lpp |
	       (vsw << 10) |
	       (vfp << 16) |
	       (vbp << 24),
	       priv->regs + CLCD_TIM1);

	spin_lock(&priv->tim2_lock);

	tim2 = readl(priv->regs + CLCD_TIM2);
	tim2 &= (TIM2_BCD | TIM2_PCD_LO_MASK | TIM2_PCD_HI_MASK);

	if (priv->variant->broken_clockdivider)
		tim2 |= TIM2_BCD;

	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
		tim2 |= TIM2_IHS;

	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
		tim2 |= TIM2_IVS;

	if (connector) {
		if (connector->display_info.bus_flags & DRM_BUS_FLAG_DE_LOW)
			tim2 |= TIM2_IOE;

		if (connector->display_info.bus_flags &
		    DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
			tim2 |= TIM2_IPC;

		if (connector->display_info.num_bus_formats == 1 &&
		    connector->display_info.bus_formats[0] ==
		    MEDIA_BUS_FMT_Y8_1X8)
			grayscale = true;

		/*
		 * The AC pin bias frequency is set to max count when using
		 * grayscale so at least once in a while we will reverse
		 * polarity and get rid of any DC built up that could
		 * damage the display.
		 */
		if (grayscale)
			tim2 |= TIM2_ACB_MASK;
	}

	if (bridge) {
		const struct drm_bridge_timings *btimings = bridge->timings;

		/*
		 * Here is when things get really fun. Sometimes the bridge
		 * timings are such that the signal out from PL11x is not
		 * stable before the receiving bridge (such as a dumb VGA DAC
		 * or similar) samples it. If that happens, we compensate by
		 * the only method we have: output the data on the opposite
		 * edge of the clock so it is for sure stable when it gets
		 * sampled.
		 *
		 * The PL111 manual does not contain proper timining diagrams
		 * or data for these details, but we know from experiments
		 * that the setup time is more than 3000 picoseconds (3 ns).
		 * If we have a bridge that requires the signal to be stable
		 * earlier than 3000 ps before the clock pulse, we have to
		 * output the data on the opposite edge to avoid flicker.
		 */
		if (btimings && btimings->setup_time_ps >= 3000)
			tim2 ^= TIM2_IPC;
	}

	tim2 |= cpl << 16;
	writel(tim2, priv->regs + CLCD_TIM2);
	spin_unlock(&priv->tim2_lock);

	writel(0, priv->regs + CLCD_TIM3);

	/*
	 * Detect grayscale bus format. We do not support a grayscale mode
	 * toward userspace, instead we expose an RGB24 buffer and then the
	 * hardware will activate its grayscaler to convert to the grayscale
	 * format.
	 */
	if (grayscale)
		cntl = CNTL_LCDEN | CNTL_LCDMONO8;
	else
		/* Else we assume TFT display */
		cntl = CNTL_LCDEN | CNTL_LCDTFT | CNTL_LCDVCOMP(1);

	/* On the ST Micro variant, assume all 24 bits are connected */
	if (priv->variant->st_bitmux_control)
		cntl |= CNTL_ST_CDWID_24;

	/*
	 * Note that the ARM hardware's format reader takes 'r' from
	 * the low bit, while DRM formats list channels from high bit
	 * to low bit as you read left to right. The ST Micro version of
	 * the PL110 (LCDC) however uses the standard DRM format.
	 */
	switch (fb->format->format) {
	case DRM_FORMAT_BGR888:
		/* Only supported on the ST Micro variant */
		if (priv->variant->st_bitmux_control)
			cntl |= CNTL_ST_LCDBPP24_PACKED | CNTL_BGR;
		break;
	case DRM_FORMAT_RGB888:
		/* Only supported on the ST Micro variant */
		if (priv->variant->st_bitmux_control)
			cntl |= CNTL_ST_LCDBPP24_PACKED;
		break;
	case DRM_FORMAT_ABGR8888:
	case DRM_FORMAT_XBGR8888:
		if (priv->variant->st_bitmux_control)
			cntl |= CNTL_LCDBPP24 | CNTL_BGR;
		else
			cntl |= CNTL_LCDBPP24;
		break;
	case DRM_FORMAT_ARGB8888:
	case DRM_FORMAT_XRGB8888:
		if (priv->variant->st_bitmux_control)
			cntl |= CNTL_LCDBPP24;
		else
			cntl |= CNTL_LCDBPP24 | CNTL_BGR;
		break;
	case DRM_FORMAT_BGR565:
		if (priv->variant->is_pl110)
			cntl |= CNTL_LCDBPP16;
		else if (priv->variant->st_bitmux_control)
			cntl |= CNTL_LCDBPP16 | CNTL_ST_1XBPP_565 | CNTL_BGR;
		else
			cntl |= CNTL_LCDBPP16_565;
		break;
	case DRM_FORMAT_RGB565:
		if (priv->variant->is_pl110)
			cntl |= CNTL_LCDBPP16 | CNTL_BGR;
		else if (priv->variant->st_bitmux_control)
			cntl |= CNTL_LCDBPP16 | CNTL_ST_1XBPP_565;
		else
			cntl |= CNTL_LCDBPP16_565 | CNTL_BGR;
		break;
	case DRM_FORMAT_ABGR1555:
	case DRM_FORMAT_XBGR1555:
		cntl |= CNTL_LCDBPP16;
		if (priv->variant->st_bitmux_control)
			cntl |= CNTL_ST_1XBPP_5551 | CNTL_BGR;
		break;
	case DRM_FORMAT_ARGB1555:
	case DRM_FORMAT_XRGB1555:
		cntl |= CNTL_LCDBPP16;
		if (priv->variant->st_bitmux_control)
			cntl |= CNTL_ST_1XBPP_5551;
		else
			cntl |= CNTL_BGR;
		break;
	case DRM_FORMAT_ABGR4444:
	case DRM_FORMAT_XBGR4444:
		cntl |= CNTL_LCDBPP16_444;
		if (priv->variant->st_bitmux_control)
			cntl |= CNTL_ST_1XBPP_444 | CNTL_BGR;
		break;
	case DRM_FORMAT_ARGB4444:
	case DRM_FORMAT_XRGB4444:
		cntl |= CNTL_LCDBPP16_444;
		if (priv->variant->st_bitmux_control)
			cntl |= CNTL_ST_1XBPP_444;
		else
			cntl |= CNTL_BGR;
		break;
	default:
		WARN_ONCE(true, "Unknown FB format 0x%08x\n",
			  fb->format->format);
		break;
	}

	/* The PL110 in Integrator/Versatile does the BGR routing externally */
	if (priv->variant->external_bgr)
		cntl &= ~CNTL_BGR;

	/* Power sequence: first enable and chill */
	writel(cntl, priv->regs + priv->ctrl);

	/*
	 * We expect this delay to stabilize the contrast
	 * voltage Vee as stipulated by the manual
	 */
	msleep(20);

	if (priv->variant_display_enable)
		priv->variant_display_enable(drm, fb->format->format);

	/* Power Up */
	cntl |= CNTL_LCDPWR;
	writel(cntl, priv->regs + priv->ctrl);

	if (!priv->variant->broken_vblank)
		drm_crtc_vblank_on(crtc);
}

static void pl111_display_disable(struct drm_simple_display_pipe *pipe)
{
	struct drm_crtc *crtc = &pipe->crtc;
	struct drm_device *drm = crtc->dev;
	struct pl111_drm_dev_private *priv = drm->dev_private;
	u32 cntl;

	if (!priv->variant->broken_vblank)
		drm_crtc_vblank_off(crtc);

	/* Power Down */
	cntl = readl(priv->regs + priv->ctrl);
	if (cntl & CNTL_LCDPWR) {
		cntl &= ~CNTL_LCDPWR;
		writel(cntl, priv->regs + priv->ctrl);
	}

	/*
	 * We expect this delay to stabilize the contrast voltage Vee as
	 * stipulated by the manual
	 */
	msleep(20);

	if (priv->variant_display_disable)
		priv->variant_display_disable(drm);

	/* Disable */
	writel(0, priv->regs + priv->ctrl);

	clk_disable_unprepare(priv->clk);
}

static void pl111_display_update(struct drm_simple_display_pipe *pipe,
				 struct drm_plane_state *old_pstate)
{
	struct drm_crtc *crtc = &pipe->crtc;
	struct drm_device *drm = crtc->dev;
	struct pl111_drm_dev_private *priv = drm->dev_private;
	struct drm_pending_vblank_event *event = crtc->state->event;
	struct drm_plane *plane = &pipe->plane;
	struct drm_plane_state *pstate = plane->state;
	struct drm_framebuffer *fb = pstate->fb;

	if (fb) {
		u32 addr = drm_fb_dma_get_gem_addr(fb, pstate, 0);

		writel(addr, priv->regs + CLCD_UBAS);
	}

	if (event) {
		crtc->state->event = NULL;

		spin_lock_irq(&crtc->dev->event_lock);
		if (crtc->state->active && drm_crtc_vblank_get(crtc) == 0)
			drm_crtc_arm_vblank_event(crtc, event);
		else
			drm_crtc_send_vblank_event(crtc, event);
		spin_unlock_irq(&crtc->dev->event_lock);
	}
}

static int pl111_display_enable_vblank(struct drm_simple_display_pipe *pipe)
{
	struct drm_crtc *crtc = &pipe->crtc;
	struct drm_device *drm = crtc->dev;
	struct pl111_drm_dev_private *priv = drm->dev_private;

	writel(CLCD_IRQ_NEXTBASE_UPDATE, priv->regs + priv->ienb);

	return 0;
}

static void pl111_display_disable_vblank(struct drm_simple_display_pipe *pipe)
{
	struct drm_crtc *crtc = &pipe->crtc;
	struct drm_device *drm = crtc->dev;
	struct pl111_drm_dev_private *priv = drm->dev_private;

	writel(0, priv->regs + priv->ienb);
}

static struct drm_simple_display_pipe_funcs pl111_display_funcs = {
	.mode_valid = pl111_mode_valid,
	.check = pl111_display_check,
	.enable = pl111_display_enable,
	.disable = pl111_display_disable,
	.update = pl111_display_update,
};

static int pl111_clk_div_choose_div(struct clk_hw *hw, unsigned long rate,
				    unsigned long *prate, bool set_parent)
{
	int best_div = 1, div;
	struct clk_hw *parent = clk_hw_get_parent(hw);
	unsigned long best_prate = 0;
	unsigned long best_diff = ~0ul;
	int max_div = (1 << (TIM2_PCD_LO_BITS + TIM2_PCD_HI_BITS)) - 1;

	for (div = 1; div < max_div; div++) {
		unsigned long this_prate, div_rate, diff;

		if (set_parent)
			this_prate = clk_hw_round_rate(parent, rate * div);
		else
			this_prate = *prate;
		div_rate = DIV_ROUND_UP_ULL(this_prate, div);
		diff = abs(rate - div_rate);

		if (diff < best_diff) {
			best_div = div;
			best_diff = diff;
			best_prate = this_prate;
		}
	}

	*prate = best_prate;
	return best_div;
}

static long pl111_clk_div_round_rate(struct clk_hw *hw, unsigned long rate,
				     unsigned long *prate)
{
	int div = pl111_clk_div_choose_div(hw, rate, prate, true);

	return DIV_ROUND_UP_ULL(*prate, div);
}

static unsigned long pl111_clk_div_recalc_rate(struct clk_hw *hw,
					       unsigned long prate)
{
	struct pl111_drm_dev_private *priv =
		container_of(hw, struct pl111_drm_dev_private, clk_div);
	u32 tim2 = readl(priv->regs + CLCD_TIM2);
	int div;

	if (tim2 & TIM2_BCD)
		return prate;

	div = tim2 & TIM2_PCD_LO_MASK;
	div |= (tim2 & TIM2_PCD_HI_MASK) >>
		(TIM2_PCD_HI_SHIFT - TIM2_PCD_LO_BITS);
	div += 2;

	return DIV_ROUND_UP_ULL(prate, div);
}

static int pl111_clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
				  unsigned long prate)
{
	struct pl111_drm_dev_private *priv =
		container_of(hw, struct pl111_drm_dev_private, clk_div);
	int div = pl111_clk_div_choose_div(hw, rate, &prate, false);
	u32 tim2;

	spin_lock(&priv->tim2_lock);
	tim2 = readl(priv->regs + CLCD_TIM2);
	tim2 &= ~(TIM2_BCD | TIM2_PCD_LO_MASK | TIM2_PCD_HI_MASK);

	if (div == 1) {
		tim2 |= TIM2_BCD;
	} else {
		div -= 2;
		tim2 |= div & TIM2_PCD_LO_MASK;
		tim2 |= (div >> TIM2_PCD_LO_BITS) << TIM2_PCD_HI_SHIFT;
	}

	writel(tim2, priv->regs + CLCD_TIM2);
	spin_unlock(&priv->tim2_lock);

	return 0;
}

static const struct clk_ops pl111_clk_div_ops = {
	.recalc_rate = pl111_clk_div_recalc_rate,
	.round_rate = pl111_clk_div_round_rate,
	.set_rate = pl111_clk_div_set_rate,
};

static int
pl111_init_clock_divider(struct drm_device *drm)
{
	struct pl111_drm_dev_private *priv = drm->dev_private;
	struct clk *parent = devm_clk_get(drm->dev, "clcdclk");
	struct clk_hw *div = &priv->clk_div;
	const char *parent_name;
	struct clk_init_data init = {
		.name = "pl111_div",
		.ops = &pl111_clk_div_ops,
		.parent_names = &parent_name,
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	};
	int ret;

	if (IS_ERR(parent)) {
		dev_err(drm->dev, "CLCD: unable to get clcdclk.\n");
		return PTR_ERR(parent);
	}

	spin_lock_init(&priv->tim2_lock);

	/* If the clock divider is broken, use the parent directly */
	if (priv->variant->broken_clockdivider) {
		priv->clk = parent;
		return 0;
	}
	parent_name = __clk_get_name(parent);
	div->init = &init;

	ret = devm_clk_hw_register(drm->dev, div);

	priv->clk = div->clk;
	return ret;
}

int pl111_display_init(struct drm_device *drm)
{
	struct pl111_drm_dev_private *priv = drm->dev_private;
	int ret;

	ret = pl111_init_clock_divider(drm);
	if (ret)
		return ret;

	if (!priv->variant->broken_vblank) {
		pl111_display_funcs.enable_vblank = pl111_display_enable_vblank;
		pl111_display_funcs.disable_vblank = pl111_display_disable_vblank;
	}

	ret = drm_simple_display_pipe_init(drm, &priv->pipe,
					   &pl111_display_funcs,
					   priv->variant->formats,
					   priv->variant->nformats,
					   NULL,
					   priv->connector);
	if (ret)
		return ret;

	return 0;
}
