// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2019 BayLibre, SAS
 * Author: Neil Armstrong <narmstrong@baylibre.com>
 */

#include <linux/bitfield.h>

#include <drm/drm_print.h>
#include <drm/drm_fourcc.h>

#include "meson_drv.h"
#include "meson_registers.h"
#include "meson_viu.h"
#include "meson_rdma.h"
#include "meson_osd_afbcd.h"

/*
 * DOC: Driver for the ARM FrameBuffer Compression Decoders
 *
 * The Amlogic GXM and G12A SoC families embeds an AFBC Decoder,
 * to decode compressed buffers generated by the ARM Mali GPU.
 *
 * For the GXM Family, Amlogic designed their own Decoder, named in
 * the vendor source as "MESON_AFBC", and a single decoder is available
 * for the 2 OSD planes.
 * This decoder is compatible with the AFBC 1.0 specifications and the
 * Mali T820 GPU capabilities.
 * It supports :
 * - basic AFBC buffer for RGB32 only, thus YTR feature is mandatory
 * - SPARSE layout and SPLIT layout
 * - only 16x16 superblock
 *
 * The decoder reads the data from the SDRAM, decodes and sends the
 * decoded pixel stream to the OSD1 Plane pixel composer.
 *
 * For the G12A Family, Amlogic integrated an ARM AFBC Decoder, named
 * in the vendor source as "MALI_AFBC", and the decoder can decode up
 * to 4 surfaces, one for each of the 4 available OSDs.
 * This decoder is compatible with the AFBC 1.2 specifications for the
 * Mali G31 and G52 GPUs.
 * Is supports :
 * - basic AFBC buffer for multiple RGB and YUV pixel formats
 * - SPARSE layout and SPLIT layout
 * - 16x16 and 32x8 "wideblk" superblocks
 * - Tiled header
 *
 * The ARM AFBC Decoder independent from the VPU Pixel Pipeline, so
 * the ARM AFBC Decoder reads the data from the SDRAM then decodes
 * into a private internal physical address where the OSD1 Plane pixel
 * composer unpacks the decoded data.
 */

/* Amlogic AFBC Decoder for GXM Family */

#define OSD1_AFBCD_RGB32	0x15

static int meson_gxm_afbcd_pixel_fmt(u64 modifier, uint32_t format)
{
	switch (format) {
	case DRM_FORMAT_XBGR8888:
	case DRM_FORMAT_ABGR8888:
		return OSD1_AFBCD_RGB32;
	/* TOFIX support mode formats */
	default:
		DRM_DEBUG("unsupported afbc format[%08x]\n", format);
		return -EINVAL;
	}
}

static bool meson_gxm_afbcd_supported_fmt(u64 modifier, uint32_t format)
{
	if (modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_32x8)
		return false;

	if (!(modifier & AFBC_FORMAT_MOD_YTR))
		return false;

	return meson_gxm_afbcd_pixel_fmt(modifier, format) >= 0;
}

static int meson_gxm_afbcd_init(struct meson_drm *priv)
{
	return 0;
}

static int meson_gxm_afbcd_reset(struct meson_drm *priv)
{
	writel_relaxed(VIU_SW_RESET_OSD1_AFBCD,
		       priv->io_base + _REG(VIU_SW_RESET));
	writel_relaxed(0, priv->io_base + _REG(VIU_SW_RESET));

	return 0;
}

static int meson_gxm_afbcd_enable(struct meson_drm *priv)
{
	writel_relaxed(FIELD_PREP(OSD1_AFBCD_ID_FIFO_THRD, 0x40) |
		       OSD1_AFBCD_DEC_ENABLE,
		       priv->io_base + _REG(OSD1_AFBCD_ENABLE));

	return 0;
}

static int meson_gxm_afbcd_disable(struct meson_drm *priv)
{
	writel_bits_relaxed(OSD1_AFBCD_DEC_ENABLE, 0,
			    priv->io_base + _REG(OSD1_AFBCD_ENABLE));

	return 0;
}

