mirror of
https://github.com/CTCaer/hekate.git
synced 2024-11-23 02:16:41 +00:00
566 lines
19 KiB
C
566 lines
19 KiB
C
/*
|
|
* VIC driver for Tegra X1
|
|
*
|
|
* Copyright (c) 2018-2023 CTCaer
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms and conditions of the GNU General Public License,
|
|
* version 2, as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <string.h>
|
|
|
|
#include "vic.h"
|
|
#include <mem/heap.h>
|
|
#include <soc/bpmp.h>
|
|
#include <soc/clock.h>
|
|
#include <soc/timer.h>
|
|
#include <soc/t210.h>
|
|
#include <utils/types.h>
|
|
|
|
/* VIC Private registers */
|
|
#define PVIC_FALCON_PA_OFFSET 0x1000
|
|
#define PVIC_FALCON_ADDR 0x10AC
|
|
#define PVIC_FALCON_IDLESTATE 0x104C
|
|
|
|
/* VIC Control and Status registers. */
|
|
/* Fetch Control registers. */
|
|
#define VIC_FC_COMPOSE 0x10000
|
|
#define COMPOSE_START BIT(0)
|
|
|
|
#define VIC_FC_CFG_STRUCT_SLOT_INDEX 0x10B00
|
|
|
|
#define VIC_FC_CFG_STRUCT_SLOT_CFG0 0x10B04
|
|
#define SLOT_ENABLE BIT(0)
|
|
#define FIELD_CURRENT_ENABLE BIT(8)
|
|
|
|
#define VIC_FC_CFG_STRUCT_SLOT_CFG2 0x10B0C
|
|
#define CACHE_WIDTH(n) ((n) << 16)
|
|
#define CACHE_WIDTH_16BX16 0 // Block Linear.
|
|
#define CACHE_WIDTH_32BX8 1 // Block Linear. Recommended for Block Linear.
|
|
#define CACHE_WIDTH_64BX4 2 // Block Linear, Pitch. Recommended for Pitch.
|
|
#define CACHE_WIDTH_128BX2 3 // Block Linear, Pitch.
|
|
#define OUTPUT_FLIP_X BIT(20)
|
|
#define OUTPUT_FLIP_Y BIT(21)
|
|
#define OUTPUT_TRANSPOSE BIT(22)
|
|
|
|
#define VIC_FC_CFG_STRUCT_SLOT_SFC_SIZE 0x10B10
|
|
#define VIC_FC_CFG_STRUCT_SLOT_LUMA_SIZE 0x10B14
|
|
#define VIC_FC_CFG_STRUCT_SLOT_CHROMA_SIZE 0x10B18
|
|
#define VIC_FC_CFG_STRUCT_SLOT_SRC_RECT_LR 0x10B1C
|
|
#define VIC_FC_CFG_STRUCT_SLOT_SRC_RECT_TB 0x10B20
|
|
#define VIC_FC_CFG_STRUCT_SLOT_DST_RECT_LR 0x10B30
|
|
#define VIC_FC_CFG_STRUCT_SLOT_DST_RECT_TB 0x10B34
|
|
#define VIC_FC_CFG_STRUCT_TGT_RECT_LR 0x10B38
|
|
#define VIC_FC_CFG_STRUCT_TGT_RECT_TB 0x10B3C
|
|
#define VIC_FC_SLOT_MAP 0x10C00
|
|
|
|
#define VIC_FC_FCE_CTRL 0x11000
|
|
#define START_TRIGGER BIT(0)
|
|
#define HALT_TRIGGER BIT(1)
|
|
#define CLEAR_ERROR BIT(8)
|
|
|
|
#define VIC_FC_FCE_UCODE_ADDR 0x11200
|
|
#define VIC_FC_FCE_UCODE_INST 0x11300
|
|
|
|
/* Surface List registers. */
|
|
#define VIC_SL_CFG_STRUCT_SLOT_INDEX 0x12100
|
|
#define VIC_SL_CFG_STRUCT_SLOT_DST_RECT_LR 0x12200
|
|
#define VIC_SL_CFG_STRUCT_SLOT_DST_RECT_TB 0x12300
|
|
#define VIC_SL_CFG_STRUCT_TGT_RECT_LR 0x12400
|
|
#define VIC_SL_CFG_STRUCT_TGT_RECT_TB 0x12500
|
|
#define VIC_SL_CFG_STRUCT_SLOT_CFG0 0x12600
|
|
|
|
/* Surface Cache registers. */
|
|
#define VIC_SC_PRAMBASE 0x14000
|
|
#define VIC_SC_PRAMSIZE 0x14100
|
|
#define VIC_SC_SFC0_BASE_LUMA(n) (0x14300 + (n) * 0x100)
|
|
|
|
/* Blending Output registers. */
|
|
#define VIC_BL_TARGET_BASADR 0x22000
|
|
#define VIC_BL_CONFIG 0x22800
|
|
#define SUBPARTITION_MODE BIT(0)
|
|
#define PROCESS_CFG_STRUCT_TRIGGER BIT(2)
|
|
#define SLOTMASK(n) ((n) << 8)
|
|
|
|
#define VIC_BL_CFG_STRUCT_CFG0 0x22C00
|
|
#define VIC_BL_CFG_STRUCT_SFC_SIZE 0x22C04
|
|
#define VIC_BL_CFG_STRUCT_LUMA_SIZE 0x22C08
|
|
#define VIC_BL_CFG_STRUCT_CHROMA_SIZE 0x22C0C
|
|
#define VIC_BL_CFG_STRUCT_TGT_RECT_LR 0x22C10
|
|
#define VIC_BL_CFG_STRUCT_TGT_RECT_TB 0x22C14
|
|
|
|
// VIC_FC_CFG_STRUCT_SLOT_CFG2 & VIC_BL_CFG_STRUCT_CFG0.
|
|
#define BLK_KIND(n) ((n) << 8)
|
|
#define BLK_KIND_PITCH 0
|
|
#define BLK_KIND_GENERIC_16BX2 1
|
|
#define BLK_HEIGHT(n) ((n) << 12)
|
|
#define BLK_HEIGHT_ONE_GOB 0
|
|
#define BLK_HEIGHT_SIXTEEN_GOBS 4
|
|
|
|
// Generic size macros.
|
|
#define SIZE_WIDTH(n) (((n) - 1) << 0)
|
|
#define SIZE_HEIGHT(n) (((n) - 1) << 16)
|
|
#define RECT_LEFT(n) ((n) << 0)
|
|
#define RECT_RIGHT(n) (((n) - 1) << 16)
|
|
#define RECT_TOP(n) ((n) << 0)
|
|
#define RECT_BOTTOM(n) (((n) - 1) << 16)
|
|
|
|
#define FORMAT_PROGRESSIVE 0
|
|
#define SOFT_CLAMP_MIN 0
|
|
#define SOFT_CLAMP_MAX 0x3FFu
|
|
#define ALPHA_1_0 0x3FFu
|
|
|
|
typedef struct _OutputConfig {
|
|
u64 AlphaFillMode:3;
|
|
u64 AlphaFillSlot:3;
|
|
u64 BackgroundAlpha:10;
|
|
u64 BackgroundR:10;
|
|
u64 BackgroundG:10;
|
|
u64 BackgroundB:10;
|
|
u64 RegammaMode:2;
|
|
u64 OutputFlipX:1;
|
|
u64 OutputFlipY:1;
|
|
u64 OutputTranspose:1;
|
|
u64 rsvd1:1;
|
|
u64 rsvd2:12;
|
|
u64 TargetRectLeft:14;
|
|
u64 rsvd3:2;
|
|
u64 TargetRectRight:14;
|
|
u64 rsvd4:2;
|
|
u64 TargetRectTop:14;
|
|
u64 rsvd5:2;
|
|
u64 TargetRectBottom:14;
|
|
u64 rsvd6:2;
|
|
} OutputConfig;
|
|
|
|
typedef struct _OutputSurfaceConfig {
|
|
u64 OutPixelFormat:7;
|
|
u64 OutChromaLocHoriz:2;
|
|
u64 OutChromaLocVert:2;
|
|
u64 OutBlkKind:4;
|
|
u64 OutBlkHeight:4;
|
|
u64 rsvd0:3;
|
|
u64 rsvd1:10;
|
|
u64 OutSurfaceWidth:14;
|
|
u64 OutSurfaceHeight:14;
|
|
u64 rsvd2:4;
|
|
u64 OutLumaWidth:14;
|
|
u64 OutLumaHeight:14;
|
|
u64 rsvd3:4;
|
|
u64 OutChromaWidth:14;
|
|
u64 OutChromaHeight:14;
|
|
u64 rsvd4:4;
|
|
} OutputSurfaceConfig;
|
|
|
|
typedef struct _SlotConfig {
|
|
u64 SlotEnable:1;
|
|
u64 DeNoise:1;
|
|
u64 AdvancedDenoise:1;
|
|
u64 CadenceDetect:1;
|
|
u64 MotionMap:1;
|
|
u64 MMapCombine:1;
|
|
u64 IsEven:1;
|
|
u64 ChromaEven:1;
|
|
u64 CurrentFieldEnable:1;
|
|
u64 PrevFieldEnable:1;
|
|
u64 NextFieldEnable:1;
|
|
u64 NextNrFieldEnable:1;
|
|
u64 CurMotionFieldEnable:1;
|
|
u64 PrevMotionFieldEnable:1;
|
|
u64 PpMotionFieldEnable:1;
|
|
u64 CombMotionFieldEnable:1;
|
|
u64 FrameFormat:4;
|
|
u64 FilterLengthY:2;
|
|
u64 FilterLengthX:2;
|
|
u64 Panoramic:12;
|
|
u64 rsvd1:22;
|
|
u64 DetailFltClamp:6;
|
|
u64 FilterNoise:10;
|
|
u64 FilterDetail:10;
|
|
u64 ChromaNoise:10;
|
|
u64 ChromaDetail:10;
|
|
u64 DeinterlaceMode:4;
|
|
u64 MotionAccumWeight:3;
|
|
u64 NoiseIir:11;
|
|
u64 LightLevel:4;
|
|
u64 rsvd4:2;
|
|
u64 SoftClampLow:10;
|
|
u64 SoftClampHigh:10;
|
|
u64 rsvd5:3;
|
|
u64 rsvd6:9;
|
|
u64 PlanarAlpha:10;
|
|
u64 ConstantAlpha:1;
|
|
u64 StereoInterleave:3;
|
|
u64 ClipEnabled:1;
|
|
u64 ClearRectMask:8;
|
|
u64 DegammaMode:2;
|
|
u64 rsvd7:1;
|
|
u64 DecompressEnable:1;
|
|
u64 rsvd9:5;
|
|
u64 DecompressCtbCount:8;
|
|
u64 DecompressZbcColor:32;
|
|
u64 rsvd12:24;
|
|
u64 SourceRectLeft:30;
|
|
u64 rsvd14:2;
|
|
u64 SourceRectRight:30;
|
|
u64 rsvd15:2;
|
|
u64 SourceRectTop:30;
|
|
u64 rsvd16:2;
|
|
u64 SourceRectBottom:30;
|
|
u64 rsvd17:2;
|
|
u64 DestRectLeft:14;
|
|
u64 rsvd18:2;
|
|
u64 DestRectRight:14;
|
|
u64 rsvd19:2;
|
|
u64 DestRectTop:14;
|
|
u64 rsvd20:2;
|
|
u64 DestRectBottom:14;
|
|
u64 rsvd21:2;
|
|
u64 rsvd22:32;
|
|
u64 rsvd23:32;
|
|
} SlotConfig;
|
|
|
|
typedef struct _SlotSurfaceConfig {
|
|
u64 SlotPixelFormat:7;
|
|
u64 SlotChromaLocHoriz:2;
|
|
u64 SlotChromaLocVert:2;
|
|
u64 SlotBlkKind:4;
|
|
u64 SlotBlkHeight:4;
|
|
u64 SlotCacheWidth:3;
|
|
u64 rsvd0:10;
|
|
u64 SlotSurfaceWidth:14;
|
|
u64 SlotSurfaceHeight:14;
|
|
u64 rsvd1:4;
|
|
u64 SlotLumaWidth:14;
|
|
u64 SlotLumaHeight:14;
|
|
u64 rsvd2:4;
|
|
u64 SlotChromaWidth:14;
|
|
u64 SlotChromaHeight:14;
|
|
u64 rsvd3:4;
|
|
} SlotSurfaceConfig;
|
|
|
|
typedef struct _SlotStruct {
|
|
SlotConfig slot_cfg;
|
|
SlotSurfaceConfig slot_sfc_cfg;
|
|
|
|
// No need to configure. Reset to zeros.
|
|
u8 lumaKeyStruct[0x10];
|
|
u8 colorMatrixStruct[0x20];
|
|
u8 gamutMatrixStruct[0x20];
|
|
u8 blendingSlotStruct[0x10];
|
|
} SlotStruct;
|
|
|
|
typedef struct _vic_config_t {
|
|
// No need to configure. Reset to zeros.
|
|
u8 pipeConfig[0x10];
|
|
|
|
OutputConfig out_cfg;
|
|
OutputSurfaceConfig out_sfc_cfg;
|
|
|
|
// No need to configure. Reset to zeros.
|
|
u8 out_color_matrix[0x20];
|
|
u8 clear_rect[0x10 * 4];
|
|
|
|
SlotStruct slots[8];
|
|
} vic_config_t;
|
|
|
|
// VIC Fetch Control Engine microcode. Dumped from L4T r33.
|
|
u8 vic_fce_ucode[] = {
|
|
0x66, 0x00, 0x00, 0x00, 0x60, 0x07, 0x00, 0x00, 0x42, 0x40, 0x10, 0x00, 0x4E, 0x01, 0x40, 0x00,
|
|
0x6A, 0x07, 0x00, 0x00, 0x6E, 0x23, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x4E, 0x01, 0x04, 0x00,
|
|
0x6A, 0x0B, 0x00, 0x00, 0x6E, 0x1F, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x4E, 0x01, 0x10, 0x00,
|
|
0x6A, 0x0F, 0x00, 0x00, 0x6E, 0x1F, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x48, 0x80, 0x02, 0x00,
|
|
0x0E, 0x11, 0x00, 0x00, 0x6A, 0x14, 0x00, 0x00, 0x6E, 0x08, 0x06, 0x00, 0x6C, 0x00, 0x00, 0x00,
|
|
0x4E, 0x01, 0x08, 0x00, 0x6A, 0x18, 0x00, 0x00, 0x6E, 0x26, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00,
|
|
0x4E, 0x01, 0x20, 0x00, 0x6A, 0x1C, 0x00, 0x00, 0x6E, 0x26, 0x04, 0x00, 0x6C, 0x00, 0x00, 0x00,
|
|
0x4E, 0x01, 0x02, 0x00, 0x6A, 0x20, 0x00, 0x00, 0x6E, 0x24, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00,
|
|
0x56, 0x00, 0x10, 0x00, 0x56, 0x40, 0x10, 0x00, 0x22, 0x41, 0x01, 0x00, 0x6C, 0x00, 0x00, 0x00,
|
|
0x62, 0x80, 0x01, 0x00, 0x60, 0x47, 0x00, 0x00, 0x60, 0x87, 0x00, 0x00, 0x01, 0x4A, 0x00, 0x00,
|
|
0x55, 0xC0, 0x20, 0x00, 0x00, 0x59, 0x00, 0x00, 0x60, 0x87, 0x00, 0x00, 0x60, 0xC7, 0x00, 0x00,
|
|
0x01, 0x93, 0x00, 0x00, 0x40, 0x82, 0x02, 0x00, 0x4E, 0x02, 0x00, 0x00, 0x6B, 0x34, 0x00, 0x00,
|
|
0x43, 0xC1, 0x10, 0x00, 0x42, 0x02, 0x03, 0x00, 0x00, 0x23, 0x01, 0x00, 0x24, 0xD4, 0x00, 0x00,
|
|
0x56, 0x40, 0x3D, 0x00, 0x04, 0xEB, 0x00, 0x00, 0x60, 0x07, 0x01, 0x00, 0x60, 0x47, 0x00, 0x00,
|
|
0x6A, 0x3E, 0x00, 0x00, 0x55, 0xC0, 0x30, 0x00, 0x48, 0x00, 0x01, 0x00, 0x48, 0x40, 0x01, 0x00,
|
|
0x48, 0x80, 0x01, 0x00, 0x6B, 0x28, 0x02, 0x00, 0x56, 0x40, 0x09, 0x00, 0x04, 0x4D, 0x01, 0x00,
|
|
0x06, 0x4D, 0x00, 0x00, 0x42, 0xC0, 0x03, 0x00, 0x56, 0x80, 0x09, 0x00, 0x04, 0xFE, 0x01, 0x00,
|
|
0x00, 0xF9, 0x01, 0x00, 0x4E, 0x02, 0x00, 0x00, 0x6B, 0x32, 0x02, 0x00, 0x55, 0x40, 0x2F, 0x00,
|
|
0x56, 0x80, 0x0D, 0x00, 0x4F, 0x00, 0x00, 0x00, 0x6A, 0x0D, 0x02, 0x00, 0x55, 0x40, 0x31, 0x00,
|
|
0x56, 0x80, 0x0B, 0x00, 0x0C, 0x2B, 0x00, 0x00, 0x6A, 0x13, 0x02, 0x00, 0x43, 0x45, 0x03, 0x00,
|
|
0x42, 0x86, 0x03, 0x00, 0x4D, 0x06, 0x02, 0x00, 0x6A, 0x0D, 0x02, 0x00, 0x42, 0x86, 0x03, 0x00,
|
|
0x22, 0x7E, 0x01, 0x00, 0x4E, 0x04, 0x00, 0x00, 0x6B, 0x32, 0x02, 0x00, 0x55, 0x40, 0x17, 0x00,
|
|
0x0D, 0x2C, 0x00, 0x00, 0x56, 0xC0, 0x09, 0x00, 0x6A, 0x1E, 0x02, 0x00, 0x48, 0xC0, 0x01, 0x00,
|
|
0x43, 0x04, 0x03, 0x00, 0x6C, 0x20, 0x02, 0x00, 0x55, 0x40, 0x19, 0x00, 0x01, 0x2C, 0x01, 0x00,
|
|
0x65, 0x23, 0x01, 0x00, 0x42, 0x42, 0x03, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x24, 0x14, 0x01, 0x00,
|
|
0x00, 0x2C, 0x01, 0x00, 0x24, 0x14, 0x01, 0x00, 0x00, 0x3C, 0x01, 0x00, 0x42, 0x04, 0x09, 0x00,
|
|
0x42, 0xC3, 0x02, 0x00, 0x65, 0x54, 0x01, 0x00, 0x65, 0x55, 0x01, 0x00, 0x42, 0x45, 0x0D, 0x00,
|
|
0x62, 0x03, 0x00, 0x00, 0x62, 0x44, 0x00, 0x00, 0x62, 0x85, 0x00, 0x00, 0x62, 0xC2, 0x00, 0x00,
|
|
0x22, 0x48, 0x1F, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x48, 0x00, 0x01, 0x00, 0x6C, 0x28, 0x02, 0x00,
|
|
0x62, 0x80, 0x01, 0x00, 0x60, 0x07, 0x00, 0x00, 0x60, 0x47, 0x00, 0x00, 0x60, 0x87, 0x00, 0x00,
|
|
0x01, 0x01, 0x00, 0x00, 0x43, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x01, 0xCA, 0x01, 0x00,
|
|
0x60, 0x03, 0x01, 0x00, 0x01, 0xA0, 0x01, 0x00, 0x60, 0x40, 0x00, 0x00, 0x65, 0x01, 0x00, 0x00,
|
|
0x55, 0xC0, 0x2E, 0x00, 0x01, 0x18, 0x00, 0x00, 0x43, 0x00, 0x04, 0x00, 0x43, 0x41, 0x06, 0x00,
|
|
0x6F, 0x00, 0x00, 0x00, 0x61, 0xC1, 0x00, 0x00, 0x61, 0x42, 0x01, 0x00, 0x65, 0xB5, 0x00, 0x00,
|
|
0x65, 0x73, 0x01, 0x00, 0x65, 0x35, 0x01, 0x00, 0x65, 0x34, 0x01, 0x00, 0x42, 0x04, 0x0D, 0x00,
|
|
0x01, 0x14, 0x01, 0x00, 0x42, 0x04, 0x03, 0x00, 0x00, 0x20, 0x00, 0x00, 0x43, 0x03, 0x05, 0x00,
|
|
0x43, 0x85, 0x02, 0x00, 0x00, 0xAA, 0x00, 0x00, 0x48, 0x46, 0x01, 0x00, 0x65, 0xEB, 0x00, 0x00,
|
|
0x00, 0x9A, 0x00, 0x00, 0x65, 0xB2, 0x01, 0x00, 0x00, 0xA6, 0x01, 0x00, 0x42, 0x86, 0x0D, 0x00,
|
|
0x61, 0x42, 0x01, 0x00, 0x01, 0xAE, 0x01, 0x00, 0x00, 0x71, 0x00, 0x00, 0x42, 0x82, 0x08, 0x00,
|
|
0x42, 0xC3, 0x08, 0x00, 0x48, 0x40, 0x01, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x6E, 0x34, 0x02, 0x00,
|
|
0x65, 0x79, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x6C, 0x36, 0x04, 0x00, 0x6E, 0x34, 0x02, 0x00,
|
|
0x48, 0x7F, 0x01, 0x00, 0x6C, 0x0A, 0x06, 0x00, 0x6E, 0x34, 0x02, 0x00, 0x6E, 0x05, 0x04, 0x00,
|
|
0x65, 0x79, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x41, 0x87, 0x03, 0x00, 0x65, 0xBA, 0x00, 0x00,
|
|
0x65, 0xB2, 0x00, 0x00, 0x42, 0x82, 0x02, 0x00, 0x00, 0x51, 0x00, 0x00, 0x61, 0xC1, 0x00, 0x00,
|
|
0x65, 0xFB, 0x00, 0x00, 0x65, 0xF3, 0x00, 0x00, 0x41, 0x87, 0x05, 0x00, 0x65, 0xF3, 0x00, 0x00,
|
|
0x42, 0xC3, 0x08, 0x00, 0x00, 0x59, 0x00, 0x00, 0x60, 0xC7, 0x00, 0x00, 0x60, 0xC7, 0x00, 0x00,
|
|
0x56, 0xC0, 0x21, 0x00, 0x04, 0xDF, 0x01, 0x00, 0x43, 0xC7, 0x15, 0x00, 0x00, 0x38, 0x00, 0x00,
|
|
0x00, 0x79, 0x00, 0x00, 0x42, 0xC3, 0x20, 0x00, 0x43, 0xC3, 0x04, 0x00, 0x42, 0x00, 0x30, 0x00,
|
|
0x42, 0x41, 0x30, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x4B, 0x00, 0x00, 0x60, 0xC7, 0x01, 0x00,
|
|
0x22, 0x78, 0x01, 0x00, 0x22, 0x79, 0x03, 0x00, 0x22, 0x7F, 0x1F, 0x00, 0x6F, 0x00, 0x00, 0x00,
|
|
0x6E, 0x34, 0x02, 0x00, 0x6E, 0x05, 0x04, 0x00, 0x4B, 0x41, 0x00, 0x00, 0x60, 0xC7, 0x01, 0x00,
|
|
0x60, 0x87, 0x01, 0x00, 0x43, 0x86, 0x15, 0x00, 0x00, 0x30, 0x00, 0x00, 0x65, 0x39, 0x01, 0x00,
|
|
0x42, 0x04, 0x05, 0x00, 0x4E, 0x05, 0x7E, 0x00, 0x6A, 0x1B, 0x06, 0x00, 0x55, 0xC0, 0x3D, 0x00,
|
|
0x0A, 0x3C, 0x01, 0x00, 0x60, 0xC7, 0x01, 0x00, 0x22, 0x78, 0x01, 0x00, 0x22, 0x79, 0x03, 0x00,
|
|
0x22, 0x7C, 0x09, 0x00, 0x22, 0x7F, 0x1F, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x65, 0x7A, 0x01, 0x00,
|
|
0x42, 0x45, 0x05, 0x00, 0x65, 0xBB, 0x01, 0x00, 0x42, 0x86, 0x05, 0x00, 0x55, 0xC0, 0x3D, 0x00,
|
|
0x0A, 0x7D, 0x01, 0x00, 0x0A, 0xBE, 0x01, 0x00, 0x07, 0xC7, 0x01, 0x00, 0x0B, 0x7D, 0x01, 0x00,
|
|
0x0B, 0xBE, 0x01, 0x00, 0x55, 0xC0, 0x3D, 0x00, 0x0A, 0x3C, 0x01, 0x00, 0x60, 0xC7, 0x01, 0x00,
|
|
0x22, 0x78, 0x01, 0x00, 0x22, 0x79, 0x03, 0x00, 0x22, 0x7A, 0x05, 0x00, 0x22, 0x7B, 0x07, 0x00,
|
|
0x22, 0x7C, 0x09, 0x00, 0x22, 0x7D, 0x0B, 0x00, 0x22, 0x7E, 0x0D, 0x00, 0x22, 0x7F, 0x1F, 0x00,
|
|
0x6F, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
vic_config_t __attribute__((aligned (0x100))) vic_cfg = {0};
|
|
|
|
u32 _vic_read_priv(u32 addr)
|
|
{
|
|
u32 addr_lsb = addr & 0xFF;
|
|
|
|
// Set address LSB.
|
|
if (addr_lsb)
|
|
VIC(PVIC_FALCON_ADDR) = addr_lsb >> 2;
|
|
|
|
// Set address.
|
|
u32 val = VIC(PVIC_FALCON_PA_OFFSET + (addr >> 6));
|
|
|
|
// Unset address LSB.
|
|
if (addr_lsb)
|
|
VIC(PVIC_FALCON_ADDR) = 0;
|
|
|
|
return val;
|
|
}
|
|
|
|
static void _vic_write_priv(u32 addr, u32 data)
|
|
{
|
|
u32 addr_lsb = addr & 0xFF;
|
|
|
|
// Set address LSB.
|
|
if (addr_lsb)
|
|
VIC(PVIC_FALCON_ADDR) = addr_lsb >> 2;
|
|
|
|
// Set address.
|
|
VIC(PVIC_FALCON_PA_OFFSET + (addr >> 6)) = data;
|
|
|
|
// Unset address LSB.
|
|
if (addr_lsb)
|
|
VIC(PVIC_FALCON_ADDR) = 0;
|
|
}
|
|
|
|
static int _vic_wait_idle()
|
|
{
|
|
u32 timeout_count = 15000; // 150ms.
|
|
|
|
while (VIC(PVIC_FALCON_IDLESTATE))
|
|
{
|
|
usleep(10);
|
|
|
|
timeout_count--;
|
|
if (!timeout_count)
|
|
return -1;
|
|
};
|
|
|
|
return 0;
|
|
}
|
|
|
|
void vic_set_surface(vic_surface_t *sfc)
|
|
{
|
|
u32 flip_x = 0;
|
|
u32 flip_y = 0;
|
|
u32 swap_xy = 0;
|
|
u32 const_alpha = 0;
|
|
|
|
u32 width = sfc->width;
|
|
u32 height = sfc->height;
|
|
u32 pix_fmt = sfc->pix_fmt;
|
|
u32 src_buf = sfc->src_buf;
|
|
u32 dst_buf = sfc->dst_buf;
|
|
|
|
// Get format alpha type.
|
|
switch (sfc->pix_fmt)
|
|
{
|
|
case VIC_PIX_FORMAT_L8:
|
|
case VIC_PIX_FORMAT_X1B5G5R5:
|
|
case VIC_PIX_FORMAT_B5G5R5X1:
|
|
case VIC_PIX_FORMAT_X8B8G8R8:
|
|
case VIC_PIX_FORMAT_X8R8G8B8:
|
|
case VIC_PIX_FORMAT_B8G8R8X8:
|
|
case VIC_PIX_FORMAT_R8G8B8X8:
|
|
const_alpha = 1;
|
|
break;
|
|
|
|
case VIC_PIX_FORMAT_A8B8G8R8:
|
|
case VIC_PIX_FORMAT_A8R8G8B8:
|
|
case VIC_PIX_FORMAT_B8G8R8A8:
|
|
case VIC_PIX_FORMAT_R8G8B8A8:
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// Get rotation parameters.
|
|
switch (sfc->rotation)
|
|
{
|
|
case VIC_ROTATION_90:
|
|
swap_xy = 1;
|
|
break;
|
|
|
|
case VIC_ROTATION_180:
|
|
flip_x = 1;
|
|
flip_y = 1;
|
|
break;
|
|
|
|
case VIC_ROTATION_270:
|
|
flip_x = 1;
|
|
swap_xy = 1;
|
|
break;
|
|
|
|
case VIC_ROTATION_0:
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// Set output surface format.
|
|
vic_cfg.out_sfc_cfg.OutPixelFormat = pix_fmt;
|
|
vic_cfg.out_sfc_cfg.OutBlkKind = BLK_KIND_PITCH;
|
|
vic_cfg.out_sfc_cfg.OutBlkHeight = 0;
|
|
|
|
// Set output rotation/flip.
|
|
vic_cfg.out_cfg.OutputFlipX = flip_x;
|
|
vic_cfg.out_cfg.OutputFlipY = flip_y;
|
|
vic_cfg.out_cfg.OutputTranspose = swap_xy;
|
|
|
|
// Set output surface resolution.
|
|
vic_cfg.out_sfc_cfg.OutSurfaceWidth = width - 1;
|
|
vic_cfg.out_sfc_cfg.OutSurfaceHeight = height - 1;
|
|
vic_cfg.out_sfc_cfg.OutLumaWidth = width - 1;
|
|
vic_cfg.out_sfc_cfg.OutLumaHeight = height - 1;
|
|
|
|
// Set output destination rectangle. Anything outside will not be touched at output buffer.
|
|
vic_cfg.out_cfg.TargetRectLeft = 0;
|
|
vic_cfg.out_cfg.TargetRectRight = width - 1;
|
|
vic_cfg.out_cfg.TargetRectTop = 0;
|
|
vic_cfg.out_cfg.TargetRectBottom = height - 1;
|
|
|
|
// Initialize slot parameters.
|
|
vic_cfg.slots[0].slot_cfg.SlotEnable = 1;
|
|
vic_cfg.slots[0].slot_cfg.SoftClampLow = SOFT_CLAMP_MIN;
|
|
vic_cfg.slots[0].slot_cfg.SoftClampHigh = SOFT_CLAMP_MAX;
|
|
vic_cfg.slots[0].slot_cfg.PlanarAlpha = ALPHA_1_0;
|
|
vic_cfg.slots[0].slot_cfg.ConstantAlpha = const_alpha;
|
|
vic_cfg.slots[0].slot_cfg.FrameFormat = FORMAT_PROGRESSIVE;
|
|
|
|
// Set input source rectangle.
|
|
vic_cfg.slots[0].slot_cfg.SourceRectLeft = 0;
|
|
vic_cfg.slots[0].slot_cfg.SourceRectRight = (width - 1) << 16;
|
|
vic_cfg.slots[0].slot_cfg.SourceRectTop = 0;
|
|
vic_cfg.slots[0].slot_cfg.SourceRectBottom = (height - 1) << 16;
|
|
|
|
// Set input destination rectangle.
|
|
vic_cfg.slots[0].slot_cfg.DestRectLeft = 0;
|
|
vic_cfg.slots[0].slot_cfg.DestRectRight = (width - 1);
|
|
vic_cfg.slots[0].slot_cfg.DestRectTop = 0;
|
|
vic_cfg.slots[0].slot_cfg.DestRectBottom = (height - 1);
|
|
|
|
// Set input surface format.
|
|
vic_cfg.slots[0].slot_sfc_cfg.SlotPixelFormat = pix_fmt;
|
|
vic_cfg.slots[0].slot_sfc_cfg.SlotBlkKind = BLK_KIND_PITCH;
|
|
vic_cfg.slots[0].slot_sfc_cfg.SlotBlkHeight = 0;
|
|
vic_cfg.slots[0].slot_sfc_cfg.SlotCacheWidth = CACHE_WIDTH_64BX4;
|
|
|
|
// Set input surface resolution.
|
|
vic_cfg.slots[0].slot_sfc_cfg.SlotSurfaceWidth = width - 1;
|
|
vic_cfg.slots[0].slot_sfc_cfg.SlotSurfaceHeight = height - 1;
|
|
vic_cfg.slots[0].slot_sfc_cfg.SlotLumaWidth = width - 1;
|
|
vic_cfg.slots[0].slot_sfc_cfg.SlotLumaHeight = height - 1;
|
|
|
|
// Flush data.
|
|
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLEAN_WAY, false);
|
|
|
|
// Set parameters base and size. Causes a parse by surface cache.
|
|
_vic_write_priv(VIC_SC_PRAMBASE, (u32)&vic_cfg >> 8);
|
|
_vic_write_priv(VIC_SC_PRAMSIZE, sizeof(vic_config_t) >> 6);
|
|
|
|
// Wait for surface cache to get ready.
|
|
_vic_wait_idle();
|
|
|
|
// Set slot mapping.
|
|
_vic_write_priv(VIC_FC_SLOT_MAP, 0xFFFFFFF0);
|
|
|
|
// Set input surface buffer.
|
|
_vic_write_priv(VIC_SC_SFC0_BASE_LUMA(0), src_buf >> 8);
|
|
|
|
// Set output surface buffer.
|
|
_vic_write_priv(VIC_BL_TARGET_BASADR, dst_buf >> 8);
|
|
|
|
// Set blending config and push changes to surface cache.
|
|
_vic_write_priv(VIC_BL_CONFIG, SLOTMASK(0x1F) | PROCESS_CFG_STRUCT_TRIGGER | SUBPARTITION_MODE);
|
|
|
|
// Wait for surface cache to get ready.
|
|
_vic_wait_idle();
|
|
}
|
|
|
|
int vic_compose()
|
|
{
|
|
// Wait for surface cache to get ready. Otherwise VIC will hang.
|
|
int res = _vic_wait_idle();
|
|
|
|
// Start composition of a single frame.
|
|
_vic_write_priv(VIC_FC_COMPOSE, COMPOSE_START);
|
|
|
|
return res;
|
|
}
|
|
|
|
int vic_init()
|
|
{
|
|
// Ease the stress to APB.
|
|
bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL);
|
|
|
|
clock_enable_vic();
|
|
|
|
// Restore sys clock.
|
|
bpmp_clk_rate_set(prev_fid);
|
|
|
|
// Load Fetch Control Engine microcode.
|
|
for (u32 i = 0; i < sizeof(vic_fce_ucode) / sizeof(u32); i++)
|
|
{
|
|
_vic_write_priv(VIC_FC_FCE_UCODE_ADDR, (i * sizeof(u32)));
|
|
_vic_write_priv(VIC_FC_FCE_UCODE_INST, *(u32 *)&vic_fce_ucode[i * sizeof(u32)]);
|
|
}
|
|
|
|
// Start Fetch Control Engine.
|
|
_vic_write_priv(VIC_FC_FCE_CTRL, START_TRIGGER);
|
|
|
|
return _vic_wait_idle();
|
|
}
|
|
|
|
void vic_end()
|
|
{
|
|
clock_disable_vic();
|
|
}
|