// SPDX-License-Identifier: GPL-2.0+
// Copyright 2018 IBM Corporation

#include <linux/clk.h>
#include <linux/reset.h>
#include <linux/regmap.h>

#include <drm/drm_crtc_helper.h>
#include <drm/drm_device.h>
#include <drm/drm_fb_cma_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_gem_cma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_panel.h>
#include <drm/drm_simple_kms_helper.h>
#include <drm/drm_vblank.h>

#include "aspeed_gfx.h"

static struct aspeed_gfx *
drm_pipe_to_aspeed_gfx(struct drm_simple_display_pipe *pipe)
{
	return container_of(pipe, struct aspeed_gfx, pipe);
}

static int aspeed_gfx_set_pixel_fmt(struct aspeed_gfx *priv, u32 *bpp)
{
	struct drm_crtc *crtc = &priv->pipe.crtc;
	struct drm_device *drm = crtc->dev;
	const u32 format = crtc->primary->state->fb->format->format;
	u32 ctrl1;

	ctrl1 = readl(priv->base + CRT_CTRL1);
	ctrl1 &= ~CRT_CTRL_COLOR_MASK;

	switch (format) {
	case DRM_FORMAT_RGB565:
		dev_dbg(drm->dev, "Setting up RGB565 mode\n");
		ctrl1 |= CRT_CTRL_COLOR_RGB565;
		*bpp = 16;
		break;
	case DRM_FORMAT_XRGB8888:
		dev_dbg(drm->dev, "Setting up XRGB8888 mode\n");
		ctrl1 |= CRT_CTRL_COLOR_XRGB8888;
		*bpp = 32;
		break;
	default:
		dev_err(drm->dev, "Unhandled pixel format %08x\n", format);
		return -EINVAL;
	}

	writel(ctrl1, priv->base + CRT_CTRL1);

	return 0;
}

static void aspeed_gfx_enable_controller(struct aspeed_gfx *priv)
{
	u32 ctrl1 = readl(priv->base + CRT_CTRL1);
	u32 ctrl2 = readl(priv->base + CRT_CTRL2);

	/* SCU2C: set DAC source for display output to Graphics CRT (GFX) */
	regmap_update_bits(priv->scu, 0x2c, BIT(16), BIT(16));

	writel(ctrl1 | CRT_CTRL_EN, priv->base + CRT_CTRL1);
	writel(ctrl2 | CRT_CTRL_DAC_EN, priv->base + CRT_CTRL2);
}

static void aspeed_gfx_disable_controller(struct aspeed_gfx *priv)
{
	u32 ctrl1 = readl(priv->base + CRT_CTRL1);
	u32 ctrl2 = readl(priv->base + CRT_CTRL2);

	writel(ctrl1 & ~CRT_CTRL_EN, priv->base + CRT_CTRL1);
	writel(ctrl2 & ~CRT_CTRL_DAC_EN, priv->base + CRT_CTRL2);

	regmap_update_bits(priv->scu, 0x2c, BIT(16), 0);
}

static void aspeed_gfx_crtc_mode_set_nofb(struct aspeed_gfx *priv)
{
	struct drm_display_mode *m = &priv->pipe.crtc.state->adjusted_mode;
	u32 ctrl1, d_offset, t_count, bpp;
	int err;

	err = aspeed_gfx_set_pixel_fmt(priv, &bpp);
	if (err)
		return;

#if 0
	/* TODO: we have only been able to test with the 40MHz USB clock. The
	 * clock is fixed, so we cannot adjust it here. */
	clk_set_rate(priv->pixel_clk, m->crtc_clock * 1000);
#endif

	ctrl1 = readl(priv->base + CRT_CTRL1);
	ctrl1 &= ~(CRT_CTRL_INTERLACED |
			CRT_CTRL_HSYNC_NEGATIVE |
			CRT_CTRL_VSYNC_NEGATIVE);

	if (m->flags & DRM_MODE_FLAG_INTERLACE)
		ctrl1 |= CRT_CTRL_INTERLACED;

	if (!(m->flags & DRM_MODE_FLAG_PHSYNC))
		ctrl1 |= CRT_CTRL_HSYNC_NEGATIVE;

	if (!(m->flags & DRM_MODE_FLAG_PVSYNC))
		ctrl1 |= CRT_CTRL_VSYNC_NEGATIVE;

	writel(ctrl1, priv->base + CRT_CTRL1);

	/* Horizontal timing */
	writel(CRT_H_TOTAL(m->htotal - 1) | CRT_H_DE(m->hdisplay - 1),
			priv->base + CRT_HORIZ0);
	writel(CRT_H_RS_START(m->hsync_start - 1) | CRT_H_RS_END(m->hsync_end),
			priv->base + CRT_HORIZ1);


	/* Vertical timing */
	writel(CRT_V_TOTAL(m->vtotal - 1) | CRT_V_DE(m->vdisplay - 1),
			priv->base + CRT_VERT0);
	writel(CRT_V_RS_START(m->vsync_start) | CRT_V_RS_END(m->vsync_end),
			priv->base + CRT_VERT1);

	/*
	 * Display Offset: address difference between consecutive scan lines
	 * Terminal Count: memory size of one scan line
	 */
	d_offset = m->hdisplay * bpp / 8;
	t_count = (m->hdisplay * bpp + 127) / 128;
	writel(CRT_DISP_OFFSET(d_offset) | CRT_TERM_COUNT(t_count),
			priv->base + CRT_OFFSET);

	/*
	 * Threshold: FIFO thresholds of refill and stop (16 byte chunks
	 * per line, rounded up)
	 */
	writel(G5_CRT_THROD_VAL, priv->base + CRT_THROD);
}

