// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright © 2018 Broadcom
 *
 * Authors:
 *	Eric Anholt <eric@anholt.net>
 *	Boris Brezillon <boris.brezillon@bootlin.com>
 */

#include <drm/drm_atomic_helper.h>
#include <drm/drm_fb_cma_helper.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_edid.h>
#include <drm/drm_panel.h>
#include <drm/drm_writeback.h>
#include <linux/clk.h>
#include <linux/component.h>
#include <linux/of_graph.h>
#include <linux/of_platform.h>
#include <linux/pm_runtime.h>

#include "vc4_drv.h"
#include "vc4_regs.h"

/* Base address of the output.  Raster formats must be 4-byte aligned,
 * T and LT must be 16-byte aligned or maybe utile-aligned (docs are
 * inconsistent, but probably utile).
 */
#define TXP_DST_PTR		0x00

/* Pitch in bytes for raster images, 16-byte aligned.  For tiled, it's
 * the width in tiles.
 */
#define TXP_DST_PITCH		0x04
/* For T-tiled imgaes, DST_PITCH should be the number of tiles wide,
 * shifted up.
 */
# define TXP_T_TILE_WIDTH_SHIFT		7
/* For LT-tiled images, DST_PITCH should be the number of utiles wide,
 * shifted up.
 */
# define TXP_LT_TILE_WIDTH_SHIFT	4

/* Pre-rotation width/height of the image.  Must match HVS config.
 *
 * If TFORMAT and 32-bit, limit is 1920 for 32-bit and 3840 to 16-bit
 * and width/height must be tile or utile-aligned as appropriate.  If
 * transposing (rotating), width is limited to 1920.
 *
 * Height is limited to various numbers between 4088 and 4095.  I'd
 * just use 4088 to be safe.
 */
#define TXP_DIM			0x08
# define TXP_HEIGHT_SHIFT		16
# define TXP_HEIGHT_MASK		GENMASK(31, 16)
# define TXP_WIDTH_SHIFT		0
# define TXP_WIDTH_MASK			GENMASK(15, 0)

#define TXP_DST_CTRL		0x0c
/* These bits are set to 0x54 */
#define TXP_PILOT_SHIFT			24
#define TXP_PILOT_MASK			GENMASK(31, 24)
/* Bits 22-23 are set to 0x01 */
#define TXP_VERSION_SHIFT		22
#define TXP_VERSION_MASK		GENMASK(23, 22)

/* Powers down the internal memory. */
# define TXP_POWERDOWN			BIT(21)

/* Enables storing the alpha component in 8888/4444, instead of
 * filling with ~ALPHA_INVERT.
 */
# define TXP_ALPHA_ENABLE		BIT(20)

/* 4 bits, each enables stores for a channel in each set of 4 bytes.
 * Set to 0xf for normal operation.
 */
# define TXP_BYTE_ENABLE_SHIFT		16
# define TXP_BYTE_ENABLE_MASK		GENMASK(19, 16)

/* Debug: Generate VSTART again at EOF. */
# define TXP_VSTART_AT_EOF		BIT(15)

/* Debug: Terminate the current frame immediately.  Stops AXI
 * writes.
 */
# define TXP_ABORT			BIT(14)

# define TXP_DITHER			BIT(13)

/* Inverts alpha if TXP_ALPHA_ENABLE, chooses fill value for
 * !TXP_ALPHA_ENABLE.
 */
# define TXP_ALPHA_INVERT		BIT(12)

/* Note: I've listed the channels here in high bit (in byte 3/2/1) to
 * low bit (in byte 0) order.
 */
# define TXP_FORMAT_SHIFT		8
# define TXP_FORMAT_MASK		GENMASK(11, 8)
# define TXP_FORMAT_ABGR4444		0
# define TXP_FORMAT_ARGB4444		1
# define TXP_FORMAT_BGRA4444		2
# define TXP_FORMAT_RGBA4444		3
# define TXP_FORMAT_BGR565		6
# define TXP_FORMAT_RGB565		7
/* 888s are non-rotated, raster-only */
# define TXP_FORMAT_BGR888		8
# define TXP_FORMAT_RGB888		9
# define TXP_FORMAT_ABGR8888		12
# define TXP_FORMAT_ARGB8888		13
# define TXP_FORMAT_BGRA8888		14
# define TXP_FORMAT_RGBA8888		15