static int meson_gxm_afbcd_setup(struct meson_drm *priv)
{
	u32 conv_lbuf_len;
	u32 mode = FIELD_PREP(OSD1_AFBCD_MIF_URGENT, 3) |
		   FIELD_PREP(OSD1_AFBCD_HOLD_LINE_NUM, 4) |
		   FIELD_PREP(OSD1_AFBCD_RGBA_EXCHAN_CTRL, 0x34) |
		   meson_gxm_afbcd_pixel_fmt(priv->afbcd.modifier,
					     priv->afbcd.format);

	if (priv->afbcd.modifier & AFBC_FORMAT_MOD_SPARSE)
		mode |= OSD1_AFBCD_HREG_HALF_BLOCK;

	if (priv->afbcd.modifier & AFBC_FORMAT_MOD_SPLIT)
		mode |= OSD1_AFBCD_HREG_BLOCK_SPLIT;

	writel_relaxed(mode, priv->io_base + _REG(OSD1_AFBCD_MODE));

	writel_relaxed(FIELD_PREP(OSD1_AFBCD_HREG_VSIZE_IN,
				  priv->viu.osd1_width) |
		       FIELD_PREP(OSD1_AFBCD_HREG_HSIZE_IN,
				  priv->viu.osd1_height),
		       priv->io_base + _REG(OSD1_AFBCD_SIZE_IN));

	writel_relaxed(priv->viu.osd1_addr >> 4,
		       priv->io_base + _REG(OSD1_AFBCD_HDR_PTR));
	writel_relaxed(priv->viu.osd1_addr >> 4,
		       priv->io_base + _REG(OSD1_AFBCD_FRAME_PTR));
	/* TOFIX: bits 31:24 are not documented, nor the meaning of 0xe4 */
	writel_relaxed((0xe4 << 24) | (priv->viu.osd1_addr & 0xffffff),
		       priv->io_base + _REG(OSD1_AFBCD_CHROMA_PTR));

	if (priv->viu.osd1_width <= 128)
		conv_lbuf_len = 32;
	else if (priv->viu.osd1_width <= 256)
		conv_lbuf_len = 64;
	else if (priv->viu.osd1_width <= 512)
		conv_lbuf_len = 128;
	else if (priv->viu.osd1_width <= 1024)
		conv_lbuf_len = 256;
	else if (priv->viu.osd1_width <= 2048)
		conv_lbuf_len = 512;
	else
		conv_lbuf_len = 1024;

	writel_relaxed(conv_lbuf_len,
		       priv->io_base + _REG(OSD1_AFBCD_CONV_CTRL));

	writel_relaxed(FIELD_PREP(OSD1_AFBCD_DEC_PIXEL_BGN_H, 0) |
		       FIELD_PREP(OSD1_AFBCD_DEC_PIXEL_END_H,
				  priv->viu.osd1_width - 1),
		       priv->io_base + _REG(OSD1_AFBCD_PIXEL_HSCOPE));

	writel_relaxed(FIELD_PREP(OSD1_AFBCD_DEC_PIXEL_BGN_V, 0) |
		       FIELD_PREP(OSD1_AFBCD_DEC_PIXEL_END_V,
				  priv->viu.osd1_height - 1),
		       priv->io_base + _REG(OSD1_AFBCD_PIXEL_VSCOPE));

	return 0;
}

struct meson_afbcd_ops meson_afbcd_gxm_ops = {
	.init = meson_gxm_afbcd_init,
	.reset = meson_gxm_afbcd_reset,
	.enable = meson_gxm_afbcd_enable,
	.disable = meson_gxm_afbcd_disable,
	.setup = meson_gxm_afbcd_setup,
	.supported_fmt = meson_gxm_afbcd_supported_fmt,
};

/* ARM AFBC Decoder for G12A Family */

/* Amlogic G12A Mali AFBC Decoder supported formats */
enum {
	MAFBC_FMT_RGB565 = 0,
	MAFBC_FMT_RGBA5551,
	MAFBC_FMT_RGBA1010102,
	MAFBC_FMT_YUV420_10B,
	MAFBC_FMT_RGB888,
	MAFBC_FMT_RGBA8888,
	MAFBC_FMT_RGBA4444,
	MAFBC_FMT_R8,
	MAFBC_FMT_RG88,
	MAFBC_FMT_YUV420_8B,
	MAFBC_FMT_YUV422_8B = 11,
	MAFBC_FMT_YUV422_10B = 14,
};

