162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2019 BayLibre, SAS 462306a36Sopenharmony_ci * Author: Neil Armstrong <narmstrong@baylibre.com> 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#include <linux/bitfield.h> 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <drm/drm_print.h> 1062306a36Sopenharmony_ci#include <drm/drm_fourcc.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include "meson_drv.h" 1362306a36Sopenharmony_ci#include "meson_registers.h" 1462306a36Sopenharmony_ci#include "meson_viu.h" 1562306a36Sopenharmony_ci#include "meson_rdma.h" 1662306a36Sopenharmony_ci#include "meson_osd_afbcd.h" 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci/* 1962306a36Sopenharmony_ci * DOC: Driver for the ARM FrameBuffer Compression Decoders 2062306a36Sopenharmony_ci * 2162306a36Sopenharmony_ci * The Amlogic GXM and G12A SoC families embeds an AFBC Decoder, 2262306a36Sopenharmony_ci * to decode compressed buffers generated by the ARM Mali GPU. 2362306a36Sopenharmony_ci * 2462306a36Sopenharmony_ci * For the GXM Family, Amlogic designed their own Decoder, named in 2562306a36Sopenharmony_ci * the vendor source as "MESON_AFBC", and a single decoder is available 2662306a36Sopenharmony_ci * for the 2 OSD planes. 2762306a36Sopenharmony_ci * This decoder is compatible with the AFBC 1.0 specifications and the 2862306a36Sopenharmony_ci * Mali T820 GPU capabilities. 2962306a36Sopenharmony_ci * It supports : 3062306a36Sopenharmony_ci * - basic AFBC buffer for RGB32 only, thus YTR feature is mandatory 3162306a36Sopenharmony_ci * - SPARSE layout and SPLIT layout 3262306a36Sopenharmony_ci * - only 16x16 superblock 3362306a36Sopenharmony_ci * 3462306a36Sopenharmony_ci * The decoder reads the data from the SDRAM, decodes and sends the 3562306a36Sopenharmony_ci * decoded pixel stream to the OSD1 Plane pixel composer. 3662306a36Sopenharmony_ci * 3762306a36Sopenharmony_ci * For the G12A Family, Amlogic integrated an ARM AFBC Decoder, named 3862306a36Sopenharmony_ci * in the vendor source as "MALI_AFBC", and the decoder can decode up 3962306a36Sopenharmony_ci * to 4 surfaces, one for each of the 4 available OSDs. 4062306a36Sopenharmony_ci * This decoder is compatible with the AFBC 1.2 specifications for the 4162306a36Sopenharmony_ci * Mali G31 and G52 GPUs. 4262306a36Sopenharmony_ci * Is supports : 4362306a36Sopenharmony_ci * - basic AFBC buffer for multiple RGB and YUV pixel formats 4462306a36Sopenharmony_ci * - SPARSE layout and SPLIT layout 4562306a36Sopenharmony_ci * - 16x16 and 32x8 "wideblk" superblocks 4662306a36Sopenharmony_ci * - Tiled header 4762306a36Sopenharmony_ci * 4862306a36Sopenharmony_ci * The ARM AFBC Decoder independent from the VPU Pixel Pipeline, so 4962306a36Sopenharmony_ci * the ARM AFBC Decoder reads the data from the SDRAM then decodes 5062306a36Sopenharmony_ci * into a private internal physical address where the OSD1 Plane pixel 5162306a36Sopenharmony_ci * composer unpacks the decoded data. 5262306a36Sopenharmony_ci */ 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci/* Amlogic AFBC Decoder for GXM Family */ 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci#define OSD1_AFBCD_RGB32 0x15 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_cistatic int meson_gxm_afbcd_pixel_fmt(u64 modifier, uint32_t format) 5962306a36Sopenharmony_ci{ 6062306a36Sopenharmony_ci switch (format) { 6162306a36Sopenharmony_ci case DRM_FORMAT_XBGR8888: 6262306a36Sopenharmony_ci case DRM_FORMAT_ABGR8888: 6362306a36Sopenharmony_ci return OSD1_AFBCD_RGB32; 6462306a36Sopenharmony_ci /* TOFIX support mode formats */ 6562306a36Sopenharmony_ci default: 6662306a36Sopenharmony_ci DRM_DEBUG("unsupported afbc format[%08x]\n", format); 6762306a36Sopenharmony_ci return -EINVAL; 6862306a36Sopenharmony_ci } 6962306a36Sopenharmony_ci} 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_cistatic bool meson_gxm_afbcd_supported_fmt(u64 modifier, uint32_t format) 7262306a36Sopenharmony_ci{ 7362306a36Sopenharmony_ci if (modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_32x8) 7462306a36Sopenharmony_ci return false; 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci if (!(modifier & AFBC_FORMAT_MOD_YTR)) 7762306a36Sopenharmony_ci return false; 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci return meson_gxm_afbcd_pixel_fmt(modifier, format) >= 0; 8062306a36Sopenharmony_ci} 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_cistatic int meson_gxm_afbcd_reset(struct meson_drm *priv) 8362306a36Sopenharmony_ci{ 8462306a36Sopenharmony_ci writel_relaxed(VIU_SW_RESET_OSD1_AFBCD, 8562306a36Sopenharmony_ci priv->io_base + _REG(VIU_SW_RESET)); 8662306a36Sopenharmony_ci writel_relaxed(0, priv->io_base + _REG(VIU_SW_RESET)); 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci return 0; 8962306a36Sopenharmony_ci} 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_cistatic int meson_gxm_afbcd_init(struct meson_drm *priv) 9262306a36Sopenharmony_ci{ 9362306a36Sopenharmony_ci return 0; 9462306a36Sopenharmony_ci} 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_cistatic void meson_gxm_afbcd_exit(struct meson_drm *priv) 9762306a36Sopenharmony_ci{ 9862306a36Sopenharmony_ci meson_gxm_afbcd_reset(priv); 9962306a36Sopenharmony_ci} 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_cistatic int meson_gxm_afbcd_enable(struct meson_drm *priv) 10262306a36Sopenharmony_ci{ 10362306a36Sopenharmony_ci writel_relaxed(FIELD_PREP(OSD1_AFBCD_ID_FIFO_THRD, 0x40) | 10462306a36Sopenharmony_ci OSD1_AFBCD_DEC_ENABLE, 10562306a36Sopenharmony_ci priv->io_base + _REG(OSD1_AFBCD_ENABLE)); 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci return 0; 10862306a36Sopenharmony_ci} 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_cistatic int meson_gxm_afbcd_disable(struct meson_drm *priv) 11162306a36Sopenharmony_ci{ 11262306a36Sopenharmony_ci writel_bits_relaxed(OSD1_AFBCD_DEC_ENABLE, 0, 11362306a36Sopenharmony_ci priv->io_base + _REG(OSD1_AFBCD_ENABLE)); 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci return 0; 11662306a36Sopenharmony_ci} 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_cistatic int meson_gxm_afbcd_setup(struct meson_drm *priv) 11962306a36Sopenharmony_ci{ 12062306a36Sopenharmony_ci u32 conv_lbuf_len; 12162306a36Sopenharmony_ci u32 mode = FIELD_PREP(OSD1_AFBCD_MIF_URGENT, 3) | 12262306a36Sopenharmony_ci FIELD_PREP(OSD1_AFBCD_HOLD_LINE_NUM, 4) | 12362306a36Sopenharmony_ci FIELD_PREP(OSD1_AFBCD_RGBA_EXCHAN_CTRL, 0x34) | 12462306a36Sopenharmony_ci meson_gxm_afbcd_pixel_fmt(priv->afbcd.modifier, 12562306a36Sopenharmony_ci priv->afbcd.format); 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci if (priv->afbcd.modifier & AFBC_FORMAT_MOD_SPARSE) 12862306a36Sopenharmony_ci mode |= OSD1_AFBCD_HREG_HALF_BLOCK; 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci if (priv->afbcd.modifier & AFBC_FORMAT_MOD_SPLIT) 13162306a36Sopenharmony_ci mode |= OSD1_AFBCD_HREG_BLOCK_SPLIT; 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci writel_relaxed(mode, priv->io_base + _REG(OSD1_AFBCD_MODE)); 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci writel_relaxed(FIELD_PREP(OSD1_AFBCD_HREG_VSIZE_IN, 13662306a36Sopenharmony_ci priv->viu.osd1_width) | 13762306a36Sopenharmony_ci FIELD_PREP(OSD1_AFBCD_HREG_HSIZE_IN, 13862306a36Sopenharmony_ci priv->viu.osd1_height), 13962306a36Sopenharmony_ci priv->io_base + _REG(OSD1_AFBCD_SIZE_IN)); 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci writel_relaxed(priv->viu.osd1_addr >> 4, 14262306a36Sopenharmony_ci priv->io_base + _REG(OSD1_AFBCD_HDR_PTR)); 14362306a36Sopenharmony_ci writel_relaxed(priv->viu.osd1_addr >> 4, 14462306a36Sopenharmony_ci priv->io_base + _REG(OSD1_AFBCD_FRAME_PTR)); 14562306a36Sopenharmony_ci /* TOFIX: bits 31:24 are not documented, nor the meaning of 0xe4 */ 14662306a36Sopenharmony_ci writel_relaxed((0xe4 << 24) | (priv->viu.osd1_addr & 0xffffff), 14762306a36Sopenharmony_ci priv->io_base + _REG(OSD1_AFBCD_CHROMA_PTR)); 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci if (priv->viu.osd1_width <= 128) 15062306a36Sopenharmony_ci conv_lbuf_len = 32; 15162306a36Sopenharmony_ci else if (priv->viu.osd1_width <= 256) 15262306a36Sopenharmony_ci conv_lbuf_len = 64; 15362306a36Sopenharmony_ci else if (priv->viu.osd1_width <= 512) 15462306a36Sopenharmony_ci conv_lbuf_len = 128; 15562306a36Sopenharmony_ci else if (priv->viu.osd1_width <= 1024) 15662306a36Sopenharmony_ci conv_lbuf_len = 256; 15762306a36Sopenharmony_ci else if (priv->viu.osd1_width <= 2048) 15862306a36Sopenharmony_ci conv_lbuf_len = 512; 15962306a36Sopenharmony_ci else 16062306a36Sopenharmony_ci conv_lbuf_len = 1024; 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci writel_relaxed(conv_lbuf_len, 16362306a36Sopenharmony_ci priv->io_base + _REG(OSD1_AFBCD_CONV_CTRL)); 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci writel_relaxed(FIELD_PREP(OSD1_AFBCD_DEC_PIXEL_BGN_H, 0) | 16662306a36Sopenharmony_ci FIELD_PREP(OSD1_AFBCD_DEC_PIXEL_END_H, 16762306a36Sopenharmony_ci priv->viu.osd1_width - 1), 16862306a36Sopenharmony_ci priv->io_base + _REG(OSD1_AFBCD_PIXEL_HSCOPE)); 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci writel_relaxed(FIELD_PREP(OSD1_AFBCD_DEC_PIXEL_BGN_V, 0) | 17162306a36Sopenharmony_ci FIELD_PREP(OSD1_AFBCD_DEC_PIXEL_END_V, 17262306a36Sopenharmony_ci priv->viu.osd1_height - 1), 17362306a36Sopenharmony_ci priv->io_base + _REG(OSD1_AFBCD_PIXEL_VSCOPE)); 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci return 0; 17662306a36Sopenharmony_ci} 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_cistruct meson_afbcd_ops meson_afbcd_gxm_ops = { 17962306a36Sopenharmony_ci .init = meson_gxm_afbcd_init, 18062306a36Sopenharmony_ci .exit = meson_gxm_afbcd_exit, 18162306a36Sopenharmony_ci .reset = meson_gxm_afbcd_reset, 18262306a36Sopenharmony_ci .enable = meson_gxm_afbcd_enable, 18362306a36Sopenharmony_ci .disable = meson_gxm_afbcd_disable, 18462306a36Sopenharmony_ci .setup = meson_gxm_afbcd_setup, 18562306a36Sopenharmony_ci .supported_fmt = meson_gxm_afbcd_supported_fmt, 18662306a36Sopenharmony_ci}; 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci/* ARM AFBC Decoder for G12A Family */ 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci/* Amlogic G12A Mali AFBC Decoder supported formats */ 19162306a36Sopenharmony_cienum { 19262306a36Sopenharmony_ci MAFBC_FMT_RGB565 = 0, 19362306a36Sopenharmony_ci MAFBC_FMT_RGBA5551, 19462306a36Sopenharmony_ci MAFBC_FMT_RGBA1010102, 19562306a36Sopenharmony_ci MAFBC_FMT_YUV420_10B, 19662306a36Sopenharmony_ci MAFBC_FMT_RGB888, 19762306a36Sopenharmony_ci MAFBC_FMT_RGBA8888, 19862306a36Sopenharmony_ci MAFBC_FMT_RGBA4444, 19962306a36Sopenharmony_ci MAFBC_FMT_R8, 20062306a36Sopenharmony_ci MAFBC_FMT_RG88, 20162306a36Sopenharmony_ci MAFBC_FMT_YUV420_8B, 20262306a36Sopenharmony_ci MAFBC_FMT_YUV422_8B = 11, 20362306a36Sopenharmony_ci MAFBC_FMT_YUV422_10B = 14, 20462306a36Sopenharmony_ci}; 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_cistatic int meson_g12a_afbcd_pixel_fmt(u64 modifier, uint32_t format) 20762306a36Sopenharmony_ci{ 20862306a36Sopenharmony_ci switch (format) { 20962306a36Sopenharmony_ci case DRM_FORMAT_XRGB8888: 21062306a36Sopenharmony_ci case DRM_FORMAT_ARGB8888: 21162306a36Sopenharmony_ci /* YTR is forbidden for non XBGR formats */ 21262306a36Sopenharmony_ci if (modifier & AFBC_FORMAT_MOD_YTR) 21362306a36Sopenharmony_ci return -EINVAL; 21462306a36Sopenharmony_ci fallthrough; 21562306a36Sopenharmony_ci case DRM_FORMAT_XBGR8888: 21662306a36Sopenharmony_ci case DRM_FORMAT_ABGR8888: 21762306a36Sopenharmony_ci return MAFBC_FMT_RGBA8888; 21862306a36Sopenharmony_ci case DRM_FORMAT_RGB888: 21962306a36Sopenharmony_ci /* YTR is forbidden for non XBGR formats */ 22062306a36Sopenharmony_ci if (modifier & AFBC_FORMAT_MOD_YTR) 22162306a36Sopenharmony_ci return -EINVAL; 22262306a36Sopenharmony_ci return MAFBC_FMT_RGB888; 22362306a36Sopenharmony_ci case DRM_FORMAT_RGB565: 22462306a36Sopenharmony_ci /* YTR is forbidden for non XBGR formats */ 22562306a36Sopenharmony_ci if (modifier & AFBC_FORMAT_MOD_YTR) 22662306a36Sopenharmony_ci return -EINVAL; 22762306a36Sopenharmony_ci return MAFBC_FMT_RGB565; 22862306a36Sopenharmony_ci /* TOFIX support mode formats */ 22962306a36Sopenharmony_ci default: 23062306a36Sopenharmony_ci DRM_DEBUG("unsupported afbc format[%08x]\n", format); 23162306a36Sopenharmony_ci return -EINVAL; 23262306a36Sopenharmony_ci } 23362306a36Sopenharmony_ci} 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_cistatic int meson_g12a_afbcd_bpp(uint32_t format) 23662306a36Sopenharmony_ci{ 23762306a36Sopenharmony_ci switch (format) { 23862306a36Sopenharmony_ci case DRM_FORMAT_XRGB8888: 23962306a36Sopenharmony_ci case DRM_FORMAT_ARGB8888: 24062306a36Sopenharmony_ci case DRM_FORMAT_XBGR8888: 24162306a36Sopenharmony_ci case DRM_FORMAT_ABGR8888: 24262306a36Sopenharmony_ci return 32; 24362306a36Sopenharmony_ci case DRM_FORMAT_RGB888: 24462306a36Sopenharmony_ci return 24; 24562306a36Sopenharmony_ci case DRM_FORMAT_RGB565: 24662306a36Sopenharmony_ci return 16; 24762306a36Sopenharmony_ci /* TOFIX support mode formats */ 24862306a36Sopenharmony_ci default: 24962306a36Sopenharmony_ci DRM_ERROR("unsupported afbc format[%08x]\n", format); 25062306a36Sopenharmony_ci return 0; 25162306a36Sopenharmony_ci } 25262306a36Sopenharmony_ci} 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_cistatic int meson_g12a_afbcd_fmt_to_blk_mode(u64 modifier, uint32_t format) 25562306a36Sopenharmony_ci{ 25662306a36Sopenharmony_ci switch (format) { 25762306a36Sopenharmony_ci case DRM_FORMAT_XRGB8888: 25862306a36Sopenharmony_ci case DRM_FORMAT_ARGB8888: 25962306a36Sopenharmony_ci case DRM_FORMAT_XBGR8888: 26062306a36Sopenharmony_ci case DRM_FORMAT_ABGR8888: 26162306a36Sopenharmony_ci return OSD_MALI_COLOR_MODE_RGBA8888; 26262306a36Sopenharmony_ci case DRM_FORMAT_RGB888: 26362306a36Sopenharmony_ci return OSD_MALI_COLOR_MODE_RGB888; 26462306a36Sopenharmony_ci case DRM_FORMAT_RGB565: 26562306a36Sopenharmony_ci return OSD_MALI_COLOR_MODE_RGB565; 26662306a36Sopenharmony_ci /* TOFIX support mode formats */ 26762306a36Sopenharmony_ci default: 26862306a36Sopenharmony_ci DRM_DEBUG("unsupported afbc format[%08x]\n", format); 26962306a36Sopenharmony_ci return -EINVAL; 27062306a36Sopenharmony_ci } 27162306a36Sopenharmony_ci} 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_cistatic bool meson_g12a_afbcd_supported_fmt(u64 modifier, uint32_t format) 27462306a36Sopenharmony_ci{ 27562306a36Sopenharmony_ci return meson_g12a_afbcd_pixel_fmt(modifier, format) >= 0; 27662306a36Sopenharmony_ci} 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_cistatic int meson_g12a_afbcd_reset(struct meson_drm *priv) 27962306a36Sopenharmony_ci{ 28062306a36Sopenharmony_ci meson_rdma_reset(priv); 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci meson_rdma_writel_sync(priv, VIU_SW_RESET_G12A_AFBC_ARB | 28362306a36Sopenharmony_ci VIU_SW_RESET_G12A_OSD1_AFBCD, 28462306a36Sopenharmony_ci VIU_SW_RESET); 28562306a36Sopenharmony_ci meson_rdma_writel_sync(priv, 0, VIU_SW_RESET); 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci return 0; 28862306a36Sopenharmony_ci} 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_cistatic int meson_g12a_afbcd_init(struct meson_drm *priv) 29162306a36Sopenharmony_ci{ 29262306a36Sopenharmony_ci int ret; 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci ret = meson_rdma_init(priv); 29562306a36Sopenharmony_ci if (ret) 29662306a36Sopenharmony_ci return ret; 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_ci meson_rdma_setup(priv); 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci /* Handle AFBC Decoder reset manually */ 30162306a36Sopenharmony_ci writel_bits_relaxed(MALI_AFBCD_MANUAL_RESET, MALI_AFBCD_MANUAL_RESET, 30262306a36Sopenharmony_ci priv->io_base + _REG(MALI_AFBCD_TOP_CTRL)); 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci return 0; 30562306a36Sopenharmony_ci} 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_cistatic void meson_g12a_afbcd_exit(struct meson_drm *priv) 30862306a36Sopenharmony_ci{ 30962306a36Sopenharmony_ci meson_g12a_afbcd_reset(priv); 31062306a36Sopenharmony_ci meson_rdma_free(priv); 31162306a36Sopenharmony_ci} 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_cistatic int meson_g12a_afbcd_enable(struct meson_drm *priv) 31462306a36Sopenharmony_ci{ 31562306a36Sopenharmony_ci meson_rdma_writel_sync(priv, VPU_MAFBC_IRQ_SURFACES_COMPLETED | 31662306a36Sopenharmony_ci VPU_MAFBC_IRQ_CONFIGURATION_SWAPPED | 31762306a36Sopenharmony_ci VPU_MAFBC_IRQ_DECODE_ERROR | 31862306a36Sopenharmony_ci VPU_MAFBC_IRQ_DETILING_ERROR, 31962306a36Sopenharmony_ci VPU_MAFBC_IRQ_MASK); 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci meson_rdma_writel_sync(priv, VPU_MAFBC_S0_ENABLE, 32262306a36Sopenharmony_ci VPU_MAFBC_SURFACE_CFG); 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci meson_rdma_writel_sync(priv, VPU_MAFBC_DIRECT_SWAP, 32562306a36Sopenharmony_ci VPU_MAFBC_COMMAND); 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci /* This will enable the RDMA replaying the register writes on vsync */ 32862306a36Sopenharmony_ci meson_rdma_flush(priv); 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci return 0; 33162306a36Sopenharmony_ci} 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_cistatic int meson_g12a_afbcd_disable(struct meson_drm *priv) 33462306a36Sopenharmony_ci{ 33562306a36Sopenharmony_ci writel_bits_relaxed(VPU_MAFBC_S0_ENABLE, 0, 33662306a36Sopenharmony_ci priv->io_base + _REG(VPU_MAFBC_SURFACE_CFG)); 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ci return 0; 33962306a36Sopenharmony_ci} 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_cistatic int meson_g12a_afbcd_setup(struct meson_drm *priv) 34262306a36Sopenharmony_ci{ 34362306a36Sopenharmony_ci u32 format = meson_g12a_afbcd_pixel_fmt(priv->afbcd.modifier, 34462306a36Sopenharmony_ci priv->afbcd.format); 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci if (priv->afbcd.modifier & AFBC_FORMAT_MOD_YTR) 34762306a36Sopenharmony_ci format |= VPU_MAFBC_YUV_TRANSFORM; 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci if (priv->afbcd.modifier & AFBC_FORMAT_MOD_SPLIT) 35062306a36Sopenharmony_ci format |= VPU_MAFBC_BLOCK_SPLIT; 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_ci if (priv->afbcd.modifier & AFBC_FORMAT_MOD_TILED) 35362306a36Sopenharmony_ci format |= VPU_MAFBC_TILED_HEADER_EN; 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_ci if ((priv->afbcd.modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) == 35662306a36Sopenharmony_ci AFBC_FORMAT_MOD_BLOCK_SIZE_32x8) 35762306a36Sopenharmony_ci format |= FIELD_PREP(VPU_MAFBC_SUPER_BLOCK_ASPECT, 1); 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ci meson_rdma_writel_sync(priv, format, 36062306a36Sopenharmony_ci VPU_MAFBC_FORMAT_SPECIFIER_S0); 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci meson_rdma_writel_sync(priv, priv->viu.osd1_addr, 36362306a36Sopenharmony_ci VPU_MAFBC_HEADER_BUF_ADDR_LOW_S0); 36462306a36Sopenharmony_ci meson_rdma_writel_sync(priv, 0, 36562306a36Sopenharmony_ci VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S0); 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_ci meson_rdma_writel_sync(priv, priv->viu.osd1_width, 36862306a36Sopenharmony_ci VPU_MAFBC_BUFFER_WIDTH_S0); 36962306a36Sopenharmony_ci meson_rdma_writel_sync(priv, ALIGN(priv->viu.osd1_height, 32), 37062306a36Sopenharmony_ci VPU_MAFBC_BUFFER_HEIGHT_S0); 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_ci meson_rdma_writel_sync(priv, 0, 37362306a36Sopenharmony_ci VPU_MAFBC_BOUNDING_BOX_X_START_S0); 37462306a36Sopenharmony_ci meson_rdma_writel_sync(priv, priv->viu.osd1_width - 1, 37562306a36Sopenharmony_ci VPU_MAFBC_BOUNDING_BOX_X_END_S0); 37662306a36Sopenharmony_ci meson_rdma_writel_sync(priv, 0, 37762306a36Sopenharmony_ci VPU_MAFBC_BOUNDING_BOX_Y_START_S0); 37862306a36Sopenharmony_ci meson_rdma_writel_sync(priv, priv->viu.osd1_height - 1, 37962306a36Sopenharmony_ci VPU_MAFBC_BOUNDING_BOX_Y_END_S0); 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci meson_rdma_writel_sync(priv, MESON_G12A_AFBCD_OUT_ADDR, 38262306a36Sopenharmony_ci VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S0); 38362306a36Sopenharmony_ci meson_rdma_writel_sync(priv, 0, 38462306a36Sopenharmony_ci VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S0); 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ci meson_rdma_writel_sync(priv, priv->viu.osd1_width * 38762306a36Sopenharmony_ci (meson_g12a_afbcd_bpp(priv->afbcd.format) / 8), 38862306a36Sopenharmony_ci VPU_MAFBC_OUTPUT_BUF_STRIDE_S0); 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci return 0; 39162306a36Sopenharmony_ci} 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_cistruct meson_afbcd_ops meson_afbcd_g12a_ops = { 39462306a36Sopenharmony_ci .init = meson_g12a_afbcd_init, 39562306a36Sopenharmony_ci .exit = meson_g12a_afbcd_exit, 39662306a36Sopenharmony_ci .reset = meson_g12a_afbcd_reset, 39762306a36Sopenharmony_ci .enable = meson_g12a_afbcd_enable, 39862306a36Sopenharmony_ci .disable = meson_g12a_afbcd_disable, 39962306a36Sopenharmony_ci .setup = meson_g12a_afbcd_setup, 40062306a36Sopenharmony_ci .fmt_to_blk_mode = meson_g12a_afbcd_fmt_to_blk_mode, 40162306a36Sopenharmony_ci .supported_fmt = meson_g12a_afbcd_supported_fmt, 40262306a36Sopenharmony_ci}; 403