/* If TFORMAT is set, generates LT instead of T format. */
# define TXP_LINEAR_UTILE		BIT(7)

/* Rotate output by 90 degrees. */
# define TXP_TRANSPOSE			BIT(6)

/* Generate a tiled format for V3D. */
# define TXP_TFORMAT			BIT(5)

/* Generates some undefined test mode output. */
# define TXP_TEST_MODE			BIT(4)

/* Request odd field from HVS. */
# define TXP_FIELD			BIT(3)

/* Raise interrupt when idle. */
# define TXP_EI				BIT(2)

/* Set when generating a frame, clears when idle. */
# define TXP_BUSY			BIT(1)

/* Starts a frame.  Self-clearing. */
# define TXP_GO				BIT(0)

/* Number of lines received and committed to memory. */
#define TXP_PROGRESS		0x10

#define TXP_READ(offset) readl(txp->regs + (offset))
#define TXP_WRITE(offset, val) writel(val, txp->regs + (offset))

struct vc4_txp {
	struct platform_device *pdev;

	struct drm_writeback_connector connector;

	void __iomem *regs;
};

static inline struct vc4_txp *encoder_to_vc4_txp(struct drm_encoder *encoder)
{
	return container_of(encoder, struct vc4_txp, connector.encoder);
}

static inline struct vc4_txp *connector_to_vc4_txp(struct drm_connector *conn)
{
	return container_of(conn, struct vc4_txp, connector.base);
}

#define TXP_REG(reg) { reg, #reg }
static const struct {
	u32 reg;
	const char *name;
} txp_regs[] = {
	TXP_REG(TXP_DST_PTR),
	TXP_REG(TXP_DST_PITCH),
	TXP_REG(TXP_DIM),
	TXP_REG(TXP_DST_CTRL),
	TXP_REG(TXP_PROGRESS),
};

#ifdef CONFIG_DEBUG_FS
int vc4_txp_debugfs_regs(struct seq_file *m, void *unused)
{
	struct drm_info_node *node = (struct drm_info_node *)m->private;
	struct drm_device *dev = node->minor->dev;
	struct vc4_dev *vc4 = to_vc4_dev(dev);
	struct vc4_txp *txp = vc4->txp;
	int i;

	if (!txp)
		return 0;

	for (i = 0; i < ARRAY_SIZE(txp_regs); i++) {
		seq_printf(m, "%s (0x%04x): 0x%08x\n",
			   txp_regs[i].name, txp_regs[i].reg,
			   TXP_READ(txp_regs[i].reg));
	}

	return 0;
}
#endif

static int vc4_txp_connector_get_modes(struct drm_connector *connector)
{
	struct drm_device *dev = connector->dev;

	return drm_add_modes_noedid(connector, dev->mode_config.max_width,
				    dev->mode_config.max_height);
}

static enum drm_mode_status
vc4_txp_connector_mode_valid(struct drm_connector *connector,
			     struct drm_display_mode *mode)
{
	struct drm_device *dev = connector->dev;
	struct drm_mode_config *mode_config = &dev->mode_config;
	int w = mode->hdisplay, h = mode->vdisplay;

	if (w < mode_config->min_width || w > mode_config->max_width)
		return MODE_BAD_HVALUE;

	if (h < mode_config->min_height || h > mode_config->max_height)
		return MODE_BAD_VVALUE;

	return MODE_OK;
}

static const u32 drm_fmts[] = {
	DRM_FORMAT_RGB888,
	DRM_FORMAT_BGR888,
	DRM_FORMAT_XRGB8888,
	DRM_FORMAT_XBGR8888,
	DRM_FORMAT_ARGB8888,
	DRM_FORMAT_ABGR8888,
	DRM_FORMAT_RGBX8888,
	DRM_FORMAT_BGRX8888,
	DRM_FORMAT_RGBA8888,
	DRM_FORMAT_BGRA8888,
};

