// 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_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_init(struct meson_drm *priv)
{
	return 0;
}

static void meson_gxm_afbcd_exit(struct meson_drm *priv)
{
	meson_gxm_afbcd_reset(priv);
}

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,
	.exit = meson_gxm_afbcd_exit,
	.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_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_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 void meson_g12a_afbcd_exit(struct meson_drm *priv)
{
	meson_g12a_afbcd_reset(priv);
	meson_rdma_free(priv);
}

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,
	.exit = meson_g12a_afbcd_exit,
	.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,
};