static int meson_g12a_afbcd_pixel_fmt(u64 modifier, uint32_t format)
{
	switch (format) {
	case DRM_FORMAT_XRGB8888:
	case DRM_FORMAT_ARGB8888:
		/* YTR is forbidden for non XBGR formats */
		if (modifier & AFBC_FORMAT_MOD_YTR)
			return -EINVAL;
		fallthrough;
	case DRM_FORMAT_XBGR8888:
	case DRM_FORMAT_ABGR8888:
		return MAFBC_FMT_RGBA8888;
	case DRM_FORMAT_RGB888:
		/* YTR is forbidden for non XBGR formats */
		if (modifier & AFBC_FORMAT_MOD_YTR)
			return -EINVAL;
		return MAFBC_FMT_RGB888;
	case DRM_FORMAT_RGB565:
		/* YTR is forbidden for non XBGR formats */
		if (modifier & AFBC_FORMAT_MOD_YTR)
			return -EINVAL;
		return MAFBC_FMT_RGB565;
	/* TOFIX support mode formats */
	default:
		DRM_DEBUG("unsupported afbc format[%08x]\n", format);
		return -EINVAL;
	}
}

static int meson_g12a_afbcd_bpp(uint32_t format)
{
	switch (format) {
	case DRM_FORMAT_XRGB8888:
	case DRM_FORMAT_ARGB8888:
	case DRM_FORMAT_XBGR8888:
	case DRM_FORMAT_ABGR8888:
		return 32;
	case DRM_FORMAT_RGB888:
		return 24;
	case DRM_FORMAT_RGB565:
		return 16;
	/* TOFIX support mode formats */
	default:
		DRM_ERROR("unsupported afbc format[%08x]\n", format);
		return 0;
	}
}

static int meson_g12a_afbcd_fmt_to_blk_mode(u64 modifier, uint32_t format)
{
	switch (format) {
	case DRM_FORMAT_XRGB8888:
	case DRM_FORMAT_ARGB8888:
	case DRM_FORMAT_XBGR8888:
	case DRM_FORMAT_ABGR8888:
		return OSD_MALI_COLOR_MODE_RGBA8888;
	case DRM_FORMAT_RGB888:
		return OSD_MALI_COLOR_MODE_RGB888;
	case DRM_FORMAT_RGB565:
		return OSD_MALI_COLOR_MODE_RGB565;
	/* TOFIX support mode formats */
	default:
		DRM_DEBUG("unsupported afbc format[%08x]\n", format);
		return -EINVAL;
	}
}

static bool meson_g12a_afbcd_supported_fmt(u64 modifier, uint32_t format)
{
	return meson_g12a_afbcd_pixel_fmt(modifier, format) >= 0;
}

static int meson_g12a_afbcd_init(struct meson_drm *priv)
{
	int ret;

	ret = meson_rdma_init(priv);
	if (ret)
		return ret;

	meson_rdma_setup(priv);

	/* Handle AFBC Decoder reset manually */
	writel_bits_relaxed(MALI_AFBCD_MANUAL_RESET, MALI_AFBCD_MANUAL_RESET,
			    priv->io_base + _REG(MALI_AFBCD_TOP_CTRL));

	return 0;
}

static int meson_g12a_afbcd_reset(struct meson_drm *priv)
{
	meson_rdma_reset(priv);

	meson_rdma_writel_sync(priv, VIU_SW_RESET_G12A_AFBC_ARB |
			       VIU_SW_RESET_G12A_OSD1_AFBCD,
			       VIU_SW_RESET);
	meson_rdma_writel_sync(priv, 0, VIU_SW_RESET);

	return 0;
}