static const u32 txp_fmts[] = {
	TXP_FORMAT_RGB888,
	TXP_FORMAT_BGR888,
	TXP_FORMAT_ARGB8888,
	TXP_FORMAT_ABGR8888,
	TXP_FORMAT_ARGB8888,
	TXP_FORMAT_ABGR8888,
	TXP_FORMAT_RGBA8888,
	TXP_FORMAT_BGRA8888,
	TXP_FORMAT_RGBA8888,
	TXP_FORMAT_BGRA8888,
};

static int vc4_txp_connector_atomic_check(struct drm_connector *conn,
					struct drm_connector_state *conn_state)
{
	struct drm_crtc_state *crtc_state;
	struct drm_gem_cma_object *gem;
	struct drm_framebuffer *fb;
	int i;

	if (!conn_state->writeback_job || !conn_state->writeback_job->fb)
		return 0;

	crtc_state = drm_atomic_get_new_crtc_state(conn_state->state,
						   conn_state->crtc);

	fb = conn_state->writeback_job->fb;
	if (fb->width != crtc_state->mode.hdisplay ||
	    fb->height != crtc_state->mode.vdisplay) {
		DRM_DEBUG_KMS("Invalid framebuffer size %ux%u\n",
			      fb->width, fb->height);
		return -EINVAL;
	}

	for (i = 0; i < ARRAY_SIZE(drm_fmts); i++) {
		if (fb->format->format == drm_fmts[i])
			break;
	}

	if (i == ARRAY_SIZE(drm_fmts))
		return -EINVAL;

	gem = drm_fb_cma_get_gem_obj(fb, 0);

	/* Pitch must be aligned on 16 bytes. */
	if (fb->pitches[0] & GENMASK(3, 0))
		return -EINVAL;

	vc4_crtc_txp_armed(crtc_state);

	return 0;
}

static void vc4_txp_connector_atomic_commit(struct drm_connector *conn,
					struct drm_connector_state *conn_state)
{
	struct vc4_txp *txp = connector_to_vc4_txp(conn);
	struct drm_gem_cma_object *gem;
	struct drm_display_mode *mode;
	struct drm_framebuffer *fb;
	u32 ctrl;
	int i;

	if (WARN_ON(!conn_state->writeback_job ||
		    !conn_state->writeback_job->fb))
		return;

	mode = &conn_state->crtc->state->adjusted_mode;
	fb = conn_state->writeback_job->fb;

	for (i = 0; i < ARRAY_SIZE(drm_fmts); i++) {
		if (fb->format->format == drm_fmts[i])
			break;
	}

	if (WARN_ON(i == ARRAY_SIZE(drm_fmts)))
		return;

	ctrl = TXP_GO | TXP_VSTART_AT_EOF | TXP_EI |
	       VC4_SET_FIELD(0xf, TXP_BYTE_ENABLE) |
	       VC4_SET_FIELD(txp_fmts[i], TXP_FORMAT);

	if (fb->format->has_alpha)
		ctrl |= TXP_ALPHA_ENABLE;

	gem = drm_fb_cma_get_gem_obj(fb, 0);
	TXP_WRITE(TXP_DST_PTR, gem->paddr + fb->offsets[0]);
	TXP_WRITE(TXP_DST_PITCH, fb->pitches[0]);
	TXP_WRITE(TXP_DIM,
		  VC4_SET_FIELD(mode->hdisplay, TXP_WIDTH) |
		  VC4_SET_FIELD(mode->vdisplay, TXP_HEIGHT));

	TXP_WRITE(TXP_DST_CTRL, ctrl);

	drm_writeback_queue_job(&txp->connector, conn_state->writeback_job);
}

static const struct drm_connector_helper_funcs vc4_txp_connector_helper_funcs = {
	.get_modes = vc4_txp_connector_get_modes,
	.mode_valid = vc4_txp_connector_mode_valid,
	.atomic_check = vc4_txp_connector_atomic_check,
	.atomic_commit = vc4_txp_connector_atomic_commit,
};

static enum drm_connector_status
vc4_txp_connector_detect(struct drm_connector *connector, bool force)
{
	return connector_status_connected;
}

static void vc4_txp_connector_destroy(struct drm_connector *connector)
{
	drm_connector_unregister(connector);
	drm_connector_cleanup(connector);
}