static void aspeed_gfx_pipe_enable(struct drm_simple_display_pipe *pipe,
			      struct drm_crtc_state *crtc_state,
			      struct drm_plane_state *plane_state)
{
	struct aspeed_gfx *priv = drm_pipe_to_aspeed_gfx(pipe);
	struct drm_crtc *crtc = &pipe->crtc;

	aspeed_gfx_crtc_mode_set_nofb(priv);
	aspeed_gfx_enable_controller(priv);
	drm_crtc_vblank_on(crtc);
}

static void aspeed_gfx_pipe_disable(struct drm_simple_display_pipe *pipe)
{
	struct aspeed_gfx *priv = drm_pipe_to_aspeed_gfx(pipe);
	struct drm_crtc *crtc = &pipe->crtc;

	drm_crtc_vblank_off(crtc);
	aspeed_gfx_disable_controller(priv);
}

static void aspeed_gfx_pipe_update(struct drm_simple_display_pipe *pipe,
				   struct drm_plane_state *plane_state)
{
	struct aspeed_gfx *priv = drm_pipe_to_aspeed_gfx(pipe);
	struct drm_crtc *crtc = &pipe->crtc;
	struct drm_framebuffer *fb = pipe->plane.state->fb;
	struct drm_pending_vblank_event *event;
	struct drm_gem_cma_object *gem;

	spin_lock_irq(&crtc->dev->event_lock);
	event = crtc->state->event;
	if (event) {
		crtc->state->event = NULL;

		if (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);

	if (!fb)
		return;

	gem = drm_fb_cma_get_gem_obj(fb, 0);
	if (!gem)
		return;
	writel(gem->paddr, priv->base + CRT_ADDR);
}

static int aspeed_gfx_enable_vblank(struct drm_simple_display_pipe *pipe)
{
	struct aspeed_gfx *priv = drm_pipe_to_aspeed_gfx(pipe);
	u32 reg = readl(priv->base + CRT_CTRL1);

	/* Clear pending VBLANK IRQ */
	writel(reg | CRT_CTRL_VERTICAL_INTR_STS, priv->base + CRT_CTRL1);

	reg |= CRT_CTRL_VERTICAL_INTR_EN;
	writel(reg, priv->base + CRT_CTRL1);

	return 0;
}

static void aspeed_gfx_disable_vblank(struct drm_simple_display_pipe *pipe)
{
	struct aspeed_gfx *priv = drm_pipe_to_aspeed_gfx(pipe);
	u32 reg = readl(priv->base + CRT_CTRL1);

	reg &= ~CRT_CTRL_VERTICAL_INTR_EN;
	writel(reg, priv->base + CRT_CTRL1);

	/* Clear pending VBLANK IRQ */
	writel(reg | CRT_CTRL_VERTICAL_INTR_STS, priv->base + CRT_CTRL1);
}

static const struct drm_simple_display_pipe_funcs aspeed_gfx_funcs = {
	.enable		= aspeed_gfx_pipe_enable,
	.disable	= aspeed_gfx_pipe_disable,
	.update		= aspeed_gfx_pipe_update,
	.prepare_fb	= drm_gem_fb_simple_display_pipe_prepare_fb,
	.enable_vblank	= aspeed_gfx_enable_vblank,
	.disable_vblank	= aspeed_gfx_disable_vblank,
};

static const uint32_t aspeed_gfx_formats[] = {
	DRM_FORMAT_XRGB8888,
	DRM_FORMAT_RGB565,
};

int aspeed_gfx_create_pipe(struct drm_device *drm)
{
	struct aspeed_gfx *priv = drm->dev_private;

	return drm_simple_display_pipe_init(drm, &priv->pipe, &aspeed_gfx_funcs,
					    aspeed_gfx_formats,
					    ARRAY_SIZE(aspeed_gfx_formats),
					    NULL,
					    &priv->connector);
}