static int meson_g12a_afbcd_enable(struct meson_drm *priv)
{
	meson_rdma_writel_sync(priv, VPU_MAFBC_IRQ_SURFACES_COMPLETED |
			       VPU_MAFBC_IRQ_CONFIGURATION_SWAPPED |
			       VPU_MAFBC_IRQ_DECODE_ERROR |
			       VPU_MAFBC_IRQ_DETILING_ERROR,
			       VPU_MAFBC_IRQ_MASK);

	meson_rdma_writel_sync(priv, VPU_MAFBC_S0_ENABLE,
			       VPU_MAFBC_SURFACE_CFG);

	meson_rdma_writel_sync(priv, VPU_MAFBC_DIRECT_SWAP,
			       VPU_MAFBC_COMMAND);

	/* This will enable the RDMA replaying the register writes on vsync */
	meson_rdma_flush(priv);

	return 0;
}

static int meson_g12a_afbcd_disable(struct meson_drm *priv)
{
	writel_bits_relaxed(VPU_MAFBC_S0_ENABLE, 0,
			    priv->io_base + _REG(VPU_MAFBC_SURFACE_CFG));

	return 0;
}

static int meson_g12a_afbcd_setup(struct meson_drm *priv)
{
	u32 format = meson_g12a_afbcd_pixel_fmt(priv->afbcd.modifier,
						priv->afbcd.format);

	if (priv->afbcd.modifier & AFBC_FORMAT_MOD_YTR)
		format |= VPU_MAFBC_YUV_TRANSFORM;

	if (priv->afbcd.modifier & AFBC_FORMAT_MOD_SPLIT)
		format |= VPU_MAFBC_BLOCK_SPLIT;

	if (priv->afbcd.modifier & AFBC_FORMAT_MOD_TILED)
		format |= VPU_MAFBC_TILED_HEADER_EN;

	if ((priv->afbcd.modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) ==
		AFBC_FORMAT_MOD_BLOCK_SIZE_32x8)
		format |= FIELD_PREP(VPU_MAFBC_SUPER_BLOCK_ASPECT, 1);

	meson_rdma_writel_sync(priv, format,
			       VPU_MAFBC_FORMAT_SPECIFIER_S0);

	meson_rdma_writel_sync(priv, priv->viu.osd1_addr,
			       VPU_MAFBC_HEADER_BUF_ADDR_LOW_S0);
	meson_rdma_writel_sync(priv, 0,
			       VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S0);

	meson_rdma_writel_sync(priv, priv->viu.osd1_width,
			       VPU_MAFBC_BUFFER_WIDTH_S0);
	meson_rdma_writel_sync(priv, ALIGN(priv->viu.osd1_height, 32),
			       VPU_MAFBC_BUFFER_HEIGHT_S0);

	meson_rdma_writel_sync(priv, 0,
			       VPU_MAFBC_BOUNDING_BOX_X_START_S0);
	meson_rdma_writel_sync(priv, priv->viu.osd1_width - 1,
			       VPU_MAFBC_BOUNDING_BOX_X_END_S0);
	meson_rdma_writel_sync(priv, 0,
			       VPU_MAFBC_BOUNDING_BOX_Y_START_S0);
	meson_rdma_writel_sync(priv, priv->viu.osd1_height - 1,
			       VPU_MAFBC_BOUNDING_BOX_Y_END_S0);

	meson_rdma_writel_sync(priv, MESON_G12A_AFBCD_OUT_ADDR,
			       VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S0);
	meson_rdma_writel_sync(priv, 0,
			       VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S0);

	meson_rdma_writel_sync(priv, priv->viu.osd1_width *
			       (meson_g12a_afbcd_bpp(priv->afbcd.format) / 8),
			       VPU_MAFBC_OUTPUT_BUF_STRIDE_S0);

	return 0;
}

struct meson_afbcd_ops meson_afbcd_g12a_ops = {
	.init = meson_g12a_afbcd_init,
	.reset = meson_g12a_afbcd_reset,
	.enable = meson_g12a_afbcd_enable,
	.disable = meson_g12a_afbcd_disable,
	.setup = meson_g12a_afbcd_setup,
	.fmt_to_blk_mode = meson_g12a_afbcd_fmt_to_blk_mode,
	.supported_fmt = meson_g12a_afbcd_supported_fmt,
};
