bdk: Add driver for VIC

VIC is a HW engine that allows for frame/texture buffer manipulation.
This commit is contained in:
CTCaer 2022-10-11 06:41:38 +03:00
parent efe6e2f206
commit 9d889e2c3e
9 changed files with 679 additions and 2 deletions

View File

@ -20,6 +20,7 @@
#include <memory_map.h>
#include <display/di.h>
#include <display/vic.h>
#include <input/als.h>
#include <input/joycon.h>
#include <input/touch.h>

View File

@ -867,6 +867,15 @@ u32 *display_init_framebuffer_pitch()
return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
}
u32 *display_init_framebuffer_pitch_vic()
{
// This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 720x1280 (line stride 720).
exec_cfg((u32 *)DISPLAY_A_BASE, _di_win_framebuffer_pitch_vic, CFG_SIZE(_di_win_framebuffer_pitch_vic));
usleep(35000); // Wait 2 frames. No need on Aula.
return (u32 *)DISPLAY_A(_DIREG(DC_WINBUF_START_ADDR));
}
u32 *display_init_framebuffer_pitch_inv()
{
// This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 720x1280 (line stride 720).

View File

@ -805,6 +805,7 @@ u32 display_get_backlight_brightness();
/*! Init display in full 720x1280 resolution (B8G8R8A8, line stride 720, framebuffer size = 720*1280*4 bytes). */
u32 *display_init_framebuffer_pitch();
u32 *display_init_framebuffer_pitch_vic();
u32 *display_init_framebuffer_pitch_inv();
u32 *display_init_framebuffer_block();
u32 *display_init_framebuffer_log();

View File

@ -504,6 +504,32 @@ static const cfg_op_t _di_win_framebuffer_pitch[] = {
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
};
// Display A Window A linear pitch + Win D support config.
static const cfg_op_t _di_win_framebuffer_pitch_vic[] = {
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT | WINDOW_C_SELECT | WINDOW_B_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
{DC_WIN_WIN_OPTIONS, 0},
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, // NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8.
{DC_WIN_POSITION, 0}, //(0,0)
{DC_WIN_H_INITIAL_DDA, 0},
{DC_WIN_V_INITIAL_DDA, 0},
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
{DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST},
{DC_WINBUF_SURFACE_KIND, PITCH},
{DC_WINBUF_START_ADDR, NYX_FB_ADDRESS}, // Framebuffer address.
{DC_WINBUF_ADDR_H_OFFSET, 0},
{DC_WINBUF_ADDR_V_OFFSET, 0},
{DC_WIN_WIN_OPTIONS, WIN_ENABLE}, // Enable window AD.
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display.
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
};
// Display A Window A linear pitch inverse + Win D support config.
static const cfg_op_t _di_win_framebuffer_pitch_inv[] = {
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT | WINDOW_C_SELECT | WINDOW_B_SELECT},

558
bdk/display/vic.c Normal file
View File

@ -0,0 +1,558 @@
/*
* VIC driver for Tegra X1
*
* Copyright (c) 2018-2019 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;
}
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_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()
{
clock_enable_host1x();
clock_enable_vic();
// 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();
}

63
bdk/display/vic.h Normal file
View File

@ -0,0 +1,63 @@
/*
* VIC driver for Tegra X1
*
* Copyright (c) 2018-2019 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/>.
*/
#ifndef _VIC_H_
#define _VIC_H_
#include <utils/types.h>
#define VIC_THI_SLCG_OVERRIDE_LOW_A 0x8C
typedef enum _vic_rotation_t
{
VIC_ROTATION_0 = 0,
VIC_ROTATION_90 = 1,
VIC_ROTATION_180 = 2,
VIC_ROTATION_270 = 3,
} vic_rotation_t;
typedef enum _vic_pix_format_t
{
VIC_PIX_FORMAT_A8B8G8R8 = 31, // 32-bit ABGR.
VIC_PIX_FORMAT_A8R8G8B8 = 32, // 32-bit ARGB.
VIC_PIX_FORMAT_B8G8R8A8 = 33, // 32-bit BGRA.
VIC_PIX_FORMAT_R8G8B8A8 = 34, // 32-bit RGBA.
VIC_PIX_FORMAT_X8B8G8R8 = 35, // 32-bit XBGR.
VIC_PIX_FORMAT_X8R8G8B8 = 36, // 32-bit XRGB.
VIC_PIX_FORMAT_B8G8R8X8 = 37, // 32-bit BGRX.
VIC_PIX_FORMAT_R8G8B8X8 = 38, // 32-bit RGBX.
} vic_pix_format_t;
typedef struct _vic_surface_t
{
u32 src_buf;
u32 dst_buf;
u32 width;
u32 height;
u32 pix_fmt;
u32 rotation;
} vic_surface_t;
void vic_set_surface(vic_surface_t *sfc);
int vic_compose();
int vic_init();
void vic_end();
#endif

View File

@ -77,6 +77,9 @@ static clock_t _clock_nvdec = {
static clock_t _clock_nvjpg = {
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_NVJPG, CLK_Y_NVJPG, 4, 0 // 408 MHz. Max: 627.2/652.8MHz.
};
static clock_t _clock_vic = {
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_VIC, CLK_X_VIC, 2, 0 // 408 MHz. Max: 627.2/652.8MHz.
};
static clock_t _clock_sor_safe = {
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_NO_SOURCE, CLK_Y_SOR_SAFE, 0, 0
};
@ -242,6 +245,16 @@ void clock_disable_nvjpg()
clock_disable(&_clock_nvjpg);
}
void clock_enable_vic()
{
clock_enable(&_clock_vic);
}
void clock_disable_vic()
{
clock_disable(&_clock_vic);
}
void clock_enable_sor_safe()
{
clock_enable(&_clock_sor_safe);

View File

@ -156,6 +156,7 @@
#define CLK_RST_CONTROLLER_CLK_SOURCE_I2C6 0x65C
#define CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL 0x664
#define CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL 0x66C
#define CLK_RST_CONTROLLER_CLK_SOURCE_VIC 0x678
#define CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM 0x694
#define CLK_RST_CONTROLLER_CLK_SOURCE_NVDEC 0x698
#define CLK_RST_CONTROLLER_CLK_SOURCE_NVJPG 0x69C
@ -655,6 +656,8 @@ void clock_enable_nvdec();
void clock_disable_nvdec();
void clock_enable_nvjpg();
void clock_disable_nvjpg();
void clock_enable_vic();
void clock_disable_vic();
void clock_enable_sor_safe();
void clock_disable_sor_safe();
void clock_enable_sor0();

View File

@ -19,6 +19,7 @@
#include <soc/hw_init.h>
#include <display/di.h>
#include <display/vic.h>
#include <input/joycon.h>
#include <input/touch.h>
#include <sec/se.h>
@ -174,8 +175,9 @@ static void _mbist_workaround()
I2S(I2S5_CTRL) |= I2S_CTRL_MASTER_EN;
I2S(I2S5_CG) &= ~I2S_CG_SLCG_ENABLE;
// Set SLCG overrides.
DISPLAY_A(_DIREG(DC_COM_DSC_TOP_CTL)) |= 4; // DSC_SLCG_OVERRIDE.
VIC(0x8C) = 0xFFFFFFFF; // NV_PVIC_THI_CONFIG0.
VIC(VIC_THI_SLCG_OVERRIDE_LOW_A) = 0xFFFFFFFF;
usleep(2);
// Set per-clock reset for APE/VIC/HOST1X/DISP1.
@ -421,7 +423,8 @@ void hw_reinit_workaround(bool coreboot, u32 bl_magic)
bpmp_clk_rate_set(BPMP_CLK_NORMAL);
#ifdef BDK_HW_EXTRA_DEINIT
// Disable temperature sensor, touchscreen, 5V regulators and Joy-Con.
// Disable temperature sensor, touchscreen, 5V regulators, Joy-Con and VIC.
vic_end();
tmp451_end();
set_fan_duty(0);
touch_power_off();