static const struct drm_connector_funcs vc4_txp_connector_funcs = {
	.detect = vc4_txp_connector_detect,
	.fill_modes = drm_helper_probe_single_connector_modes,
	.destroy = vc4_txp_connector_destroy,
	.reset = drm_atomic_helper_connector_reset,
	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};

static void vc4_txp_encoder_disable(struct drm_encoder *encoder)
{
	struct vc4_txp *txp = encoder_to_vc4_txp(encoder);

	if (TXP_READ(TXP_DST_CTRL) & TXP_BUSY) {
		unsigned long timeout = jiffies + msecs_to_jiffies(1000);

		TXP_WRITE(TXP_DST_CTRL, TXP_ABORT);

		while (TXP_READ(TXP_DST_CTRL) & TXP_BUSY &&
		       time_before(jiffies, timeout))
			;

		WARN_ON(TXP_READ(TXP_DST_CTRL) & TXP_BUSY);
	}

	TXP_WRITE(TXP_DST_CTRL, TXP_POWERDOWN);
}

static const struct drm_encoder_helper_funcs vc4_txp_encoder_helper_funcs = {
	.disable = vc4_txp_encoder_disable,
};

static irqreturn_t vc4_txp_interrupt(int irq, void *data)
{
	struct vc4_txp *txp = data;

	TXP_WRITE(TXP_DST_CTRL, TXP_READ(TXP_DST_CTRL) & ~TXP_EI);
	vc4_crtc_handle_vblank(to_vc4_crtc(txp->connector.base.state->crtc));
	drm_writeback_signal_completion(&txp->connector, 0);

	return IRQ_HANDLED;
}

static int vc4_txp_bind(struct device *dev, struct device *master, void *data)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct drm_device *drm = dev_get_drvdata(master);
	struct vc4_dev *vc4 = to_vc4_dev(drm);
	struct vc4_txp *txp;
	int ret, irq;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;

	txp = devm_kzalloc(dev, sizeof(*txp), GFP_KERNEL);
	if (!txp)
		return -ENOMEM;

	txp->pdev = pdev;

	txp->regs = vc4_ioremap_regs(pdev, 0);
	if (IS_ERR(txp->regs))
		return PTR_ERR(txp->regs);

	drm_connector_helper_add(&txp->connector.base,
				 &vc4_txp_connector_helper_funcs);
	ret = drm_writeback_connector_init(drm, &txp->connector,
					   &vc4_txp_connector_funcs,
					   &vc4_txp_encoder_helper_funcs,
					   drm_fmts, ARRAY_SIZE(drm_fmts));
	if (ret)
		return ret;

	ret = devm_request_irq(dev, irq, vc4_txp_interrupt, 0,
			       dev_name(dev), txp);
	if (ret)
		return ret;

	dev_set_drvdata(dev, txp);
	vc4->txp = txp;

	return 0;
}

static void vc4_txp_unbind(struct device *dev, struct device *master,
			   void *data)
{
	struct drm_device *drm = dev_get_drvdata(master);
	struct vc4_dev *vc4 = to_vc4_dev(drm);
	struct vc4_txp *txp = dev_get_drvdata(dev);

	vc4_txp_connector_destroy(&txp->connector.base);

	vc4->txp = NULL;
}

static const struct component_ops vc4_txp_ops = {
	.bind   = vc4_txp_bind,
	.unbind = vc4_txp_unbind,
};

static int vc4_txp_probe(struct platform_device *pdev)
{
	return component_add(&pdev->dev, &vc4_txp_ops);
}

static int vc4_txp_remove(struct platform_device *pdev)
{
	component_del(&pdev->dev, &vc4_txp_ops);
	return 0;
}

static const struct of_device_id vc4_txp_dt_match[] = {
	{ .compatible = "brcm,bcm2835-txp" },
	{ /* sentinel */ },
};

struct platform_driver vc4_txp_driver = {
	.probe = vc4_txp_probe,
	.remove = vc4_txp_remove,
	.driver = {
		.name = "vc4_txp",
		.of_match_table = vc4_txp_dt_match,
	},
};
