6 Commits
v0.10 ... v0.11

Author SHA1 Message Date
Mario Bălănică
19360cf5b2 Update README.md
Signed-off-by: Mario Bălănică <mariobalanica02@gmail.com>
2024-07-09 05:50:16 +03:00
Mario Bălănică
066de1179b FydetabDuo: Add display support
The panel is a 1600x2560 CSOT PNC357DB1-4.

Signed-off-by: Mario Bălănică <mariobalanica02@gmail.com>
2024-07-09 05:22:31 +03:00
Mario Bălănică
9797896a6d Add MIPI DSI support
Signed-off-by: Mario Bălănică <mariobalanica02@gmail.com>
2024-07-09 05:22:30 +03:00
Mario Bălănică
f8768a8a02 Add initial support for Fydetab Duo
The DSI panel is not yet working.

Signed-off-by: Mario Bălănică <mariobalanica02@gmail.com>
2024-07-09 05:22:29 +03:00
Mario Bălănică
c02b333c22 RkSdmmcDxe: Add option for inverted card detect signal
It's worth noting that when the detection logic is inverted,
the boot ROM assumes the SD card is disconnected and skips
booting from it altogether.

Signed-off-by: Mario Bălănică <mariobalanica02@gmail.com>
2024-07-09 05:22:29 +03:00
Mario Bălănică
1b6ef19bf3 RkSdmmcPlatformLib: Ensure JTAG is disabled
If the card is not connected at boot, force_jtag in
SYS_GRF_SOC_CON6 may remain set. This muxes DAT2/DAT3 over
to JTAG instead of SDMMC, preventing SD card operation in
4-bit mode.

Signed-off-by: Mario Bălănică <mariobalanica02@gmail.com>
2024-07-09 05:22:24 +03:00
50 changed files with 7721 additions and 76 deletions

View File

@@ -29,6 +29,7 @@ jobs:
- orangepi-5
- orangepi-5plus
- indiedroid-nova
- fydetab-duo
- roc-rk3588s-pc
- itx-3588j
- aio-3588q

View File

@@ -8,6 +8,7 @@ This repository contains an UEFI firmware implementation based on EDK2 for vario
- [Orange Pi 5](http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/details/Orange-Pi-5.html)
- [Orange Pi 5 Plus](http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/details/Orange-Pi-5-plus.html)
- [ameriDroid Indiedroid Nova](https://indiedroid.us)
- [Fydetab Duo](https://fydetabduo.com/)
- [Firefly AIO-3588Q](https://en.t-firefly.com/product/industry/aio3588q)
- [Firefly ITX-3588J](https://en.t-firefly.com/product/industry/itx3588j)
- [Firefly ROC-RK3588S-PC](https://en.t-firefly.com/product/industry/rocrk3588spc)
@@ -55,7 +56,7 @@ This repository contains an UEFI firmware implementation based on EDK2 for vario
| HDMI output | 🟡 Partial | Single display with mode limited at 1080p 60 Hz |
| DisplayPort output (USB-C) | 🟡 Partial | Mode fixed at 1080p 60 Hz, only works in one orientation of the Type-C port. Some displays may not work regardless. |
| eDP output | 🟡 Partial | Disabled, requires manual configuration depending on the platform and panel. |
| DSI output | 🔴 Not working | |
| DSI output | 🟢 Working | Only enabled on Fydetab Duo. Requires manual configuration depending on the platform and panel. |
| GMAC Ethernet | 🔴 Not working | Only brought-up for OS usage |
| Realtek PCIe Ethernet | 🟢 Working | Some platforms don't have MAC addresses set, networking may not work in that case. |
| UART | 🟢 Working | UART2 console available at 1500000 baud rate |

3
configs/fydetab-duo.conf Normal file
View File

@@ -0,0 +1,3 @@
DSC_FILE=edk2-rockchip/Platform/FydeInnovations/FydetabDuo/FydetabDuo.dsc
PLATFORM_NAME=FydetabDuo
SOC=RK3588

View File

@@ -0,0 +1,57 @@
#/** @file
#
# ACPI table data and ASL sources required to boot the platform.
#
# Copyright (c) 2019-2021, ARM Limited. All rights reserved.
# Copyright (c) Microsoft Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
#**/
[Defines]
INF_VERSION = 0x0001001A
BASE_NAME = AcpiTables
FILE_GUID = 7E374E25-8E01-4FEE-87F2-390C23C606CD
MODULE_TYPE = USER_DEFINED
VERSION_STRING = 1.0
RK_COMMON_ACPI_DIR = Silicon/Rockchip/RK3588/AcpiTables
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = AARCH64
#
[Sources]
Dsdt.asl
$(RK_COMMON_ACPI_DIR)/Madt.aslc
$(RK_COMMON_ACPI_DIR)/Fadt.aslc
$(RK_COMMON_ACPI_DIR)/Gtdt.aslc
$(RK_COMMON_ACPI_DIR)/Spcr.aslc
$(RK_COMMON_ACPI_DIR)/Mcfg.aslc
$(RK_COMMON_ACPI_DIR)/Dbg2.aslc
$(RK_COMMON_ACPI_DIR)/Pptt.aslc
[Packages]
ArmPkg/ArmPkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
EmbeddedPkg/EmbeddedPkg.dec
MdeModulePkg/MdeModulePkg.dec
MdePkg/MdePkg.dec
Silicon/Rockchip/RockchipPkg.dec
Silicon/Rockchip/RK3588/RK3588.dec
[FixedPcd]
gArmTokenSpaceGuid.PcdArmArchTimerIntrNum
gArmTokenSpaceGuid.PcdArmArchTimerHypIntrNum
gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum
gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
gArmTokenSpaceGuid.PcdGicDistributorBase
gArmTokenSpaceGuid.PcdGicRedistributorsBase
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase
gRK3588TokenSpaceGuid.PcdI2S0Supported
gRK3588TokenSpaceGuid.PcdI2S1Supported
gRockchipTokenSpaceGuid.PcdRkMtlMailBoxBase
gRockchipTokenSpaceGuid.PcdRkMtlMailBoxSize

View File

@@ -0,0 +1,52 @@
/** @file
*
* Differentiated System Definition Table (DSDT)
*
* Copyright (c) 2020, Pete Batard <pete@akeo.ie>
* Copyright (c) 2018-2020, Andrey Warkentin <andrey.warkentin@gmail.com>
* Copyright (c) Microsoft Corporation. All rights reserved.
* Copyright (c) 2021, ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*
**/
#include "AcpiTables.h"
#define BOARD_I2S0_TPLG "i2s-jack"
#define BOARD_AUDIO_CODEC_HID "ESSX8388"
#define BOARD_CODEC_I2C "\\_SB.I2C7"
#define BOARD_CODEC_I2C_ADDR 0x11
#define BOARD_CODEC_GPIO "\\_SB.GPI1"
#define BOARD_CODEC_GPIO_PIN GPIO_PIN_PC0
DefinitionBlock ("Dsdt.aml", "DSDT", 2, "RKCP ", "RK3588 ", 2)
{
Scope (\_SB_)
{
include ("DsdtCommon.asl")
include ("Cpu.asl")
include ("Pcie.asl")
include ("Sata.asl")
include ("Emmc.asl")
include ("Sdhc.asl")
include ("Dma.asl")
include ("Gpio.asl")
include ("I2c.asl")
include ("Uart.asl")
include ("I2s.asl")
include ("Usb2Host.asl")
include ("Usb3Host0.asl")
include ("Usb3Host2.asl")
Scope (I2C7) {
include ("Es8388.asl")
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

View File

@@ -0,0 +1,144 @@
/** @file
Logo DXE Driver, install Edkii Platform Logo protocol.
Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>
Copyright (c) 2022 Rockchip Electronics Co. Ltd.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Uefi.h>
#include <Protocol/HiiDatabase.h>
#include <Protocol/GraphicsOutput.h>
#include <Protocol/HiiImageEx.h>
#include <Protocol/PlatformLogo.h>
#include <Protocol/HiiPackageList.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/DebugLib.h>
typedef struct {
EFI_IMAGE_ID ImageId;
EDKII_PLATFORM_LOGO_DISPLAY_ATTRIBUTE Attribute;
INTN OffsetX;
INTN OffsetY;
} LOGO_ENTRY;
STATIC EFI_HII_IMAGE_EX_PROTOCOL *mHiiImageEx;
STATIC EFI_HII_HANDLE mHiiHandle;
STATIC LOGO_ENTRY mLogos[] = {
{
IMAGE_TOKEN (IMG_LOGO),
EdkiiPlatformLogoDisplayAttributeCenter,
0,
0
}
};
/**
Load a platform logo image and return its data and attributes.
@param This The pointer to this protocol instance.
@param Instance The visible image instance is found.
@param Image Points to the image.
@param Attribute The display attributes of the image returned.
@param OffsetX The X offset of the image regarding the Attribute.
@param OffsetY The Y offset of the image regarding the Attribute.
@retval EFI_SUCCESS The image was fetched successfully.
@retval EFI_NOT_FOUND The specified image could not be found.
**/
STATIC
EFI_STATUS
EFIAPI
GetImage (
IN EDKII_PLATFORM_LOGO_PROTOCOL *This,
IN OUT UINT32 *Instance,
OUT EFI_IMAGE_INPUT *Image,
OUT EDKII_PLATFORM_LOGO_DISPLAY_ATTRIBUTE *Attribute,
OUT INTN *OffsetX,
OUT INTN *OffsetY
)
{
UINT32 Current;
if (Instance == NULL || Image == NULL ||
Attribute == NULL || OffsetX == NULL || OffsetY == NULL) {
return EFI_INVALID_PARAMETER;
}
Current = *Instance;
if (Current >= ARRAY_SIZE (mLogos)) {
return EFI_NOT_FOUND;
}
(*Instance)++;
*Attribute = mLogos[Current].Attribute;
*OffsetX = mLogos[Current].OffsetX;
*OffsetY = mLogos[Current].OffsetY;
return mHiiImageEx->GetImageEx (mHiiImageEx, mHiiHandle,
mLogos[Current].ImageId, Image);
}
STATIC EDKII_PLATFORM_LOGO_PROTOCOL mPlatformLogo = {
GetImage
};
/**
Entrypoint of this module.
This function is the entrypoint of this module. It installs the Edkii
Platform Logo protocol.
@param ImageHandle The firmware allocated handle for the EFI image.
@param SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS The entry point is executed successfully.
**/
EFI_STATUS
EFIAPI
InitializeLogo (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_HII_PACKAGE_LIST_HEADER *PackageList;
EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
EFI_HANDLE Handle;
Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL,
(VOID **) &HiiDatabase);
ASSERT_EFI_ERROR (Status);
Status = gBS->LocateProtocol (&gEfiHiiImageExProtocolGuid, NULL,
(VOID **) &mHiiImageEx);
ASSERT_EFI_ERROR (Status);
//
// Retrieve HII package list from ImageHandle
//
Status = gBS->OpenProtocol (ImageHandle, &gEfiHiiPackageListProtocolGuid,
(VOID **) &PackageList, ImageHandle, NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR,
"HII Image Package with logo not found in PE/COFF resource section\n"));
return Status;
}
//
// Publish HII package list to HII Database.
//
Status = HiiDatabase->NewPackageList (HiiDatabase, PackageList, NULL,
&mHiiHandle);
if (!EFI_ERROR (Status)) {
Handle = NULL;
Status = gBS->InstallMultipleProtocolInterfaces (&Handle,
&gEdkiiPlatformLogoProtocolGuid, &mPlatformLogo, NULL);
}
return Status;
}

View File

@@ -0,0 +1,10 @@
// @file
// Platform Logo image definition file.
//
// Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>
// Copyright (c) 2022 Rockchip Electronics Co. Ltd.
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
#image IMG_LOGO Logo.bmp

View File

@@ -0,0 +1,48 @@
## @file
# The default logo bitmap picture shown on setup screen.
#
# Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>
# Copyright (c) 2022 Rockchip Electronics Co. Ltd.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
#
##
[Defines]
INF_VERSION = 0x0001001A
BASE_NAME = LogoDxe
FILE_GUID = 4b55f0bc-8b1a-11ec-bd4b-f42a7dcb925d
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = InitializeLogo
#
# This flag specifies whether HII resource section is generated into PE image.
#
UEFI_HII_RESOURCE_SECTION = TRUE
[Sources]
Logo.bmp
Logo.c
Logo.idf
[Packages]
MdeModulePkg/MdeModulePkg.dec
MdePkg/MdePkg.dec
[LibraryClasses]
UefiBootServicesTableLib
UefiDriverEntryPoint
DebugLib
[Protocols]
gEfiHiiDatabaseProtocolGuid ## CONSUMES
gEfiHiiImageExProtocolGuid ## CONSUMES
gEfiHiiPackageListProtocolGuid ## PRODUCES CONSUMES
gEdkiiPlatformLogoProtocolGuid ## PRODUCES
[Depex]
gEfiHiiDatabaseProtocolGuid AND
gEfiHiiImageExProtocolGuid

View File

@@ -0,0 +1,18 @@
## @file
#
# Copyright (c) 2023-2024, Mario Bălănică <mariobalanica02@gmail.com>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
# ACPI Support
INF RuleOverride = ACPITABLE $(PLATFORM_DIRECTORY)/AcpiTables/AcpiTables.inf
# TODO: Device Tree Support
# FILE FREEFORM = gDtPlatformDefaultDtbFileGuid {
# SECTION RAW = Platform/Rockchip/DeviceTree/rk3588s-9tripod-linux.dtb
# }
# Splash screen logo
INF $(PLATFORM_DIRECTORY)/Drivers/LogoDxe/LogoDxe.inf

View File

@@ -0,0 +1,113 @@
## @file
#
# Copyright (c) 2014-2018, Linaro Limited. All rights reserved.
# Copyright (c) 2023-2024, Mario Bălănică <mariobalanica02@gmail.com>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
################################################################################
#
# Defines Section - statements that will be processed to create a Makefile.
#
################################################################################
[Defines]
PLATFORM_NAME = FydetabDuo
PLATFORM_VENDOR = FydeInnovations
PLATFORM_GUID = de3232fb-1716-4f63-a8fe-67a623ae5297
PLATFORM_VERSION = 0.2
DSC_SPECIFICATION = 0x00010019
OUTPUT_DIRECTORY = Build/$(PLATFORM_NAME)
VENDOR_DIRECTORY = Platform/$(PLATFORM_VENDOR)
PLATFORM_DIRECTORY = $(VENDOR_DIRECTORY)/$(PLATFORM_NAME)
SUPPORTED_ARCHITECTURES = AARCH64
BUILD_TARGETS = DEBUG|RELEASE
SKUID_IDENTIFIER = DEFAULT
FLASH_DEFINITION = Silicon/Rockchip/RK3588/RK3588.fdf
RK_PLATFORM_FVMAIN_MODULES = $(PLATFORM_DIRECTORY)/$(PLATFORM_NAME).Modules.fdf.inc
#
# HYM8563 RTC support
# I2C location configured by PCDs below.
#
DEFINE RK_RTC8563_ENABLE = TRUE
# No HDMI output on this platform
DEFINE RK_DW_HDMI_QP_ENABLE = FALSE
#
# RK3588S-based platform
#
!include Silicon/Rockchip/RK3588/RK3588SPlatform.dsc.inc
################################################################################
#
# Library Class section - list of all Library Classes needed by this Platform.
#
################################################################################
[LibraryClasses.common]
RockchipPlatformLib|$(PLATFORM_DIRECTORY)/Library/RockchipPlatformLib/RockchipPlatformLib.inf
################################################################################
#
# Pcd Section - list of all EDK II PCD Entries defined by this Platform.
#
################################################################################
[PcdsFixedAtBuild.common]
# SMBIOS platform config
gRockchipTokenSpaceGuid.PcdPlatformName|"Fydetab Duo"
gRockchipTokenSpaceGuid.PcdPlatformVendorName|"Fyde Innovations"
gRockchipTokenSpaceGuid.PcdFamilyName|"Fydetab"
gRockchipTokenSpaceGuid.PcdProductUrl|"https://fydetabduo.com/"
gRockchipTokenSpaceGuid.PcdDeviceTreeName|"rk3588s-12c"
# I2C
gRockchipTokenSpaceGuid.PcdI2cSlaveAddresses|{ 0x42, 0x43, 0x50, 0x51, 0x11 }
gRockchipTokenSpaceGuid.PcdI2cSlaveBuses|{ 0x0, 0x0, 0x6, 0x6, 0x7 }
gRockchipTokenSpaceGuid.PcdI2cSlaveBusesRuntimeSupport|{ FALSE, FALSE, FALSE, TRUE, FALSE }
gRockchipTokenSpaceGuid.PcdRk860xRegulatorAddresses|{ 0x42, 0x43 }
gRockchipTokenSpaceGuid.PcdRk860xRegulatorBuses|{ 0x0, 0x0 }
gRockchipTokenSpaceGuid.PcdRk860xRegulatorTags|{ $(SCMI_CLK_CPUB01), $(SCMI_CLK_CPUB23) }
gPcf8563RealTimeClockLibTokenSpaceGuid.PcdI2cSlaveAddress|0x51
gRockchipTokenSpaceGuid.PcdRtc8563Bus|0x6
#
# CPU Performance default values
#
gRK3588TokenSpaceGuid.PcdCPULClusterClockPresetDefault|$(CPU_PERF_CLUSTER_CLOCK_PRESET_MAX)
gRK3588TokenSpaceGuid.PcdCPUB01ClusterClockPresetDefault|$(CPU_PERF_CLUSTER_CLOCK_PRESET_MAX)
gRK3588TokenSpaceGuid.PcdCPUB23ClusterClockPresetDefault|$(CPU_PERF_CLUSTER_CLOCK_PRESET_MAX)
#
# PCIe/SATA/USB Combo PIPE PHY support flags and default values
#
gRK3588TokenSpaceGuid.PcdComboPhy0ModeDefault|$(COMBO_PHY_MODE_PCIE)
#
# USB/DP Combo PHY support flags and default values
#
gRK3588TokenSpaceGuid.PcdUsbDpPhy0Supported|TRUE
gRK3588TokenSpaceGuid.PcdDp0LaneMux|{ 0x2, 0x3 }
#
# I2S
#
gRK3588TokenSpaceGuid.PcdI2S0Supported|TRUE
# SD card detect signal is inverted
gRockchipTokenSpaceGuid.PcdRkSdmmcCardDetectInverted|TRUE
################################################################################
#
# Components Section - list of all EDK II Modules needed by this Platform.
#
################################################################################
[Components.common]
# ACPI Support
$(PLATFORM_DIRECTORY)/AcpiTables/AcpiTables.inf
# Splash screen logo
$(PLATFORM_DIRECTORY)/Drivers/LogoDxe/LogoDxe.inf

View File

@@ -0,0 +1,171 @@
/** @file
*
* Copyright (c) 2024, Mario Bălănică <mariobalanica02@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*
**/
#include <Uefi.h>
#include <Protocol/RockchipDsiPanel.h>
#include <Library/GpioLib.h>
#include <Library/TimerLib.h>
#include <Library/UefiBootServicesTableLib.h>
STATIC UINT8 mCsotDsiInitSequence[] = {
0x0a, 0x31, 0x58, 0x11, 0x00, 0x00, 0x89, 0x30, 0x80, 0x0A, 0x00, 0x06, 0x40, 0x00, 0x28, 0x06, 0x40, 0x06, 0x40, 0x02, 0x00, 0x04, 0x21, 0x00, 0x20, 0x05, 0xD0, 0x00, 0x16, 0x00, 0x0C, 0x02, 0x77, 0x00, 0xDA, 0x18, 0x00, 0x10, 0xE0, 0x03, 0x0C, 0x20, 0x00, 0x06, 0x0B, 0x0B, 0x33, 0x0E, 0x1C, 0x2A, 0x38, 0x46, 0x54, 0x62, 0x69, 0x70, 0x77, 0x79, 0x7B, 0x7D, 0x7E, 0x01, 0x02, 0x01, 0x00, 0x09, 0x40, 0x09, 0xBE, 0x19, 0xFC, 0x19, 0xFA, 0x19, 0xF8, 0x1A, 0x38, 0x1A, 0x78, 0x1A, 0xB6, 0x2A, 0xF6, 0x2B, 0x34, 0x2B, 0x74, 0x3B, 0x74, 0x6B, 0x74,
0x39, 0x00, 0x06, 0xB9, 0x83, 0x12, 0x1A, 0x55, 0x00,
0x39, 0x00, 0x03, 0x51, 0x08, 0x00,
0x39, 0x00, 0x02, 0x53, 0x24,
0x39, 0x00, 0x1D, 0xB1, 0x1C, 0x6B, 0x6B, 0x27, 0xE7, 0x00, 0x1B, 0x12, 0x20, 0x20, 0x2D, 0x2D, 0x1F, 0x33, 0x31, 0x40, 0xCD, 0xFF, 0x1A, 0x05, 0x15, 0x98, 0x00, 0x88, 0xF9, 0xFF, 0xFF, 0xCF,
0x39, 0x00, 0x12, 0xB2, 0x00, 0x6A, 0x40, 0x00, 0x00, 0x14, 0x6E, 0x40, 0x73, 0x02, 0x80, 0x21, 0x21, 0x00, 0x00, 0x10, 0x27,
0x39, 0x00, 0x2D, 0xB4, 0x64, 0x00, 0x08, 0x7F, 0x08, 0x7F, 0x00, 0x62, 0x01, 0x72, 0x01, 0x72, 0x00, 0x60, 0x00, 0x00, 0x0A, 0x08, 0x00, 0x29, 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x14, 0x00, 0x00, 0x0F, 0x0F, 0x2D, 0x2D,
0x39, 0x00, 0x04, 0xB6, 0x8F, 0x8F, 0x03,
0x39, 0x00, 0x03, 0xBC, 0x06, 0x02,
0x39, 0x00, 0x07, 0xC0, 0x34, 0x34, 0x44, 0x00, 0x08, 0xD8,
0x39, 0x00, 0x06, 0xC9, 0x00, 0x1E, 0x80, 0xA5, 0x01,
0x39, 0x00, 0x07, 0xCB, 0x00, 0x13, 0x38, 0x00, 0x0B, 0x27,
0x39, 0x00, 0x02, 0xCC, 0x02,
0x39, 0x00, 0x02, 0xD1, 0x07,
0x39, 0x00, 0x29, 0xD3, 0x00, 0xC0, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x14, 0x02, 0x07, 0x07, 0x07, 0x31, 0x13, 0x12, 0x12, 0x12, 0x03, 0x03, 0x03, 0x32, 0x10, 0x11, 0x00, 0x11, 0x32, 0x10, 0x03, 0x00, 0x03, 0x32, 0x10, 0x03, 0x00, 0x03, 0x00, 0x00, 0xFF, 0x00,
0x39, 0x00, 0x31, 0xD5, 0x19, 0x19, 0x18, 0x18, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x00, 0x00, 0x01, 0x01, 0x18, 0x18, 0x40, 0x40, 0x20, 0x20, 0x18, 0x18, 0x18, 0x18, 0x40, 0x40, 0x18, 0x18, 0x2F, 0x2F, 0x31, 0x31, 0x2F, 0x2F, 0x31, 0x31, 0x18, 0x18, 0x41, 0x41, 0x41, 0x41,
0x39, 0x00, 0x31, 0xD6, 0x40, 0x40, 0x18, 0x18, 0x05, 0x05, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x07, 0x07, 0x06, 0x06, 0x18, 0x18, 0x19, 0x19, 0x20, 0x20, 0x18, 0x18, 0x18, 0x18, 0x40, 0x40, 0x18, 0x18, 0x2F, 0x2F, 0x31, 0x31, 0x2F, 0x2F, 0x31, 0x31, 0x18, 0x18, 0x41, 0x41, 0x41, 0x41,
0x39, 0x00, 0x40, 0xE1, 0x11, 0x00, 0x00, 0x89, 0x30, 0x80, 0x0A, 0x00, 0x06, 0x40, 0x00, 0x28, 0x06, 0x40, 0x06, 0x40, 0x02, 0x00, 0x04, 0x21, 0x00, 0x20, 0x05, 0xD0, 0x00, 0x16, 0x00, 0x0C, 0x02, 0x77, 0x00, 0xDA, 0x18, 0x00, 0x10, 0xE0, 0x03, 0x0C, 0x20, 0x00, 0x06, 0x0B, 0x0B, 0x33, 0x0E, 0x1C, 0x2A, 0x38, 0x46, 0x54, 0x62, 0x69, 0x70, 0x77, 0x79, 0x7B, 0x7D, 0x7E, 0x01, 0x02, 0x01, 0x00, 0x09,
0x39, 0x00, 0x0C, 0xE7, 0x06, 0x14, 0x14, 0x1A, 0x23, 0x38, 0x00, 0x23, 0x5D, 0x02, 0x02,
0x39, 0x00, 0x02, 0xBD, 0x01,
0x39, 0x00, 0x04, 0xB1, 0x01, 0x23, 0x00,
0x39, 0x00, 0x25, 0xD8, 0x20, 0x00, 0x02, 0x22, 0x00, 0x00, 0x20, 0x00, 0x02, 0x22, 0x00, 0x00, 0x20, 0x00, 0x02, 0x22, 0x00, 0x00, 0x20, 0x00, 0x02, 0x22, 0x00, 0x00, 0x20, 0x00, 0x02, 0x22, 0x00, 0x00, 0x20, 0x00, 0x02, 0x22, 0x00, 0x00,
0x39, 0x00, 0x1A, 0xE1, 0x40, 0x09, 0xBE, 0x19, 0xFC, 0x19, 0xFA, 0x19, 0xF8, 0x1A, 0x38, 0x1A, 0x78, 0x1A, 0xB6, 0x2A, 0xF6, 0x2B, 0x34, 0x2B, 0x74, 0x3B, 0x74, 0x6B, 0xF4,
0x39, 0x00, 0x0D, 0xE7, 0x02, 0x00, 0x40, 0x01, 0x84, 0x13, 0xBE, 0x14, 0x48, 0x00, 0x04, 0x26,
0x39, 0x00, 0x08, 0xCB, 0x1F, 0x55, 0x03, 0x28, 0x0D, 0x08, 0x0A,
0x39, 0x00, 0x02, 0xBD, 0x02,
0x39, 0x00, 0x0D, 0xD8, 0xAF, 0xFF, 0xFA, 0xFA, 0xBF, 0xEA, 0xAF, 0xFF, 0xFA, 0xFA, 0xBF, 0xEA,
0x39, 0x00, 0x23, 0xE7, 0x01, 0x05, 0x01, 0x03, 0x01, 0x03, 0x04, 0x02, 0x02, 0x24, 0x00, 0x24, 0x81, 0x02, 0x40, 0x00, 0x29, 0x60, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x39, 0x00, 0x02, 0xBD, 0x03,
0x39, 0x00, 0x19, 0xD8, 0xAA, 0xAA, 0xAA, 0xAB, 0xBF, 0xEA, 0xAA, 0xAA, 0xAA, 0xAB, 0xBF, 0xEA, 0xAF, 0xFF, 0xFA, 0xFA, 0xBF, 0xEA, 0xAF, 0xFF, 0xFA, 0xFA, 0xBF, 0xEA,
0x39, 0x00, 0x03, 0xE1, 0x01, 0x3F,
0x39, 0x00, 0x02, 0xBD, 0x00,
0x39, 0x00, 0x2F, 0xE0, 0x00, 0x13, 0x30, 0x36, 0x40, 0x78, 0x8B, 0x94, 0x95, 0x97, 0x94, 0x94, 0x91, 0x8F, 0x8F, 0x8B, 0x8A, 0x8C, 0x8E, 0xA6, 0xB7, 0x4D, 0x7F, 0x00, 0x13, 0x30, 0x36, 0x40, 0x78, 0x8B, 0x94, 0x95, 0x97, 0x94, 0x94, 0x91, 0x8F, 0x8F, 0x8B, 0x8A, 0x8C, 0x8E, 0xA6, 0xB7, 0x4D, 0x7F,
0x39, 0x00, 0x05, 0xBA, 0x70, 0x03, 0xA8, 0x92,
0x39, 0x00, 0x25, 0xD8, 0xEA, 0xAA, 0xAA, 0xAE, 0xAA, 0xAF, 0xEA, 0xAA, 0xAA, 0xAE, 0xAA, 0xAF, 0xE0, 0x00, 0x0A, 0x2E, 0x80, 0x2F, 0xE0, 0x00, 0x0A, 0x2E, 0x80, 0x2F, 0xE0, 0x00, 0x0A, 0x2E, 0x80, 0x2F, 0xE0, 0x00, 0x0A, 0x2E, 0x80, 0x2F,
0x39, 0x00, 0x02, 0xBD, 0x00,
0x39, 0x00, 0x02, 0xC1, 0x01,
0x39, 0x00, 0x02, 0xBD, 0x01,
0x39, 0x00, 0x3B, 0xC1, 0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x18, 0x1C, 0x1F, 0x23, 0x27, 0x2B, 0x2F, 0x33, 0x37, 0x3B, 0x3F, 0x43, 0x47, 0x4B, 0x52, 0x5A, 0x62, 0x69, 0x71, 0x79, 0x81, 0x89, 0x91, 0x98, 0xA1, 0xA9, 0xB1, 0xB9, 0xC1, 0xCA, 0xD2, 0xDA, 0xE3, 0xEA, 0xF4, 0xF8, 0xF9, 0xFB, 0xFD, 0xFF, 0x16, 0xA4, 0x44, 0x16, 0x90, 0xE7, 0xF9, 0x71, 0xA0, 0xF3, 0x1F, 0x40,
0x39, 0x00, 0x02, 0xBD, 0x02,
0x39, 0x00, 0x3B, 0xC1, 0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x18, 0x1C, 0x20, 0x24, 0x28, 0x2D, 0x31, 0x35, 0x39, 0x3D, 0x41, 0x45, 0x49, 0x4D, 0x55, 0x5D, 0x65, 0x6D, 0x75, 0x7D, 0x85, 0x8D, 0x94, 0x9C, 0xA4, 0xAC, 0xB4, 0xBC, 0xC4, 0xCC, 0xD4, 0xDC, 0xE4, 0xEC, 0xF4, 0xF8, 0xFA, 0xFC, 0xFE, 0xFF, 0x06, 0xAA, 0xFC, 0x5B, 0xFF, 0xFF, 0xA4, 0xF9, 0x86, 0xF9, 0x55, 0x40,
0x39, 0x00, 0x02, 0xBD, 0x03,
0x39, 0x00, 0x3B, 0xC1, 0x00, 0x04, 0x07, 0x0B, 0x0F, 0x13, 0x17, 0x1B, 0x1F, 0x23, 0x27, 0x2C, 0x30, 0x33, 0x38, 0x3C, 0x40, 0x44, 0x48, 0x4C, 0x53, 0x5B, 0x63, 0x6B, 0x72, 0x7A, 0x82, 0x89, 0x91, 0x99, 0xA1, 0xA9, 0xB1, 0xB9, 0xC1, 0xC9, 0xD1, 0xDA, 0xE2, 0xEA, 0xF3, 0xF6, 0xF9, 0xFA, 0xFE, 0xFF, 0x0F, 0x9A, 0xFC, 0x31, 0x40, 0xE4, 0xFB, 0xE9, 0xA3, 0xD9, 0x77, 0x00,
0x39, 0x00, 0x02, 0xBD, 0x02,
0x39, 0x00, 0x02, 0xBF, 0x72,
0x39, 0x00, 0x02, 0xBD, 0x00,
0x39, 0x00, 0x08, 0xBF, 0xFD, 0x00, 0x80, 0x9C, 0x10, 0x00, 0x80,
0x39, 0x00, 0x02, 0xE9, 0xDE,
0x39, 0x00, 0x04, 0xB1, 0xCC, 0x03, 0x00,
0x39, 0x00, 0x02, 0xE9, 0x3F,
0x39, 0x00, 0x07, 0xD0, 0x07, 0xC0, 0x08, 0x03, 0x11, 0x00,
0x39, 0x00, 0x03, 0xB0, 0x00, 0x00,
0x39, 0x00, 0x02, 0xE9, 0xCF,
0x39, 0x00, 0x02, 0xBA, 0x03,
0x39, 0x00, 0x02, 0xE9, 0x3F,
// 0x39, 0x00, 0x04, 0xB9, 0x83, 0x12, 0x1A,
// 0x39, 0x00, 0x02, 0xC7, 0x00,
// 0x39, 0x00, 0x02, 0xCF, 0xFF,
0x39, 0x00, 0x01, 0x11,
0x39, 0x00, 0x01, 0x29,
};
EFI_STATUS
EFIAPI
CsotDsiPanelPrepare (
IN ROCKCHIP_DSI_PANEL_PROTOCOL *This
)
{
/* vcc_lcd_en_pin */
GpioPinWrite (4, GPIO_PIN_PA3, TRUE);
GpioPinSetDirection (4, GPIO_PIN_PA3, GPIO_PIN_OUTPUT);
MicroSecondDelay (5 * 1000);
/* avdd_lcd_gpio */
GpioPinWrite (3, GPIO_PIN_PA7, TRUE);
GpioPinSetDirection (3, GPIO_PIN_PA7, GPIO_PIN_OUTPUT);
MicroSecondDelay (5 * 1000);
/* avee_lcd_gpio */
GpioPinWrite (3, GPIO_PIN_PA6, TRUE);
GpioPinSetDirection (3, GPIO_PIN_PA6, GPIO_PIN_OUTPUT);
MicroSecondDelay (5 * 1000);
MicroSecondDelay (120 * 1000);
/* lcd_rst_gpio (inverted) */
GpioPinWrite (3, GPIO_PIN_PC6, FALSE);
GpioPinSetDirection (3, GPIO_PIN_PC6, GPIO_PIN_OUTPUT);
MicroSecondDelay (120 * 1000);
/* lcd_rst_gpio (inverted) */
GpioPinWrite (3, GPIO_PIN_PC6, TRUE);
MicroSecondDelay (120 * 1000);
return EFI_SUCCESS;
}
STATIC ROCKCHIP_DSI_PANEL_PROTOCOL mCsotDsiPanel = {
.DsiId = 0,
.DsiLaneRate = 676000,
.DsiLanes = 4,
.DsiFlags = MIPI_DSI_MODE_VIDEO |
MIPI_DSI_MODE_VIDEO_BURST |
MIPI_DSI_MODE_LPM |
MIPI_DSI_MODE_EOT_PACKET,
.DsiFormat = MIPI_DSI_FMT_RGB888,
.DscEnable = TRUE,
.SliceWidth = 1600,
.SliceHeight = 40,
.VersionMajor = 1,
.VersionMinor = 1,
.InitSequence = mCsotDsiInitSequence,
.InitSequenceLength = ARRAY_SIZE (mCsotDsiInitSequence),
.NativeMode = {
.CrtcId = 2,
.OscFreq = 275000000,
.Horizontal = {
.Resolution = 1600,
.Sync = 20,
.BackPorch = 40,
.FrontPorch = 60
},
.Vertical = {
.Resolution = 2560,
.Sync = 4,
.BackPorch = 18,
.FrontPorch = 112
},
.HsyncActive = 0,
.VsyncActive = 0,
.DenActive = 0,
.ClkActive = 0,
.VpsConfigModeID = 1
},
.Prepare = CsotDsiPanelPrepare,
};
EFI_STATUS
EFIAPI
AttachCsotDsiPanel (
VOID
)
{
EFI_HANDLE Handle = NULL;
return gBS->InstallMultipleProtocolInterfaces (
&Handle,
&gRockchipDsiPanelProtocolGuid,
&mCsotDsiPanel,
NULL
);
}

View File

@@ -0,0 +1,306 @@
/** @file
*
* Copyright (c) 2021, Rockchip Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*
**/
#include <Base.h>
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/GpioLib.h>
#include <Library/RK806.h>
#include <Library/Rk3588Pcie.h>
#include <Library/PWMLib.h>
#include <Soc.h>
static struct regulator_init_data rk806_init_data[] = {
/* Master PMIC */
RK8XX_VOLTAGE_INIT(MASTER_BUCK1, 750000),
RK8XX_VOLTAGE_INIT(MASTER_BUCK3, 750000),
RK8XX_VOLTAGE_INIT(MASTER_BUCK4, 750000),
RK8XX_VOLTAGE_INIT(MASTER_BUCK5, 850000),
// RK8XX_VOLTAGE_INIT(MASTER_BUCK6, 750000),
RK8XX_VOLTAGE_INIT(MASTER_BUCK7, 2000000),
RK8XX_VOLTAGE_INIT(MASTER_BUCK8, 3300000),
RK8XX_VOLTAGE_INIT(MASTER_BUCK10, 1800000),
RK8XX_VOLTAGE_INIT(MASTER_NLDO1, 750000),
RK8XX_VOLTAGE_INIT(MASTER_NLDO2, 850000),
RK8XX_VOLTAGE_INIT(MASTER_NLDO3, 750000),
RK8XX_VOLTAGE_INIT(MASTER_NLDO4, 850000),
RK8XX_VOLTAGE_INIT(MASTER_NLDO5, 750000),
RK8XX_VOLTAGE_INIT(MASTER_PLDO1, 1800000),
RK8XX_VOLTAGE_INIT(MASTER_PLDO2, 1800000),
RK8XX_VOLTAGE_INIT(MASTER_PLDO3, 1200000),
RK8XX_VOLTAGE_INIT(MASTER_PLDO4, 3300000),
RK8XX_VOLTAGE_INIT(MASTER_PLDO5, 3300000),
RK8XX_VOLTAGE_INIT(MASTER_PLDO6, 1800000),
/* No dual PMICs on this platform */
};
VOID
EFIAPI
SdmmcIoMux (
VOID
)
{
/* sdmmc0 iomux (microSD socket) */
BUS_IOC->GPIO4D_IOMUX_SEL_L = (0xFFFFUL << 16) | (0x1111); //SDMMC_D0,SDMMC_D1,SDMMC_D2,SDMMC_D3
BUS_IOC->GPIO4D_IOMUX_SEL_H = (0x00FFUL << 16) | (0x0011); //SDMMC_CLK,SDMMC_CMD
PMU1_IOC->GPIO0A_IOMUX_SEL_H = (0x000FUL << 16) | (0x0001); //SDMMC_DET
}
VOID
EFIAPI
SdhciEmmcIoMux (
VOID
)
{
/* sdmmc0 iomux */
/* Do not override, set by earlier boot stages. */
}
#define NS_CRU_BASE 0xFD7C0000
#define CRU_CLKSEL_CON59 0x03EC
#define CRU_CLKSEL_CON78 0x0438
VOID
EFIAPI
Rk806SpiIomux (
VOID
)
{
/* io mux */
//BUS_IOC->GPIO1A_IOMUX_SEL_H = (0xFFFFUL << 16) | 0x8888;
//BUS_IOC->GPIO1B_IOMUX_SEL_L = (0x000FUL << 16) | 0x0008;
PMU1_IOC->GPIO0A_IOMUX_SEL_H = (0x0FF0UL << 16) | 0x0110;
PMU1_IOC->GPIO0B_IOMUX_SEL_L = (0xF0FFUL << 16) | 0x1011;
MmioWrite32(NS_CRU_BASE + CRU_CLKSEL_CON59, (0x00C0UL << 16) | 0x0080);
}
VOID
EFIAPI
Rk806Configure (
VOID
)
{
UINTN RegCfgIndex;
RK806Init();
for (RegCfgIndex = 0; RegCfgIndex < ARRAY_SIZE(rk806_init_data); RegCfgIndex++)
RK806RegulatorInit(rk806_init_data[RegCfgIndex]);
}
VOID
EFIAPI
SetCPULittleVoltage (
IN UINT32 Microvolts
)
{
struct regulator_init_data Rk806CpuLittleSupply =
RK8XX_VOLTAGE_INIT(MASTER_BUCK2, Microvolts);
RK806RegulatorInit(Rk806CpuLittleSupply);
}
VOID
EFIAPI
NorFspiIomux (
VOID
)
{
/* io mux */
/* Do not override, set by earlier boot stages. */
}
VOID
EFIAPI
GmacIomux (
IN UINT32 Id
)
{
/* No GMAC here */
}
VOID
EFIAPI
NorFspiEnableClock (
UINT32 *CruBase
)
{
UINTN BaseAddr = (UINTN) CruBase;
MmioWrite32(BaseAddr + 0x087C, 0x0E000000);
}
VOID
EFIAPI
I2cIomux (
UINT32 id
)
{
switch (id) {
case 0:
GpioPinSetFunction(0, GPIO_PIN_PD1, 3); //i2c0_scl_m2
GpioPinSetFunction(0, GPIO_PIN_PD2, 3); //i2c0_sda_m2
break;
case 1:
break;
case 2:
GpioPinSetFunction(0, GPIO_PIN_PB7, 9); //i2c2_scl_m0
GpioPinSetFunction(0, GPIO_PIN_PC0, 9); //i2c2_sda_m0
break;
case 3:
GpioPinSetFunction(3, GPIO_PIN_PB7, 9); //i2c3_scl_m1
GpioPinSetFunction(3, GPIO_PIN_PC0, 9); //i2c3_sda_m1
break;
case 4:
GpioPinSetFunction(1, GPIO_PIN_PA3, 9); //i2c4_scl_m3
GpioPinSetFunction(1, GPIO_PIN_PA2, 9); //i2c4_sda_m3
break;
case 5:
GpioPinSetFunction(1, GPIO_PIN_PB6, 9); //i2c5_scl_m3
GpioPinSetFunction(1, GPIO_PIN_PB7, 9); //i2c5_sda_m3
break;
case 6:
GpioPinSetFunction(4, GPIO_PIN_PB1, 9); //i2c6_scl_m3
GpioPinSetFunction(4, GPIO_PIN_PB0, 9); //i2c6_sda_m3
break;
case 7:
GpioPinSetFunction(1, GPIO_PIN_PD0, 9); //i2c7_scl_m0
GpioPinSetFunction(1, GPIO_PIN_PD1, 9); //i2c7_sda_m0
break;
default:
break;
}
}
VOID
EFIAPI
UsbPortPowerEnable (
VOID
)
{
}
VOID
EFIAPI
Usb2PhyResume (
VOID
)
{
MmioWrite32(0xfd5d0008, 0x20000000);
MmioWrite32(0xfd5d4008, 0x20000000);
MmioWrite32(0xfd5d8008, 0x20000000);
MmioWrite32(0xfd5dc008, 0x20000000);
MmioWrite32(0xfd7f0a10, 0x07000700);
MmioWrite32(0xfd7f0a10, 0x07000000);
}
VOID
EFIAPI
PcieIoInit (
UINT32 Segment
)
{
/* Set reset to gpio output mode */
if(Segment == PCIE_SEGMENT_PCIE20L2) { // AP6275P Wi-Fi
GpioPinSetDirection (3, GPIO_PIN_PD1, GPIO_PIN_OUTPUT);
/* wifi_poweren_gpio */
GpioPinSetDirection (0, GPIO_PIN_PC7, GPIO_PIN_OUTPUT);
}
}
VOID
EFIAPI
PciePowerEn (
UINT32 Segment,
BOOLEAN Enable
)
{
if(Segment == PCIE_SEGMENT_PCIE20L2) {
/* wifi_poweren_gpio */
GpioPinWrite (0, GPIO_PIN_PC7, Enable);
}
}
VOID
EFIAPI
PciePeReset (
UINT32 Segment,
BOOLEAN Enable
)
{
if(Segment == PCIE_SEGMENT_PCIE20L2) {
GpioPinWrite (3, GPIO_PIN_PD1, !Enable);
}
}
VOID
EFIAPI
PwmFanIoSetup (
VOID
)
{
}
VOID
EFIAPI
PwmFanSetSpeed (
IN UINT32 Percentage
)
{
}
VOID
EFIAPI
PlatformInitLeds (
VOID
)
{
GpioPinWrite (3, GPIO_PIN_PC2, FALSE);
GpioPinSetDirection (3, GPIO_PIN_PC2, GPIO_PIN_OUTPUT);
}
VOID
EFIAPI
PlatformSetStatusLed (
IN BOOLEAN Enable
)
{
GpioPinWrite (3, GPIO_PIN_PC2, Enable);
}
extern
EFI_STATUS
EFIAPI
AttachCsotDsiPanel (
VOID
);
VOID
EFIAPI
PlatformEarlyInit (
VOID
)
{
/* vcc_5v0_en */
GpioPinWrite (4, GPIO_PIN_PA2, TRUE);
GpioPinSetDirection (4, GPIO_PIN_PA2, GPIO_PIN_OUTPUT);
GpioPinSetFunction(1, GPIO_PIN_PC0, 0); //jdet
/* spk-con-gpio */
GpioPinWrite (4, GPIO_PIN_PA5, TRUE);
GpioPinSetDirection (4, GPIO_PIN_PA5, GPIO_PIN_OUTPUT);
AttachCsotDsiPanel();
}

View File

@@ -0,0 +1,41 @@
#
# Copyright (c) 2021, Rockchip Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
[Defines]
INF_VERSION = 0x00010019
BASE_NAME = RockchipPlatformLib
FILE_GUID = 5178fa86-2fec-11ec-95b4-f42a7dcb925d
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = RockchipPlatformLib
RKPLATLIB_COMMON_DIR = Silicon/Rockchip/RK3588/Library/RockchipPlatformLibCommon
[Packages]
EmbeddedPkg/EmbeddedPkg.dec
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
Silicon/Rockchip/RK3588/RK3588.dec
Silicon/Rockchip/RockchipPkg.dec
[LibraryClasses]
ArmLib
HobLib
IoLib
MemoryAllocationLib
SerialPortLib
CruLib
GpioLib
PWMLib
TimerLib
UefiBootServicesTableLib
[Protocols]
gRockchipDsiPanelProtocolGuid
[Sources.common]
RockchipPlatformLib.c
CsotDsiPanel.c
$(RKPLATLIB_COMMON_DIR)/RK3588CruLib.c

View File

@@ -10,6 +10,7 @@
**/
#include <PiDxe.h>
#include <Protocol/RockchipDsiPanel.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DevicePathLib.h>
#include <Library/UefiBootServicesTableLib.h>
@@ -53,25 +54,6 @@ STATIC OVER_SCAN mDefaultOverScanParas = {
.BottomMargin = 100
};
typedef struct {
UINT32 Resolution;
UINT32 Sync;
UINT32 BackPorch;
UINT32 FrontPorch;
} SCAN_TIMINGS;
typedef struct {
UINT32 CrtcId;
UINT32 OscFreq;
SCAN_TIMINGS Horizontal;
SCAN_TIMINGS Vertical;
UINT32 HsyncActive;
UINT32 VsyncActive;
UINT32 DenActive;
UINT32 ClkActive;
UINT32 VpsConfigModeID;
} DISPLAY_MODE;
STATIC DISPLAY_MODE mDisplayModes[] = {
{
2,
@@ -331,21 +313,11 @@ LcdGraphicsOutputInit (
// logic to let users choose the primary display through a setup option.
//
HorizontalResolution = PcdGet32 (PcdVideoHorizontalResolution);
VerticalResolution = PcdGet32 (PcdVideoVerticalResolution);
for (ModeIndex = 0; ModeIndex < mMaxMode; ModeIndex++) {
Mode = &mDisplayModes[ModeIndex];
if (Mode->Horizontal.Resolution == HorizontalResolution && Mode->Vertical.Resolution == VerticalResolution) {
break;
}
}
if (ModeIndex >= mMaxMode) {
DEBUG ((DEBUG_ERROR, "%a: %dx%d mode not supported.\n",
__func__, HorizontalResolution, VerticalResolution));
return EFI_UNSUPPORTED;
}
//
// Assume mode #0 is the highest supported mode for now.
//
ModeIndex = 0;
Mode = &mDisplayModes[ModeIndex];
InitializeListHead (&mDisplayStateList);
@@ -353,13 +325,6 @@ LcdGraphicsOutputInit (
DisplayState = AllocateZeroPool (sizeof(DISPLAY_STATE));
InitializeListHead (&DisplayState->ListHead);
/* adapt to UEFI architecture */
DisplayState->ModeNumber = ModeIndex;
DisplayState->VpsConfigModeID = Mode->VpsConfigModeID;
DisplayState->CrtcState.Crtc = (VOID *) Crtc;
DisplayState->CrtcState.CrtcID = Mode->CrtcId;
Status = gBS->HandleProtocol (ConnectorHandles[Index],
&gRockchipConnectorProtocolGuid,
(VOID **) &DisplayState->ConnectorState.Connector);
@@ -369,6 +334,27 @@ LcdGraphicsOutputInit (
return Status;
}
//
// DSI panel has a hardcoded mode. Overwrite the current one.
// This is all pretty ugly and prevents using multiple displays,
// but whatever...
//
ROCKCHIP_DSI_PANEL_PROTOCOL *DsiPanel;
Status = gBS->HandleProtocol (ConnectorHandles[Index],
&gRockchipDsiPanelProtocolGuid,
(VOID **) &DsiPanel);
if (!EFI_ERROR (Status)) {
CopyMem (Mode, &DsiPanel->NativeMode, sizeof (*Mode));
}
/* adapt to UEFI architecture */
DisplayState->ModeNumber = ModeIndex;
DisplayState->VpsConfigModeID = Mode->VpsConfigModeID;
DisplayState->CrtcState.Crtc = (VOID *) Crtc;
DisplayState->CrtcState.CrtcID = Mode->CrtcId;
DisplayState->ConnectorState.OverScan.LeftMargin = mDefaultOverScanParas.LeftMargin;
DisplayState->ConnectorState.OverScan.RightMargin = mDefaultOverScanParas.RightMargin;
DisplayState->ConnectorState.OverScan.TopMargin = mDefaultOverScanParas.TopMargin;

View File

@@ -47,14 +47,13 @@
gEfiGraphicsOutputProtocolGuid
gRockchipCrtcProtocolGuid
gRockchipConnectorProtocolGuid
gRockchipDsiPanelProtocolGuid
[Guids]
gEfiEndOfDxeEventGroupGuid
[Pcd]
gRockchipTokenSpaceGuid.PcdLcdPixelFormat
gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution
gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution
[FeaturePcd]
gArmPlatformTokenSpaceGuid.PcdGopDisableOnExitBootServices

View File

@@ -127,7 +127,11 @@ RkSdmmcCardDetect (
return TRUE; // let the driver do software detection
}
return PresenceState == RkSdmmcCardPresent;
if (FixedPcdGetBool (PcdRkSdmmcCardDetectInverted)) {
return PresenceState != RkSdmmcCardPresent;
} else {
return PresenceState == RkSdmmcCardPresent;
}
}
STATIC PLATFORM_DW_MMC_PROTOCOL mDwMmcDeviceProtocol = {

View File

@@ -43,6 +43,7 @@
[Pcd]
gRockchipTokenSpaceGuid.PcdRkSdmmcBaseAddress
gRockchipTokenSpaceGuid.PcdRkSdmmcCardDetectInverted
[Depex]
TRUE

View File

@@ -215,30 +215,27 @@ static VOP2_POWER_DOMAIN_DATA mCluster0PdDataRK3588 = {
};
static VOP2_POWER_DOMAIN_DATA mCluster1PdDataRK3588 = {
.IsParentNeeded = TRUE,
.PdEnShift = RK3588_CLUSTER1_PD_EN_SHIFT,
.PdStatusShift = RK3588_CLUSTER1_PD_STATUS_SHIFT,
.PmuStatusShift = RK3588_PD_CLUSTER1_PWR_STAT_SHIFI,
.BisrEnStatusShift = RK3588_PD_CLUSTER1_REPAIR_EN_SHIFT,
.ParentPhyID = ROCKCHIP_VOP2_CLUSTER0,
.ParentPdData = &mCluster0PdDataRK3588,
};
static VOP2_POWER_DOMAIN_DATA mCluster2PdDataRK3588 = {
.IsParentNeeded = TRUE,
.PdEnShift = RK3588_CLUSTER2_PD_EN_SHIFT,
.PdStatusShift = RK3588_CLUSTER2_PD_STATUS_SHIFT,
.PmuStatusShift = RK3588_PD_CLUSTER2_PWR_STAT_SHIFI,
.BisrEnStatusShift = RK3588_PD_CLUSTER2_REPAIR_EN_SHIFT,
.ParentPhyID = ROCKCHIP_VOP2_CLUSTER0,
.ParentPdData = &mCluster0PdDataRK3588,
};
static VOP2_POWER_DOMAIN_DATA mCluster3PdDataRK3588 = {
.IsParentNeeded = TRUE,
.PdEnShift = RK3588_CLUSTER3_PD_EN_SHIFT,
.PdStatusShift = RK3588_CLUSTER3_PD_STATUS_SHIFT,
.PmuStatusShift = RK3588_PD_CLUSTER3_PWR_STAT_SHIFI,
.BisrEnStatusShift = RK3588_PD_CLUSTER3_REPAIR_EN_SHIFT,
.ParentPhyID = ROCKCHIP_VOP2_CLUSTER0,
.ParentPdData = &mCluster0PdDataRK3588,
};
static VOP2_POWER_DOMAIN_DATA mEsmartPdDataRK3588 = {
@@ -248,6 +245,20 @@ static VOP2_POWER_DOMAIN_DATA mEsmartPdDataRK3588 = {
.BisrEnStatusShift = RK3588_PD_ESMART_REPAIR_EN_SHIFT,
};
static VOP2_POWER_DOMAIN_DATA mDsc8KPdDataRK3588 = {
.PdEnShift = RK3588_DSC_8K_PD_EN_SHIFT,
.PdStatusShift = RK3588_DSC_8K_PD_STATUS_SHIFT,
.PmuStatusShift = RK3588_PD_DSC_8K_PWR_STAT_SHIFI,
.BisrEnStatusShift = RK3588_PD_DSC_8K_REPAIR_EN_SHIFT,
};
static VOP2_POWER_DOMAIN_DATA mDsc4KPdDataRK3588 = {
.PdEnShift = RK3588_DSC_4K_PD_EN_SHIFT,
.PdStatusShift = RK3588_DSC_4K_PD_STATUS_SHIFT,
.PmuStatusShift = RK3588_PD_DSC_4K_PWR_STAT_SHIFI,
.BisrEnStatusShift = RK3588_PD_DSC_4K_REPAIR_EN_SHIFT,
};
static VOP2_WIN_DATA mWinDataRK3588[8] = {
{
.Name = "Cluster0",
@@ -330,12 +341,38 @@ static VOP2_WIN_DATA mWinDataRK3588[8] = {
},
};
STATIC VOP2_DSC_DATA mDscDataRK3588[] = {
{
.id = ROCKCHIP_VOP2_DSC_8K,
.PdData = &mDsc8KPdDataRK3588,
.max_slice_num = 8,
.max_linebuf_depth = 11,
.min_bits_per_pixel = 8,
.dsc_txp_clk_src_name = "dsc_8k_txp_clk_src",
.dsc_txp_clk_name = "dsc_8k_txp_clk",
.dsc_pxl_clk_name = "dsc_8k_pxl_clk",
.dsc_cds_clk_name = "dsc_8k_cds_clk",
},
{
.id = ROCKCHIP_VOP2_DSC_4K,
.PdData = &mDsc4KPdDataRK3588,
.max_slice_num = 2,
.max_linebuf_depth = 11,
.min_bits_per_pixel = 8,
.dsc_txp_clk_src_name = "dsc_4k_txp_clk_src",
.dsc_txp_clk_name = "dsc_4k_txp_clk",
.dsc_pxl_clk_name = "dsc_4k_pxl_clk",
.dsc_cds_clk_name = "dsc_4k_cds_clk",
},
};
STATIC VOP2_DATA mVop2RK3588 = {
.Version = VOP_VERSION_RK3588,
.NrVps = 4,
.VpData = mVpDataRK3588,
.WinData = mWinDataRK3588,
.DscData = mDscDataRK3588,
/*
.plane_table = rk3588_plane_table,
*/
@@ -454,6 +491,18 @@ Vop2GrfWrite (
MmioWrite32(Address + Offset, TempVal);
}
INLINE
UINT32
Vop2GrfRead (
IN UINTN Address,
IN UINT32 Offset,
IN UINT32 Mask,
IN UINT32 Shift
)
{
return (MmioRead32(Address + Offset) >> Shift) & Mask;
}
INLINE
UINT32 GenericHWeight32 (
IN UINT32 W
@@ -953,6 +1002,33 @@ Vop2CalcCruConfig (
}
*DclkOutDiv = DclkRate / DclkOutRate;
*DclkCoreDiv = DclkRate / DclkCoreRate;
} else if (OutputType == DRM_MODE_CONNECTOR_DSI) {
if (ConnectorState->OutputFlags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
K = 2;
if (CrtcState->dsc_enable)
/* dsc output is 96bit, dsi input is 192 bit */
IfPixclkRate = CrtcState->dsc_cds_clk_rate >> 1;
else
IfPixclkRate = DclkCoreRate / K;
/* dclk_core = dclk_out * K = if_pixclk * K = VPixclk / 4 */
DclkOutRate = DclkCoreRate / K;
/* DclkRate = N * DclkCoreRate N = (1,2,4 ), we get a little factor here */
DclkRate = Vop2CalcDclk(DclkOutRate,
Vop2->Data->VpData->MaxDclk);
if (!DclkRate) {
DEBUG ((DEBUG_INFO, "MIPI dclk out of range(max_dclk: %d KHZ, DclkRate: %ld KHZ)\n",
Vop2->Data->VpData->MaxDclk, DclkRate));
return -EINVAL;
}
if (CrtcState->dsc_enable)
DclkRate /= CrtcState->dsc_slice_num;
*DclkOutDiv = DclkRate / DclkOutRate;
*DclkCoreDiv = DclkRate / DclkCoreRate;
*IfPixclkDiv = 1; /*mipi pixclk == dclk_out*/
if (CrtcState->dsc_enable)
*IfPixclkDiv = DclkOutRate * 1000LL / IfPixclkRate;
}
*IfPixclkDiv = LogCalculate(*IfPixclkDiv);
@@ -968,6 +1044,39 @@ Vop2CalcCruConfig (
return DclkRate;
}
STATIC
EFI_STATUS
Vop2CalcDscClk (
OUT DISPLAY_STATE *DisplayState
)
{
CRTC_STATE *CrtcState = &DisplayState->CrtcState;
CONNECTOR_STATE *ConnectorState = &DisplayState->ConnectorState;
DRM_DISPLAY_MODE *DisplayMode = &ConnectorState->DisplayMode;
UINT64 VPixclk = DisplayMode->CrtcClock * 1000LL; /* video timing pixclk */
UINT8 K = 1;
if (ConnectorState->OutputFlags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
K = 2;
CrtcState->dsc_txp_clk_rate = VPixclk;
do_div(CrtcState->dsc_txp_clk_rate, (CrtcState->dsc_pixel_num * K));
CrtcState->dsc_pxl_clk_rate = VPixclk;
do_div(CrtcState->dsc_pxl_clk_rate, (CrtcState->dsc_slice_num * K));
/* dsc_cds = crtc_clock / (cds_dat_width / bits_per_pixel)
* cds_dat_width = 96;
* bits_per_pixel = [8-12];
* As cds clk is div from txp clk and only support 1/2/4 div,
* so when txp_clk is equal to VPixclk, we set dsc_cds = crtc_clock / 4,
* otherwise dsc_cds = crtc_clock / 8;
*/
CrtcState->dsc_cds_clk_rate = VPixclk / (CrtcState->dsc_txp_clk_rate == VPixclk ? 4 : 8);
return 0;
}
STATIC
UINT32
Vop2IfConfig (
@@ -978,6 +1087,7 @@ Vop2IfConfig (
CRTC_STATE *CrtcState = &DisplayState->CrtcState;
CONNECTOR_STATE *ConnectorState = &DisplayState->ConnectorState;
DRM_DISPLAY_MODE *DisplayMode = &ConnectorState->DisplayMode;
struct rockchip_dsc_sink_cap *dsc_sink_cap = &CrtcState->dsc_sink_cap;
UINT32 VPOffset = CrtcState->CrtcID * 0x100;
UINT32 OutputIf = ConnectorState->OutputInterface;
UINT32 DclkCoreDiv = 0;
@@ -995,7 +1105,80 @@ Vop2IfConfig (
Val |= (DisplayMode->Flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE);
}
if (CrtcState->dsc_enable) {
UINT32 K = 1;
if (!Vop2->Data->NrDscs) {
DEBUG ((DEBUG_ERROR, "Unsupported DSC\n"));
return 0;
}
if (ConnectorState->OutputFlags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
K = 2;
CrtcState->dsc_id = OutputIf & (VOP_OUTPUT_IF_MIPI0 | VOP_OUTPUT_IF_HDMI0) ? 0 : 1;
CrtcState->dsc_slice_num = DisplayMode->CrtcHDisplay / dsc_sink_cap->slice_width / K;
CrtcState->dsc_pixel_num = CrtcState->dsc_slice_num > 4 ? 4 : CrtcState->dsc_slice_num;
Vop2CalcDscClk(DisplayState);
DEBUG ((DEBUG_INFO, "Enable DSC%d slice:%dx%d, slice num:%d\n",
CrtcState->dsc_id, dsc_sink_cap->slice_width,
dsc_sink_cap->slice_height, CrtcState->dsc_slice_num));
}
DclkRate = Vop2CalcCruConfig(DisplayState, &DclkCoreDiv, &DclkOutDiv, &IfPixclkDiv, &IfDclkDiv);
CrtcState->DclkCoreDiv = DclkCoreDiv;
CrtcState->DclkOutDiv = DclkOutDiv;
if (OutputIf & VOP_OUTPUT_IF_MIPI0) {
if (CrtcState->CrtcID == 2)
Val = 0;
else
Val = 1;
if (ConnectorState->OutputFlags & ROCKCHIP_OUTPUT_MIPI_DS_MODE)
Vop2MaskWrite (Vop2->BaseAddress, RK3568_DSP_IF_CTRL, EN_MASK,
RK3588_MIPI_DSI0_MODE_SEL_SHIFT, 1, FALSE);
Vop2MaskWrite (Vop2->BaseAddress, RK3568_DSP_IF_EN, EN_MASK, RK3588_MIPI0_EN_SHIFT,
1, FALSE);
Vop2MaskWrite (Vop2->BaseAddress, RK3568_DSP_IF_EN, 1, RK3588_MIPI0_MUX_SHIFT, Val, FALSE);
Vop2MaskWrite (Vop2->BaseAddress, RK3568_DSP_IF_CTRL, 3, MIPI0_PIXCLK_DIV_SHIFT,
IfPixclkDiv, FALSE);
if (ConnectorState->hold_mode) {
Vop2MaskWrite (Vop2->BaseAddress, RK3568_VP0_MIPI_CTRL + VPOffset,
EN_MASK, EDPI_TE_EN, TRUE, FALSE);
Vop2MaskWrite (Vop2->BaseAddress, RK3568_VP0_MIPI_CTRL + VPOffset,
EN_MASK, EDPI_WMS_HOLD_EN, 1, FALSE);
}
}
if (OutputIf & VOP_OUTPUT_IF_MIPI1) {
if (CrtcState->CrtcID == 2)
Val = 0;
else if (CrtcState->CrtcID == 3)
Val = 1;
else
Val = 3; /*VP1*/
if (ConnectorState->OutputFlags & ROCKCHIP_OUTPUT_MIPI_DS_MODE)
Vop2MaskWrite (Vop2->BaseAddress, RK3568_DSP_IF_CTRL, EN_MASK,
RK3588_MIPI_DSI1_MODE_SEL_SHIFT, 1, FALSE);
Vop2MaskWrite (Vop2->BaseAddress, RK3568_DSP_IF_EN, EN_MASK, RK3588_MIPI1_EN_SHIFT,
1, FALSE);
Vop2MaskWrite (Vop2->BaseAddress, RK3568_DSP_IF_EN, IF_MUX_MASK, MIPI1_MUX_SHIFT,
Val, FALSE);
Vop2MaskWrite (Vop2->BaseAddress, RK3568_DSP_IF_CTRL, 3, MIPI1_PIXCLK_DIV_SHIFT,
IfPixclkDiv, FALSE);
if (ConnectorState->hold_mode) {
Vop2MaskWrite (Vop2->BaseAddress, RK3568_VP0_MIPI_CTRL + VPOffset,
EN_MASK, EDPI_TE_EN, TRUE, FALSE);
Vop2MaskWrite (Vop2->BaseAddress, RK3568_VP0_MIPI_CTRL + VPOffset,
EN_MASK, EDPI_WMS_HOLD_EN, 1, FALSE);
}
}
if (OutputIf & VOP_OUTPUT_IF_eDP0) {
Vop2MaskWrite (Vop2->BaseAddress, RK3568_DSP_IF_EN, EN_MASK,
@@ -1380,6 +1563,57 @@ Vop2PostConfig (
MmioWrite32 (0xfdd906e8, 0x34000000);
}
STATIC
INT32
Vop2WaitPowerDomainOn (
OUT VOP2 *Vop2,
OUT VOP2_POWER_DOMAIN_DATA *PdData
)
{
UINT32 Val = 0;
BOOLEAN IsBisrEn = FALSE;
IsBisrEn = Vop2GrfRead (Vop2->SysPmu, RK3588_PMU_BISR_CON3, EN_MASK, PdData->BisrEnStatusShift);
if (IsBisrEn) {
return readl_poll_timeout(Vop2->SysPmu + RK3588_PMU_BISR_STATUS5, Val,
((Val >> PdData->PmuStatusShift) & 0x1), 50 * 1000);
} else {
return readl_poll_timeout(Vop2->BaseAddress + RK3568_SYS_STATUS0, Val,
!((Val >> PdData->PdStatusShift) & 0x1), 50 * 1000);
}
}
STATIC
EFI_STATUS
Vop2PowerDomainOn (
OUT VOP2 *Vop2,
OUT VOP2_POWER_DOMAIN_DATA *PdData
)
{
INT32 Ret = 0;
if (!PdData)
return 0;
if (PdData->ParentPdData) {
Ret = Vop2PowerDomainOn (Vop2, PdData->ParentPdData);
if (Ret) {
DEBUG ((DEBUG_ERROR, "can't open parent power domain\n"));
return EFI_INVALID_PARAMETER;
}
}
Vop2MaskWrite (Vop2->BaseAddress, RK3568_SYS_PD_CTRL, EN_MASK,
PdData->PdEnShift, 0, FALSE);
Ret = Vop2WaitPowerDomainOn(Vop2, PdData);
if (Ret) {
DEBUG ((DEBUG_ERROR, "wait vop2 power domain timeout\n"));
return EFI_TIMEOUT;
}
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
Vop2SetClk (
@@ -1431,6 +1665,7 @@ Vop2PreInit (
if (!RockchipVop2) {
RockchipVop2 = AllocatePool (sizeof(*RockchipVop2));
RockchipVop2->BaseAddress = RK3588_VOP2_REG_BASE;
RockchipVop2->SysPmu = SYS_PMU_BASE;
RockchipVop2->Version = mVop2RK3588.Version;
RockchipVop2->Data = &mVop2RK3588;
RockchipVop2->GlobalInit = FALSE;
@@ -1476,6 +1711,250 @@ Vop2PostColorSwap (
DATA_SWAP_SHIFT, DateSwap, FALSE);
}
STATIC
VOID
Vop2CalcDscCruCfg (
OUT DISPLAY_STATE *DisplayState,
OUT UINT32 *dsc_txp_clk_div,
OUT UINT32 *dsc_pxl_clk_div,
OUT UINT32 *dsc_cds_clk_div,
IN UINT64 dclk_rate
)
{
CRTC_STATE *CrtcState = &DisplayState->CrtcState;
*dsc_txp_clk_div = dclk_rate / CrtcState->dsc_txp_clk_rate;
*dsc_pxl_clk_div = dclk_rate / CrtcState->dsc_pxl_clk_rate;
*dsc_cds_clk_div = dclk_rate / CrtcState->dsc_cds_clk_rate;
*dsc_txp_clk_div = LogCalculate(*dsc_txp_clk_div);
*dsc_pxl_clk_div = LogCalculate(*dsc_pxl_clk_div);
*dsc_cds_clk_div = LogCalculate(*dsc_cds_clk_div);
}
STATIC
VOID
Vop2LoadPps (
OUT DISPLAY_STATE *DisplayState,
OUT VOP2 *Vop2,
IN UINT8 dsc_id
)
{
CRTC_STATE *CrtcState = &DisplayState->CrtcState;
struct drm_dsc_picture_parameter_set *pps = &CrtcState->pps;
struct drm_dsc_picture_parameter_set config_pps;
const VOP2_DSC_DATA *dsc_data = &Vop2->Data->DscData[dsc_id];
UINT32 *pps_val = (UINT32 *)&config_pps;
UINT32 decoder_regs_offset = (dsc_id * 0x100);
UINT32 i = 0;
memcpy(&config_pps, pps, sizeof(config_pps));
if ((config_pps.pps_3 & 0xf) > dsc_data->max_linebuf_depth) {
config_pps.pps_3 &= 0xf0;
config_pps.pps_3 |= dsc_data->max_linebuf_depth;
DEBUG((DEBUG_INFO, "DSC%d max_linebuf_depth is: %d, current set value is: %d\n",
dsc_id, dsc_data->max_linebuf_depth, config_pps.pps_3 & 0xf));
}
for (i = 0; i < DSC_NUM_BUF_RANGES; i++) {
config_pps.rc_range_parameters[i] =
(pps->rc_range_parameters[i] >> 3 & 0x1f) |
((pps->rc_range_parameters[i] >> 14 & 0x3) << 5) |
((pps->rc_range_parameters[i] >> 0 & 0x7) << 7) |
((pps->rc_range_parameters[i] >> 8 & 0x3f) << 10);
}
for (i = 0; i < ROCKCHIP_DSC_PPS_SIZE_BYTE / 4; i++)
Vop2Writel (Vop2->BaseAddress, RK3588_DSC_8K_PPS0_3 + decoder_regs_offset + i * 4, *pps_val++);
}
STATIC
VOID
Vop2DscEnable (
OUT DISPLAY_STATE *DisplayState,
OUT VOP2 *Vop2,
IN UINT8 dsc_id,
IN UINT64 dclk_rate
)
{
CONNECTOR_STATE *ConnectorState = &DisplayState->ConnectorState;
DRM_DISPLAY_MODE *Mode = &ConnectorState->DisplayMode;
CRTC_STATE *CrtcState = &DisplayState->CrtcState;
struct rockchip_dsc_sink_cap *dsc_sink_cap = &CrtcState->dsc_sink_cap;
const VOP2_DSC_DATA *dsc_data = &Vop2->Data->DscData[dsc_id];
BOOLEAN mipi_ds_mode = FALSE;
UINT8 dsc_interface_mode = 0;
UINT16 hsync_len = Mode->CrtcHSyncEnd - Mode->CrtcHSyncStart;
UINT16 hdisplay = Mode->CrtcHDisplay;
UINT16 htotal = Mode->CrtcHTotal;
UINT16 hact_st = Mode->CrtcHTotal - Mode->CrtcHSyncStart;
UINT16 vdisplay = Mode->CrtcVDisplay;
UINT16 vtotal = Mode->CrtcVTotal;
UINT16 vsync_len = Mode->CrtcVSyncEnd - Mode->CrtcVSyncStart;
UINT16 vact_st = Mode->CrtcVTotal - Mode->CrtcVSyncStart;
UINT16 vact_end = vact_st + vdisplay;
UINT32 ctrl_regs_offset = (dsc_id * 0x30);
UINT32 decoder_regs_offset = (dsc_id * 0x100);
UINT32 dsc_txp_clk_div = 0;
UINT32 dsc_pxl_clk_div = 0;
UINT32 dsc_cds_clk_div = 0;
UINT32 val = 0;
if (!Vop2->Data->NrDscs) {
DEBUG ((DEBUG_ERROR, "Unsupported DSC\n"));
return;
}
if (CrtcState->dsc_slice_num > dsc_data->max_slice_num)
DEBUG ((DEBUG_INFO, "DSC%d supported max slice is: %d, current is: %d\n",
dsc_data->id, dsc_data->max_slice_num, CrtcState->dsc_slice_num));
if (dsc_data->PdData) {
if (Vop2PowerDomainOn (Vop2, dsc_data->PdData))
DEBUG ((DEBUG_ERROR, "open dsc%d pd fail\n", dsc_id));
}
Vop2MaskWrite (Vop2->BaseAddress, RK3588_DSC_8K_INIT_DLY + ctrl_regs_offset, EN_MASK,
SCAN_TIMING_PARA_IMD_EN_SHIFT, 1, FALSE);
Vop2MaskWrite (Vop2->BaseAddress, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_PORT_SEL_MASK,
DSC_PORT_SEL_SHIFT, CrtcState->CrtcID, FALSE);
if (ConnectorState->OutputInterface & (VOP_OUTPUT_IF_HDMI0 | VOP_OUTPUT_IF_HDMI1)) {
dsc_interface_mode = VOP_DSC_IF_HDMI;
} else {
mipi_ds_mode = !!(ConnectorState->OutputFlags & ROCKCHIP_OUTPUT_MIPI_DS_MODE);
if (mipi_ds_mode)
dsc_interface_mode = VOP_DSC_IF_MIPI_DS_MODE;
else
dsc_interface_mode = VOP_DSC_IF_MIPI_VIDEO_MODE;
}
if (ConnectorState->OutputFlags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
Vop2MaskWrite (Vop2->BaseAddress, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_MAN_MODE_MASK,
DSC_MAN_MODE_SHIFT, 0, FALSE);
else
Vop2MaskWrite (Vop2->BaseAddress, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_MAN_MODE_MASK,
DSC_MAN_MODE_SHIFT, 1, FALSE);
Vop2CalcDscCruCfg(DisplayState, &dsc_txp_clk_div, &dsc_pxl_clk_div, &dsc_cds_clk_div, dclk_rate);
Vop2MaskWrite (Vop2->BaseAddress, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_INTERFACE_MODE_MASK,
DSC_INTERFACE_MODE_SHIFT, dsc_interface_mode, FALSE);
Vop2MaskWrite (Vop2->BaseAddress, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_PIXEL_NUM_MASK,
DSC_PIXEL_NUM_SHIFT, CrtcState->dsc_pixel_num >> 1, FALSE);
Vop2MaskWrite (Vop2->BaseAddress, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_TXP_CLK_DIV_MASK,
DSC_TXP_CLK_DIV_SHIFT, dsc_txp_clk_div, FALSE);
Vop2MaskWrite (Vop2->BaseAddress, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_PXL_CLK_DIV_MASK,
DSC_PXL_CLK_DIV_SHIFT, dsc_pxl_clk_div, FALSE);
Vop2MaskWrite (Vop2->BaseAddress, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_CDS_CLK_DIV_MASK,
DSC_CDS_CLK_DIV_SHIFT, dsc_cds_clk_div, FALSE);
Vop2MaskWrite (Vop2->BaseAddress, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, EN_MASK,
DSC_SCAN_EN_SHIFT, !mipi_ds_mode, FALSE);
Vop2MaskWrite (Vop2->BaseAddress, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_CDS_CLK_DIV_MASK,
DSC_HALT_EN_SHIFT, mipi_ds_mode, FALSE);
if (!mipi_ds_mode) {
UINT16 dsc_hsync, dsc_htotal, dsc_hact_st, dsc_hact_end;
UINT32 target_bpp = dsc_sink_cap->target_bits_per_pixel_x16;
UINT64 dsc_cds_rate = CrtcState->dsc_cds_clk_rate;
UINT32 v_pixclk_mhz = Mode->CrtcClock / 1000; /* video timing pixclk */
UINT32 dly_num, dsc_cds_rate_mhz, val = 0;
UINT32 k = 1;
if (ConnectorState->OutputFlags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)
k = 2;
if (target_bpp >> 4 < dsc_data->min_bits_per_pixel)
DEBUG ((DEBUG_WARN, "Unsupported bpp less than: %d\n", dsc_data->min_bits_per_pixel));
/*
* dly_num = delay_line_num * T(one-line) / T (dsc_cds)
* T (one-line) = 1/v_pixclk_mhz * htotal = htotal/v_pixclk_mhz
* T (dsc_cds) = 1 / dsc_cds_rate_mhz
*
* HDMI:
* delay_line_num: according the pps initial_xmit_delay to adjust vop dsc delay
* delay_line_num = 4 - BPP / 8
* = (64 - target_bpp / 8) / 16
* dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * (64 - target_bpp / 8) / 16;
*
* MIPI DSI[4320 and 9216 is buffer size for DSC]:
* DSC0:delay_line_num = 4320 * 8 / slince_num / chunk_size;
* delay_line_num = delay_line_num > 5 ? 5 : delay_line_num;
* DSC1:delay_line_num = 9216 * 2 / slince_num / chunk_size;
* delay_line_num = delay_line_num > 5 ? 5 : delay_line_num;
* dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * delay_line_num
*/
do_div(dsc_cds_rate, 1000000); /* hz to Mhz */
dsc_cds_rate_mhz = dsc_cds_rate;
dsc_hsync = hsync_len / 2;
if (dsc_interface_mode == VOP_DSC_IF_HDMI) {
dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * (64 - target_bpp / 8) / 16;
} else {
UINT32 dsc_buf_size = dsc_id == 0 ? 4320 * 8 : 9216 * 2;
UINT32 delay_line_num = dsc_buf_size / CrtcState->dsc_slice_num /
be16_to_cpu(CrtcState->pps.chunk_size);
delay_line_num = delay_line_num > 5 ? 5 : delay_line_num;
dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * delay_line_num;
/* The dsc mipi video mode dsc_hsync minimum size is 8 pixels */
if (dsc_hsync < 8)
dsc_hsync = 8;
}
Vop2MaskWrite (Vop2->BaseAddress, RK3588_DSC_8K_INIT_DLY + ctrl_regs_offset, DSC_INIT_DLY_MODE_MASK,
DSC_INIT_DLY_MODE_SHIFT, 0, FALSE);
Vop2MaskWrite (Vop2->BaseAddress, RK3588_DSC_8K_INIT_DLY + ctrl_regs_offset, DSC_INIT_DLY_NUM_MASK,
DSC_INIT_DLY_NUM_SHIFT, dly_num, FALSE);
/*
* htotal / dclk_core = dsc_htotal /cds_clk
*
* dclk_core = DCLK / (1 << dclk_core->div_val)
* cds_clk = txp_clk / (1 << dsc_cds_clk->div_val)
* txp_clk = DCLK / (1 << dsc_txp_clk->div_val)
*
* dsc_htotal = htotal * (1 << dclk_core->div_val) /
* ((1 << dsc_txp_clk->div_val) * (1 << dsc_cds_clk->div_val))
*/
dsc_htotal = htotal * (1 << CrtcState->DclkCoreDiv) /
((1 << dsc_txp_clk_div) * (1 << dsc_cds_clk_div));
val = dsc_htotal << 16 | dsc_hsync;
Vop2MaskWrite (Vop2->BaseAddress, RK3588_DSC_8K_HTOTAL_HS_END + ctrl_regs_offset, DSC_HTOTAL_PW_MASK,
DSC_HTOTAL_PW_SHIFT, val, FALSE);
dsc_hact_st = hact_st / 2;
dsc_hact_end = (hdisplay / k * target_bpp >> 4) / 24 + dsc_hact_st;
val = dsc_hact_end << 16 | dsc_hact_st;
Vop2MaskWrite (Vop2->BaseAddress, RK3588_DSC_8K_HACT_ST_END + ctrl_regs_offset, DSC_HACT_ST_END_MASK,
DSC_HACT_ST_END_SHIFT, val, FALSE);
Vop2MaskWrite (Vop2->BaseAddress, RK3588_DSC_8K_VTOTAL_VS_END + ctrl_regs_offset, DSC_VTOTAL_PW_MASK,
DSC_VTOTAL_PW_SHIFT, vtotal << 16 | vsync_len, FALSE);
Vop2MaskWrite (Vop2->BaseAddress, RK3588_DSC_8K_VACT_ST_END + ctrl_regs_offset, DSC_VACT_ST_END_MASK,
DSC_VACT_ST_END_SHIFT, vact_end << 16 | vact_st, FALSE);
}
Vop2MaskWrite (Vop2->BaseAddress, RK3588_DSC_8K_RST + ctrl_regs_offset, RST_DEASSERT_MASK,
RST_DEASSERT_SHIFT, 1, FALSE);
udelay(10);
val |= DSC_CTRL0_DEF_CON | (LogCalculate(CrtcState->dsc_slice_num) << DSC_NSLC_SHIFT) |
((dsc_sink_cap->version_minor == 2 ? 1 : 0) << DSC_IFEP_SHIFT);
Vop2Writel (Vop2->BaseAddress, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, val);
Vop2LoadPps(DisplayState, Vop2, dsc_id);
val |= (1 << DSC_PPS_UPD_SHIFT);
Vop2Writel (Vop2->BaseAddress, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, val);
DEBUG ((DEBUG_INFO, "DSC%d: txp:%lld div:%d, pxl:%lld div:%d, dsc:%lld div:%d\n",
dsc_id,
CrtcState->dsc_txp_clk_rate, dsc_txp_clk_div,
CrtcState->dsc_pxl_clk_rate, dsc_pxl_clk_div,
CrtcState->dsc_cds_clk_rate, dsc_cds_clk_div));
}
EFI_STATUS
Vop2Init (
IN ROCKCHIP_CRTC_PROTOCOL *This,
@@ -1633,6 +2112,15 @@ Vop2Init (
Vop2TVConfigUpdate (DisplayState, Vop2);
Vop2PostConfig (DisplayState, Vop2);
if (CrtcState->dsc_enable) {
if (ConnectorState->OutputFlags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) {
Vop2DscEnable(DisplayState, Vop2, 0, DclkRate * 1000LL);
Vop2DscEnable(DisplayState, Vop2, 1, DclkRate * 1000LL);
} else {
Vop2DscEnable(DisplayState, Vop2, CrtcState->dsc_id, DclkRate * 1000LL);
}
}
Vop2SetClk (CrtcState->CrtcID, DclkRate * 1000);
Vop2MaskWrite (Vop2->BaseAddress, RK3568_SYS_CTRL_LINE_FLAG0 + LineFlagOffset, LINE_FLAG_NUM_MASK,
@@ -1976,6 +2464,30 @@ Vop2SetPlane (
return EFI_SUCCESS;
}
STATIC
VOID
Vop2DscCfgDone (
IN ROCKCHIP_CRTC_PROTOCOL *This,
OUT DISPLAY_STATE *DisplayState
)
{
CONNECTOR_STATE *ConnectorState = &DisplayState->ConnectorState;
CRTC_STATE *CrtcState = &DisplayState->CrtcState;
VOP2 *Vop2 = CrtcState->Private;
UINT8 dsc_id = CrtcState->dsc_id;
UINT32 ctrl_regs_offset = (dsc_id * 0x30);
if (ConnectorState->OutputFlags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) {
Vop2MaskWrite (Vop2->BaseAddress, RK3588_DSC_8K_CFG_DONE, EN_MASK,
DSC_CFG_DONE_SHIFT, 1, FALSE);
Vop2MaskWrite (Vop2->BaseAddress, RK3588_DSC_8K_CFG_DONE + 0x30, EN_MASK,
DSC_CFG_DONE_SHIFT, 1, FALSE);
} else {
Vop2MaskWrite (Vop2->BaseAddress, RK3588_DSC_8K_CFG_DONE + ctrl_regs_offset, EN_MASK,
DSC_CFG_DONE_SHIFT, 1, FALSE);
}
}
EFI_STATUS
Vop2Enable (
IN ROCKCHIP_CRTC_PROTOCOL *This,
@@ -1991,6 +2503,10 @@ Vop2Enable (
STANDBY_EN_SHIFT, 0, FALSE);
Vop2Writel (Vop2->BaseAddress, RK3568_REG_CFG_DONE, CfgDone);
if (CrtcState->dsc_enable) {
Vop2DscCfgDone(This, DisplayState);
}
#ifdef DEBUG_DUMP_REG
Vop2DumpRegisters (DisplayState, Vop2FindWinByPhysID (Vop2, Vop2->VpPlaneMask[CrtcState->CrtcID].PrimaryPlaneId));
#endif

View File

@@ -61,6 +61,25 @@
/* KHz */
#define VOP2_MAX_DCLK_RATE 600000
/*
* vop2 dsc id
*/
#define ROCKCHIP_VOP2_DSC_8K 0
#define ROCKCHIP_VOP2_DSC_4K 1
/*
* vop2 internal power domain id,
* should be all none zero, 0 will be
* treat as invalid;
*/
#define VOP2_PD_CLUSTER0 BIT(0)
#define VOP2_PD_CLUSTER1 BIT(1)
#define VOP2_PD_CLUSTER2 BIT(2)
#define VOP2_PD_CLUSTER3 BIT(3)
#define VOP2_PD_DSC_8K BIT(5)
#define VOP2_PD_DSC_4K BIT(6)
#define VOP2_PD_ESMART BIT(7)
typedef enum {
CSC_BT601L,
CSC_BT709L,
@@ -128,13 +147,19 @@ typedef enum {
SCALE_DOWN = 0x2,
} SCALE_MODE;
typedef struct {
BOOLEAN IsParentNeeded;
CHAR8 PdEnShift;
CHAR8 PdStatusShift;
CHAR8 PmuStatusShift;
CHAR8 BisrEnStatusShift;
CHAR8 ParentPhyID;
typedef enum {
VOP_DSC_IF_DISABLE = 0,
VOP_DSC_IF_HDMI = 1,
VOP_DSC_IF_MIPI_DS_MODE = 2,
VOP_DSC_IF_MIPI_VIDEO_MODE = 3,
} VOP2_DSC_INTERFACE_MODE;
typedef struct VOP2_POWER_DOMAIN_DATA {
CHAR8 PdEnShift;
CHAR8 PdStatusShift;
CHAR8 PmuStatusShift;
CHAR8 BisrEnStatusShift;
struct VOP2_POWER_DOMAIN_DATA *ParentPdData;
} VOP2_POWER_DOMAIN_DATA;
typedef struct {
@@ -162,6 +187,18 @@ typedef struct {
INT32 CursorPlaneID;
} VOP2_VP_PLANE_MASK;
typedef struct {
UINT8 id;
VOP2_POWER_DOMAIN_DATA *PdData;
UINT8 max_slice_num;
UINT8 max_linebuf_depth; /* used to generate the bitstream */
UINT8 min_bits_per_pixel; /* bit num after encoder compress */
const CHAR8 *dsc_txp_clk_src_name;
const CHAR8 *dsc_txp_clk_name;
const CHAR8 *dsc_pxl_clk_name;
const CHAR8 *dsc_cds_clk_name;
} VOP2_DSC_DATA;
typedef struct {
UINT32 Version;
VOP2_VP_DATA *VpData;
@@ -171,6 +208,8 @@ typedef struct {
*/
VOP2_VP_PLANE_MASK *PlaneMask;
VOP2_DSC_DATA *DscData;
UINT8 NrVps;
UINT8 NrLayers;
UINT8 NrMixers;
@@ -181,6 +220,7 @@ typedef struct {
typedef struct {
UINT32 BaseAddress;
UINTN SysPmu;
UINT32 Version;
BOOLEAN GlobalInit;
VOP2_DATA *Data;

View File

@@ -109,8 +109,11 @@
#
INF Silicon/Rockchip/Drivers/Vop2Dxe/Vop2Dxe.inf
# INF Silicon/Rockchip/Library/DisplayLib/AnalogixDpLib.inf
!if $(RK_DW_HDMI_QP_ENABLE) == TRUE
INF Silicon/Rockchip/Library/DisplayLib/DwHdmiQpLib.inf
!endif
INF Silicon/Rockchip/Library/DisplayLib/DwDpLib.inf
INF Silicon/Rockchip/Library/DisplayLib/DwMipiDsi2Lib.inf
INF Silicon/Rockchip/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.inf
#

View File

@@ -11,6 +11,8 @@
#define __ROCKCHIP_DISPLAY_H__
#include <Uefi/UefiBaseType.h>
#include <Library/uboot-env.h>
#include <Library/drm_dsc.h>
#define LIST_FOR_EACH_ENTRY(Pos, Head, Member) \
for (Pos = BASE_CR((Head)->ForwardLink, typeof(*Pos), Member); \
@@ -24,8 +26,6 @@
#define INLINE static inline
#define BIT(x) (1 << x)
#define EDID_SIZE 128
typedef enum {
@@ -47,6 +47,8 @@ typedef enum {
#define ROCKCHIP_OUTPUT_DATA_SWAP BIT(2)
#define ROCKCHIP_OUTPUT_MIPI_DS_MODE BIT(3)
#define ROCKCHIP_DSC_PPS_SIZE_BYTE 88
/*
* display output interface supported by rockchip lcdc
*/
@@ -90,6 +92,27 @@ typedef struct {
UINT32 Height;
} VOP_RECT;
struct rockchip_dsc_sink_cap {
/**
* @slice_width: the number of pixel columns that comprise the slice width
* @slice_height: the number of pixel rows that comprise the slice height
* @block_pred: Does block prediction
* @native_420: Does sink support DSC with 4:2:0 compression
* @bpc_supported: compressed bpc supported by sink : 10, 12 or 16 bpc
* @version_major: DSC major version
* @version_minor: DSC minor version
* @target_bits_per_pixel_x16: bits num after compress and multiply 16
*/
UINT16 slice_width;
UINT16 slice_height;
BOOLEAN block_pred;
BOOLEAN native_420;
UINT8 bpc_supported;
UINT8 version_major;
UINT8 version_minor;
UINT16 target_bits_per_pixel_x16;
};
typedef struct {
UINT32 LeftMargin;
UINT32 RightMargin;
@@ -194,6 +217,19 @@ typedef struct {
UINT32 DMAAddress;
BOOLEAN YUVOverlay;
VOP_RECT MaxOutput;
UINT32 DclkCoreDiv;
UINT32 DclkOutDiv;
UINT8 dsc_id;
UINT8 dsc_enable;
UINT8 dsc_slice_num;
UINT8 dsc_pixel_num;
UINT64 dsc_txp_clk_rate;
UINT64 dsc_pxl_clk_rate;
UINT64 dsc_cds_clk_rate;
struct drm_dsc_picture_parameter_set pps;
struct rockchip_dsc_sink_cap dsc_sink_cap;
} CRTC_STATE;
typedef struct {
@@ -214,6 +250,25 @@ typedef struct {
UINT32 ForceOutputFormat;
} DISPLAY_STATE;
typedef struct {
UINT32 Resolution;
UINT32 Sync;
UINT32 BackPorch;
UINT32 FrontPorch;
} SCAN_TIMINGS;
typedef struct {
UINT32 CrtcId;
UINT32 OscFreq;
SCAN_TIMINGS Horizontal;
SCAN_TIMINGS Vertical;
UINT32 HsyncActive;
UINT32 VsyncActive;
UINT32 DenActive;
UINT32 ClkActive;
UINT32 VpsConfigModeID;
} DISPLAY_MODE;
EFIAPI
EFI_STATUS
DisplaySetCrtcInfo (
@@ -221,11 +276,10 @@ DisplaySetCrtcInfo (
IN UINT32 AdjustFlags
);
UINT32
EFIAPI
EFI_STATUS
DisplaySetFramebuffer (
OUT EFI_PHYSICAL_ADDRESS* VramBaseAddress,
OUT UINTN* VramSize
DrmModeVRefresh (
DRM_DISPLAY_MODE *Mode
);
#endif

View File

@@ -58,8 +58,22 @@
#define RK3568_DSP_IF_CTRL 0x02C
#define LVDS_DUAL_EN_SHIFT 0
#define RK3588_BT656_UV_SWAP_SHIFT 0
#define LVDS_DUAL_LEFT_RIGHT_EN_SHIFT 1
#define RK3588_BT656_YC_SWAP_SHIFT 1
#define LVDS_DUAL_SWAP_EN_SHIFT 2
#define BT656_UV_SWAP 4
#define RK3588_BT1120_UV_SWAP_SHIFT 4
#define BT656_YC_SWAP 5
#define RK3588_BT1120_YC_SWAP_SHIFT 5
#define BT656_DCLK_POL 6
#define RK3588_HDMI_DUAL_EN_SHIFT 8
#define RK3588_EDP_DUAL_EN_SHIFT 8
#define RK3588_DP_DUAL_EN_SHIFT 9
#define RK3568_MIPI_DUAL_EN_SHIFT 10
#define RK3588_MIPI_DSI0_MODE_SEL_SHIFT 11
#define RK3588_MIPI_DSI1_MODE_SEL_SHIFT 12
#define RK3568_DSP_IF_POL 0x030
#define IF_CTRL_REG_DONE_IMD_MASK 1
#define IF_CTRL_REG_DONE_IMD_SHIFT 28
@@ -112,6 +126,8 @@
#define RK3588_CLUSTER1_PD_EN_SHIFT 1
#define RK3588_CLUSTER2_PD_EN_SHIFT 2
#define RK3588_CLUSTER3_PD_EN_SHIFT 3
#define RK3588_DSC_8K_PD_EN_SHIFT 5
#define RK3588_DSC_4K_PD_EN_SHIFT 6
#define RK3588_ESMART_PD_EN_SHIFT 7
#define RK3568_SYS_STATUS0 0x60
@@ -119,6 +135,8 @@
#define RK3588_CLUSTER1_PD_STATUS_SHIFT 9
#define RK3588_CLUSTER2_PD_STATUS_SHIFT 10
#define RK3588_CLUSTER3_PD_STATUS_SHIFT 11
#define RK3588_DSC_8K_PD_STATUS_SHIFT 13
#define RK3588_DSC_4K_PD_STATUS_SHIFT 14
#define RK3588_ESMART_PD_STATUS_SHIFT 15
@@ -180,6 +198,9 @@
#define DCLK_DIV2_MASK 0x3
#define MIPI_DUAL_EN_SHIFT 20
#define MIPI_DUAL_SWAP_EN_SHIFT 21
#define EDPI_TE_EN 28
#define EDPI_WMS_HOLD_EN 30
#define EDPI_WMS_FS 31
#define RK3568_VP0_COLOR_BAR_CTRL 0xC08
#define RK3568_VP0_3D_LUT_CTRL 0xC10
@@ -566,6 +587,25 @@
#define RK3568_SMART1_REGION3_SCL_FACTOR_CBR 0x1EC8
#define RK3568_SMART1_REGION3_SCL_OFFSET 0x1ECC
/* DSC 8K/4K register definition */
#define RK3588_DSC_8K_PPS0_3 0x4000
#define RK3588_DSC_8K_CTRL0 0x40A0
#define DSC_EN_SHIFT 0
#define DSC_RBIT_SHIFT 2
#define DSC_RBYT_SHIFT 3
#define DSC_FLAL_SHIFT 4
#define DSC_MER_SHIFT 5
#define DSC_EPB_SHIFT 6
#define DSC_EPL_SHIFT 7
#define DSC_NSLC_MASK 0x7
#define DSC_NSLC_SHIFT 16
#define DSC_SBO_SHIFT 28
#define DSC_IFEP_SHIFT 29
#define DSC_PPS_UPD_SHIFT 31
#define DSC_CTRL0_DEF_CON ((1 << DSC_EN_SHIFT) | (1 << DSC_RBIT_SHIFT) | (0 << DSC_RBYT_SHIFT) | \
(1 << DSC_FLAL_SHIFT) | (1 << DSC_MER_SHIFT) | (0 << DSC_EPB_SHIFT) | \
(1 << DSC_EPL_SHIFT) | (1 << DSC_SBO_SHIFT))
#define RK3568_MAX_REG 0x1ED0
#define RK3588_VOP2_REG_BASE 0xFDD90000
@@ -574,6 +614,57 @@
#define RK3568_DSP_LINE_FLAG_NUM0_SHIFT 0
#define RK3568_DSP_LINE_FLAG_NUM1_SHIFT 16
/* DSC CTRL registers definition */
#define RK3588_DSC_8K_SYS_CTRL 0x200
#define DSC_PORT_SEL_MASK 0x3
#define DSC_PORT_SEL_SHIFT 0
#define DSC_MAN_MODE_MASK 0x1
#define DSC_MAN_MODE_SHIFT 2
#define DSC_INTERFACE_MODE_MASK 0x3
#define DSC_INTERFACE_MODE_SHIFT 4
#define DSC_PIXEL_NUM_MASK 0x3
#define DSC_PIXEL_NUM_SHIFT 6
#define DSC_PXL_CLK_DIV_MASK 0x1
#define DSC_PXL_CLK_DIV_SHIFT 8
#define DSC_CDS_CLK_DIV_MASK 0x3
#define DSC_CDS_CLK_DIV_SHIFT 12
#define DSC_TXP_CLK_DIV_MASK 0x3
#define DSC_TXP_CLK_DIV_SHIFT 14
#define DSC_INIT_DLY_MODE_MASK 0x1
#define DSC_INIT_DLY_MODE_SHIFT 16
#define DSC_SCAN_EN_SHIFT 17
#define DSC_HALT_EN_SHIFT 18
#define RK3588_DSC_8K_RST 0x204
#define RST_DEASSERT_MASK 0x1
#define RST_DEASSERT_SHIFT 0
#define RK3588_DSC_8K_CFG_DONE 0x208
#define DSC_CFG_DONE_SHIFT 0
#define RK3588_DSC_8K_INIT_DLY 0x20C
#define DSC_INIT_DLY_NUM_MASK 0xffff
#define DSC_INIT_DLY_NUM_SHIFT 0
#define SCAN_TIMING_PARA_IMD_EN_SHIFT 16
#define RK3588_DSC_8K_HTOTAL_HS_END 0x210
#define DSC_HTOTAL_PW_MASK 0xffffffff
#define DSC_HTOTAL_PW_SHIFT 0
#define RK3588_DSC_8K_HACT_ST_END 0x214
#define DSC_HACT_ST_END_MASK 0xffffffff
#define DSC_HACT_ST_END_SHIFT 0
#define RK3588_DSC_8K_VTOTAL_VS_END 0x218
#define DSC_VTOTAL_PW_MASK 0xffffffff
#define DSC_VTOTAL_PW_SHIFT 0
#define RK3588_DSC_8K_VACT_ST_END 0x21C
#define DSC_VACT_ST_END_MASK 0xffffffff
#define DSC_VACT_ST_END_SHIFT 0
#define RK3588_DSC_8K_STATUS 0x220
#define RK3588_VOP_GRF_BASE 0xFD5A4000
#define RK3588_GRF_VOP_CON2 0x0008
#define RK3588_GRF_EDP0_ENABLE_SHIFT 0
@@ -594,6 +685,8 @@
#define RK3588_PD_CLUSTER1_REPAIR_EN_SHIFT 10
#define RK3588_PD_CLUSTER2_REPAIR_EN_SHIFT 11
#define RK3588_PD_CLUSTER3_REPAIR_EN_SHIFT 12
#define RK3588_PD_DSC_8K_REPAIR_EN_SHIFT 13
#define RK3588_PD_DSC_4K_REPAIR_EN_SHIFT 14
#define RK3588_PD_ESMART_REPAIR_EN_SHIFT 15
#define RK3588_PMU_BISR_STATUS5 0x294
@@ -601,6 +694,8 @@
#define RK3588_PD_CLUSTER1_PWR_STAT_SHIFI 10
#define RK3588_PD_CLUSTER2_PWR_STAT_SHIFI 11
#define RK3588_PD_CLUSTER3_PWR_STAT_SHIFI 12
#define RK3588_PD_DSC_8K_PWR_STAT_SHIFI 13
#define RK3588_PD_DSC_4K_PWR_STAT_SHIFI 14
#define RK3588_PD_ESMART_PWR_STAT_SHIFI 15
#endif

View File

@@ -0,0 +1,613 @@
/* SPDX-License-Identifier: MIT
* Copyright (C) 2018 Intel Corp.
*
* Authors:
* Manasi Navare <manasi.d.navare@intel.com>
*/
#ifndef DRM_DSC_H_
#define DRM_DSC_H_
#include <Library/drm_dp_helper.h>
/* VESA Display Stream Compression DSC 1.2 constants */
#define DSC_NUM_BUF_RANGES 15
#define DSC_MUX_WORD_SIZE_8_10_BPC 48
#define DSC_MUX_WORD_SIZE_12_BPC 64
#define DSC_RC_PIXELS_PER_GROUP 3
#define DSC_SCALE_DECREMENT_INTERVAL_MAX 4095
#define DSC_RANGE_BPG_OFFSET_MASK 0x3f
/* DSC Rate Control Constants */
#define DSC_RC_MODEL_SIZE_CONST 8192
#define DSC_RC_EDGE_FACTOR_CONST 6
#define DSC_RC_TGT_OFFSET_HI_CONST 3
#define DSC_RC_TGT_OFFSET_LO_CONST 3
/* DSC PPS constants and macros */
#define DSC_PPS_VERSION_MAJOR_SHIFT 4
#define DSC_PPS_BPC_SHIFT 4
#define DSC_PPS_MSB_SHIFT 8
#define DSC_PPS_LSB_MASK (0xFF << 0)
#define DSC_PPS_BPP_HIGH_MASK (0x3 << 8)
#define DSC_PPS_VBR_EN_SHIFT 2
#define DSC_PPS_SIMPLE422_SHIFT 3
#define DSC_PPS_CONVERT_RGB_SHIFT 4
#define DSC_PPS_BLOCK_PRED_EN_SHIFT 5
#define DSC_PPS_INIT_XMIT_DELAY_HIGH_MASK (0x3 << 8)
#define DSC_PPS_SCALE_DEC_INT_HIGH_MASK (0xF << 8)
#define DSC_PPS_RC_TGT_OFFSET_HI_SHIFT 4
#define DSC_PPS_RC_RANGE_MINQP_SHIFT 11
#define DSC_PPS_RC_RANGE_MAXQP_SHIFT 6
#define DSC_PPS_NATIVE_420_SHIFT 1
#define DSC_1_2_MAX_LINEBUF_DEPTH_BITS 16
#define DSC_1_2_MAX_LINEBUF_DEPTH_VAL 0
#define DSC_1_1_MAX_LINEBUF_DEPTH_BITS 13
/**
* struct drm_dsc_rc_range_parameters - DSC Rate Control range parameters
*
* This defines different rate control parameters used by the DSC engine
* to compress the frame.
*/
struct drm_dsc_rc_range_parameters {
/**
* @range_min_qp: Min Quantization Parameters allowed for this range
*/
u8 range_min_qp;
/**
* @range_max_qp: Max Quantization Parameters allowed for this range
*/
u8 range_max_qp;
/**
* @range_bpg_offset:
* Bits/group offset to apply to target for this group
*/
u8 range_bpg_offset;
};
/**
* struct drm_dsc_config - Parameters required to configure DSC
*
* Driver populates this structure with all the parameters required
* to configure the display stream compression on the source.
*/
struct drm_dsc_config {
/**
* @line_buf_depth:
* Bits per component for previous reconstructed line buffer
*/
u8 line_buf_depth;
/**
* @bits_per_component: Bits per component to code (8/10/12)
*/
u8 bits_per_component;
/**
* @convert_rgb:
* Flag to indicate if RGB - YCoCg conversion is needed
* True if RGB input, False if YCoCg input
*/
bool convert_rgb;
/**
* @slice_count: Number of slices per line used by the DSC encoder
*/
u8 slice_count;
/**
* @slice_width: Width of each slice in pixels
*/
u16 slice_width;
/**
* @slice_height: Slice height in pixels
*/
u16 slice_height;
/**
* @simple_422: True if simple 4_2_2 mode is enabled else False
*/
bool simple_422;
/**
* @pic_width: Width of the input display frame in pixels
*/
u16 pic_width;
/**
* @pic_height: Vertical height of the input display frame
*/
u16 pic_height;
/**
* @rc_tgt_offset_high:
* Offset to bits/group used by RC to determine QP adjustment
*/
u8 rc_tgt_offset_high;
/**
* @rc_tgt_offset_low:
* Offset to bits/group used by RC to determine QP adjustment
*/
u8 rc_tgt_offset_low;
/**
* @bits_per_pixel:
* Target bits per pixel with 4 fractional bits, bits_per_pixel << 4
*/
u16 bits_per_pixel;
/**
* @rc_edge_factor:
* Factor to determine if an edge is present based on the bits produced
*/
u8 rc_edge_factor;
/**
* @rc_quant_incr_limit1:
* Slow down incrementing once the range reaches this value
*/
u8 rc_quant_incr_limit1;
/**
* @rc_quant_incr_limit0:
* Slow down incrementing once the range reaches this value
*/
u8 rc_quant_incr_limit0;
/**
* @initial_xmit_delay:
* Number of pixels to delay the initial transmission
*/
u16 initial_xmit_delay;
/**
* @initial_dec_delay:
* Initial decoder delay, number of pixel times that the decoder
* accumulates data in its rate buffer before starting to decode
* and output pixels.
*/
u16 initial_dec_delay;
/**
* @block_pred_enable:
* True if block prediction is used to code any groups within the
* picture. False if BP not used
*/
bool block_pred_enable;
/**
* @first_line_bpg_offset:
* Number of additional bits allocated for each group on the first
* line of slice.
*/
u8 first_line_bpg_offset;
/**
* @initial_offset: Value to use for RC model offset at slice start
*/
u16 initial_offset;
/**
* @rc_buf_thresh: Thresholds defining each of the buffer ranges
*/
u16 rc_buf_thresh[DSC_NUM_BUF_RANGES - 1];
/**
* @rc_range_params:
* Parameters for each of the RC ranges defined in
* &struct drm_dsc_rc_range_parameters
*/
struct drm_dsc_rc_range_parameters rc_range_params[DSC_NUM_BUF_RANGES];
/**
* @rc_model_size: Total size of RC model
*/
u16 rc_model_size;
/**
* @flatness_min_qp: Minimum QP where flatness information is sent
*/
u8 flatness_min_qp;
/**
* @flatness_max_qp: Maximum QP where flatness information is sent
*/
u8 flatness_max_qp;
/**
* @initial_scale_value: Initial value for the scale factor
*/
u8 initial_scale_value;
/**
* @scale_decrement_interval:
* Specifies number of group times between decrementing the scale factor
* at beginning of a slice.
*/
u16 scale_decrement_interval;
/**
* @scale_increment_interval:
* Number of group times between incrementing the scale factor value
* used at the beginning of a slice.
*/
u16 scale_increment_interval;
/**
* @nfl_bpg_offset: Non first line BPG offset to be used
*/
u16 nfl_bpg_offset;
/**
* @slice_bpg_offset: BPG offset used to enforce slice bit
*/
u16 slice_bpg_offset;
/**
* @final_offset: Final RC linear transformation offset value
*/
u16 final_offset;
/**
* @vbr_enable: True if VBR mode is enabled, false if disabled
*/
bool vbr_enable;
/**
* @mux_word_size: Mux word size (in bits) for SSM mode
*/
u8 mux_word_size;
/**
* @slice_chunk_size:
* The (max) size in bytes of the "chunks" that are used in slice
* multiplexing.
*/
u16 slice_chunk_size;
/**
* @rc_bits: Rate control buffer size in bits
*/
u16 rc_bits;
/**
* @dsc_version_minor: DSC minor version
*/
u8 dsc_version_minor;
/**
* @dsc_version_major: DSC major version
*/
u8 dsc_version_major;
/**
* @native_422: True if Native 4:2:2 supported, else false
*/
bool native_422;
/**
* @native_420: True if Native 4:2:0 supported else false.
*/
bool native_420;
/**
* @second_line_bpg_offset:
* Additional bits/grp for seconnd line of slice for native 4:2:0
*/
u8 second_line_bpg_offset;
/**
* @nsl_bpg_offset:
* Num of bits deallocated for each grp that is not in second line of
* slice
*/
u16 nsl_bpg_offset;
/**
* @second_line_offset_adj:
* Offset adjustment for second line in Native 4:2:0 mode
*/
u16 second_line_offset_adj;
};
/**
* struct picture_parameter_set - Represents 128 bytes of Picture Parameter Set
*
* The VESA DSC standard defines picture parameter set (PPS) which display
* stream compression encoders must communicate to decoders.
* The PPS is encapsulated in 128 bytes (PPS 0 through PPS 127). The fields in
* this structure are as per Table 4.1 in Vesa DSC specification v1.1/v1.2.
* The PPS fields that span over more than a byte should be stored in Big Endian
* format.
*/
#pragma pack(1)
struct drm_dsc_picture_parameter_set {
/**
* @dsc_version:
* PPS0[3:0] - dsc_version_minor: Contains Minor version of DSC
* PPS0[7:4] - dsc_version_major: Contains major version of DSC
*/
u8 dsc_version;
/**
* @pps_identifier:
* PPS1[7:0] - Application specific identifier that can be
* used to differentiate between different PPS tables.
*/
u8 pps_identifier;
/**
* @pps_reserved:
* PPS2[7:0]- RESERVED Byte
*/
u8 pps_reserved;
/**
* @pps_3:
* PPS3[3:0] - linebuf_depth: Contains linebuffer bit depth used to
* generate the bitstream. (0x0 - 16 bits for DSC 1.2, 0x8 - 8 bits,
* 0xA - 10 bits, 0xB - 11 bits, 0xC - 12 bits, 0xD - 13 bits,
* 0xE - 14 bits for DSC1.2, 0xF - 14 bits for DSC 1.2.
* PPS3[7:4] - bits_per_component: Bits per component for the original
* pixels of the encoded picture.
* 0x0 = 16bpc (allowed only when dsc_version_minor = 0x2)
* 0x8 = 8bpc, 0xA = 10bpc, 0xC = 12bpc, 0xE = 14bpc (also
* allowed only when dsc_minor_version = 0x2)
*/
u8 pps_3;
/**
* @pps_4:
* PPS4[1:0] -These are the most significant 2 bits of
* compressed BPP bits_per_pixel[9:0] syntax element.
* PPS4[2] - vbr_enable: 0 = VBR disabled, 1 = VBR enabled
* PPS4[3] - simple_422: Indicates if decoder drops samples to
* reconstruct the 4:2:2 picture.
* PPS4[4] - Convert_rgb: Indicates if DSC color space conversion is
* active.
* PPS4[5] - blobk_pred_enable: Indicates if BP is used to code any
* groups in picture
* PPS4[7:6] - Reserved bits
*/
u8 pps_4;
/**
* @bits_per_pixel_low:
* PPS5[7:0] - This indicates the lower significant 8 bits of
* the compressed BPP bits_per_pixel[9:0] element.
*/
u8 bits_per_pixel_low;
/**
* @pic_height:
* PPS6[7:0], PPS7[7:0] -pic_height: Specifies the number of pixel rows
* within the raster.
*/
__be16 pic_height;
/**
* @pic_width:
* PPS8[7:0], PPS9[7:0] - pic_width: Number of pixel columns within
* the raster.
*/
__be16 pic_width;
/**
* @slice_height:
* PPS10[7:0], PPS11[7:0] - Slice height in units of pixels.
*/
__be16 slice_height;
/**
* @slice_width:
* PPS12[7:0], PPS13[7:0] - Slice width in terms of pixels.
*/
__be16 slice_width;
/**
* @chunk_size:
* PPS14[7:0], PPS15[7:0] - Size in units of bytes of the chunks
* that are used for slice multiplexing.
*/
__be16 chunk_size;
/**
* @initial_xmit_delay_high:
* PPS16[1:0] - Most Significant two bits of initial transmission delay.
* It specifies the number of pixel times that the encoder waits before
* transmitting data from its rate buffer.
* PPS16[7:2] - Reserved
*/
u8 initial_xmit_delay_high;
/**
* @initial_xmit_delay_low:
* PPS17[7:0] - Least significant 8 bits of initial transmission delay.
*/
u8 initial_xmit_delay_low;
/**
* @initial_dec_delay:
*
* PPS18[7:0], PPS19[7:0] - Initial decoding delay which is the number
* of pixel times that the decoder accumulates data in its rate buffer
* before starting to decode and output pixels.
*/
__be16 initial_dec_delay;
/**
* @pps20_reserved:
*
* PPS20[7:0] - Reserved
*/
u8 pps20_reserved;
/**
* @initial_scale_value:
* PPS21[5:0] - Initial rcXformScale factor used at beginning
* of a slice.
* PPS21[7:6] - Reserved
*/
u8 initial_scale_value;
/**
* @scale_increment_interval:
* PPS22[7:0], PPS23[7:0] - Number of group times between incrementing
* the rcXformScale factor at end of a slice.
*/
__be16 scale_increment_interval;
/**
* @scale_decrement_interval_high:
* PPS24[3:0] - Higher 4 bits indicating number of group times between
* decrementing the rcXformScale factor at beginning of a slice.
* PPS24[7:4] - Reserved
*/
u8 scale_decrement_interval_high;
/**
* @scale_decrement_interval_low:
* PPS25[7:0] - Lower 8 bits of scale decrement interval
*/
u8 scale_decrement_interval_low;
/**
* @pps26_reserved:
* PPS26[7:0]
*/
u8 pps26_reserved;
/**
* @first_line_bpg_offset:
* PPS27[4:0] - Number of additional bits that are allocated
* for each group on first line of a slice.
* PPS27[7:5] - Reserved
*/
u8 first_line_bpg_offset;
/**
* @nfl_bpg_offset:
* PPS28[7:0], PPS29[7:0] - Number of bits including frac bits
* deallocated for each group for groups after the first line of slice.
*/
__be16 nfl_bpg_offset;
/**
* @slice_bpg_offset:
* PPS30, PPS31[7:0] - Number of bits that are deallocated for each
* group to enforce the slice constraint.
*/
__be16 slice_bpg_offset;
/**
* @initial_offset:
* PPS32,33[7:0] - Initial value for rcXformOffset
*/
__be16 initial_offset;
/**
* @final_offset:
* PPS34,35[7:0] - Maximum end-of-slice value for rcXformOffset
*/
__be16 final_offset;
/**
* @flatness_min_qp:
* PPS36[4:0] - Minimum QP at which flatness is signaled and
* flatness QP adjustment is made.
* PPS36[7:5] - Reserved
*/
u8 flatness_min_qp;
/**
* @flatness_max_qp:
* PPS37[4:0] - Max QP at which flatness is signalled and
* the flatness adjustment is made.
* PPS37[7:5] - Reserved
*/
u8 flatness_max_qp;
/**
* @rc_model_size:
* PPS38,39[7:0] - Number of bits within RC Model.
*/
__be16 rc_model_size;
/**
* @rc_edge_factor:
* PPS40[3:0] - Ratio of current activity vs, previous
* activity to determine presence of edge.
* PPS40[7:4] - Reserved
*/
u8 rc_edge_factor;
/**
* @rc_quant_incr_limit0:
* PPS41[4:0] - QP threshold used in short term RC
* PPS41[7:5] - Reserved
*/
u8 rc_quant_incr_limit0;
/**
* @rc_quant_incr_limit1:
* PPS42[4:0] - QP threshold used in short term RC
* PPS42[7:5] - Reserved
*/
u8 rc_quant_incr_limit1;
/**
* @rc_tgt_offset:
* PPS43[3:0] - Lower end of the variability range around the target
* bits per group that is allowed by short term RC.
* PPS43[7:4]- Upper end of the variability range around the target
* bits per group that i allowed by short term rc.
*/
u8 rc_tgt_offset;
/**
* @rc_buf_thresh:
* PPS44[7:0] - PPS57[7:0] - Specifies the thresholds in RC model for
* the 15 ranges defined by 14 thresholds.
*/
u8 rc_buf_thresh[DSC_NUM_BUF_RANGES - 1];
/**
* @rc_range_parameters:
* PPS58[7:0] - PPS87[7:0]
* Parameters that correspond to each of the 15 ranges.
*/
__be16 rc_range_parameters[DSC_NUM_BUF_RANGES];
/**
* @native_422_420:
* PPS88[0] - 0 = Native 4:2:2 not used
* 1 = Native 4:2:2 used
* PPS88[1] - 0 = Native 4:2:0 not use
* 1 = Native 4:2:0 used
* PPS88[7:2] - Reserved 6 bits
*/
u8 native_422_420;
/**
* @second_line_bpg_offset:
* PPS89[4:0] - Additional bits/group budget for the
* second line of a slice in Native 4:2:0 mode.
* Set to 0 if DSC minor version is 1 or native420 is 0.
* PPS89[7:5] - Reserved
*/
u8 second_line_bpg_offset;
/**
* @nsl_bpg_offset:
* PPS90[7:0], PPS91[7:0] - Number of bits that are deallocated
* for each group that is not in the second line of a slice.
*/
__be16 nsl_bpg_offset;
/**
* @second_line_offset_adj:
* PPS92[7:0], PPS93[7:0] - Used as offset adjustment for the second
* line in Native 4:2:0 mode.
*/
__be16 second_line_offset_adj;
/**
* @pps_long_94_reserved:
* PPS 94, 95, 96, 97 - Reserved
*/
u32 pps_long_94_reserved;
/**
* @pps_long_98_reserved:
* PPS 98, 99, 100, 101 - Reserved
*/
u32 pps_long_98_reserved;
/**
* @pps_long_102_reserved:
* PPS 102, 103, 104, 105 - Reserved
*/
u32 pps_long_102_reserved;
/**
* @pps_long_106_reserved:
* PPS 106, 107, 108, 109 - reserved
*/
u32 pps_long_106_reserved;
/**
* @pps_long_110_reserved:
* PPS 110, 111, 112, 113 - reserved
*/
u32 pps_long_110_reserved;
/**
* @pps_long_114_reserved:
* PPS 114 - 117 - reserved
*/
u32 pps_long_114_reserved;
/**
* @pps_long_118_reserved:
* PPS 118 - 121 - reserved
*/
u32 pps_long_118_reserved;
/**
* @pps_long_122_reserved:
* PPS 122- 125 - reserved
*/
u32 pps_long_122_reserved;
/**
* @pps_short_126_reserved:
* PPS 126, 127 - reserved
*/
__be16 pps_short_126_reserved;
};
#pragma pack()
/**
* struct drm_dsc_pps_infoframe - DSC infoframe carrying the Picture Parameter
* Set Metadata
*
* This structure represents the DSC PPS infoframe required to send the Picture
* Parameter Set metadata required before enabling VESA Display Stream
* Compression. This is based on the DP Secondary Data Packet structure and
* comprises of SDP Header as defined &struct dp_sdp_header in drm_dp_helper.h
* and PPS payload defined in &struct drm_dsc_picture_parameter_set.
*
* @pps_header: Header for PPS as per DP SDP header format of type
* &struct dp_sdp_header
* @pps_payload: PPS payload fields as per DSC specification Table 4-1
* as represented in &struct drm_dsc_picture_parameter_set
*/
#pragma pack(1)
struct drm_dsc_pps_infoframe {
struct dp_sdp_header pps_header;
struct drm_dsc_picture_parameter_set pps_payload;
};
#pragma pack()
void drm_dsc_dp_pps_header_init(struct dp_sdp_header *pps_header);
void drm_dsc_pps_payload_pack(struct drm_dsc_picture_parameter_set *pps_sdp,
const struct drm_dsc_config *dsc_cfg);
int drm_dsc_compute_rc_parameters(struct drm_dsc_config *vdsc_cfg);
#endif /* _DRM_DSC_H_ */

View File

@@ -0,0 +1,256 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* MIPI DSI Bus
*
* Copyright (C) 2012-2013, Samsung Electronics, Co., Ltd.
* Andrzej Hajda <a.hajda@samsung.com>
*/
#ifndef __DRM_MIPI_DSI_H__
#define __DRM_MIPI_DSI_H__
#include <Library/mipi_display.h>
#include <Library/drm_dsc.h>
struct mipi_dsi_host;
struct mipi_dsi_device;
/* request ACK from peripheral */
#define MIPI_DSI_MSG_REQ_ACK BIT(0)
/* use Low Power Mode to transmit message */
#define MIPI_DSI_MSG_USE_LPM BIT(1)
/**
* struct mipi_dsi_msg - read/write DSI buffer
* @channel: virtual channel id
* @type: payload data type
* @flags: flags controlling this message transmission
* @tx_len: length of @tx_buf
* @tx_buf: data to be written
* @rx_len: length of @rx_buf
* @rx_buf: data to be read, or NULL
*/
struct mipi_dsi_msg {
u8 channel;
u8 type;
u16 flags;
size_t tx_len;
const void *tx_buf;
size_t rx_len;
void *rx_buf;
};
bool mipi_dsi_packet_format_is_short(u8 type);
bool mipi_dsi_packet_format_is_long(u8 type);
/**
* struct mipi_dsi_packet - represents a MIPI DSI packet in protocol format
* @size: size (in bytes) of the packet
* @header: the four bytes that make up the header (Data ID, Word Count or
* Packet Data, and ECC)
* @payload_length: number of bytes in the payload
* @payload: a pointer to a buffer containing the payload, if any
*/
struct mipi_dsi_packet {
size_t size;
u8 header[4];
size_t payload_length;
const u8 *payload;
};
int mipi_dsi_create_packet(struct mipi_dsi_packet *packet,
const struct mipi_dsi_msg *msg);
/**
* struct mipi_dsi_host_ops - DSI bus operations
* @attach: attach DSI device to DSI host
* @detach: detach DSI device from DSI host
* @transfer: transmit a DSI packet
*
* DSI packets transmitted by .transfer() are passed in as mipi_dsi_msg
* structures. This structure contains information about the type of packet
* being transmitted as well as the transmit and receive buffers. When an
* error is encountered during transmission, this function will return a
* negative error code. On success it shall return the number of bytes
* transmitted for write packets or the number of bytes received for read
* packets.
*
* Note that typically DSI packet transmission is atomic, so the .transfer()
* function will seldomly return anything other than the number of bytes
* contained in the transmit buffer on success.
*/
struct mipi_dsi_host_ops {
int (*attach)(struct mipi_dsi_host *host,
struct mipi_dsi_device *dsi);
int (*detach)(struct mipi_dsi_host *host,
struct mipi_dsi_device *dsi);
ssize_t (*transfer)(struct mipi_dsi_host *host,
const struct mipi_dsi_msg *msg);
};
/**
* struct mipi_dsi_host - DSI host device
* @dev: driver model device node for this DSI host
* @ops: DSI host operations
* @list: list management
*/
struct mipi_dsi_host {
struct udevice *dev;
const struct mipi_dsi_host_ops *ops;
};
/* DSI mode flags */
/* video mode */
#define MIPI_DSI_MODE_VIDEO BIT(0)
/* video burst mode */
#define MIPI_DSI_MODE_VIDEO_BURST BIT(1)
/* video pulse mode */
#define MIPI_DSI_MODE_VIDEO_SYNC_PULSE BIT(2)
/* enable auto vertical count mode */
#define MIPI_DSI_MODE_VIDEO_AUTO_VERT BIT(3)
/* enable hsync-end packets in vsync-pulse and v-porch area */
#define MIPI_DSI_MODE_VIDEO_HSE BIT(4)
/* disable hfront-porch area */
#define MIPI_DSI_MODE_VIDEO_HFP BIT(5)
/* disable hback-porch area */
#define MIPI_DSI_MODE_VIDEO_HBP BIT(6)
/* disable hsync-active area */
#define MIPI_DSI_MODE_VIDEO_HSA BIT(7)
/* flush display FIFO on vsync pulse */
#define MIPI_DSI_MODE_VSYNC_FLUSH BIT(8)
/* disable EoT packets in HS mode */
#define MIPI_DSI_MODE_EOT_PACKET BIT(9)
/* device supports non-continuous clock behavior (DSI spec 5.6.1) */
#define MIPI_DSI_CLOCK_NON_CONTINUOUS BIT(10)
/* transmit data in low power */
#define MIPI_DSI_MODE_LPM BIT(11)
enum mipi_dsi_pixel_format {
MIPI_DSI_FMT_RGB888,
MIPI_DSI_FMT_RGB666,
MIPI_DSI_FMT_RGB666_PACKED,
MIPI_DSI_FMT_RGB565,
};
#define DSI_DEV_NAME_SIZE 20
/**
* struct mipi_dsi_device - DSI peripheral device
* @host: DSI host for this peripheral
* @dev: driver model device node for this peripheral
* @name: DSI peripheral chip type
* @channel: virtual channel assigned to the peripheral
* @format: pixel format for video mode
* @lanes: number of active data lanes
* @mode_flags: DSI operation mode related flags
* @hs_rate: maximum lane frequency for high speed mode in hertz, this should
* be set to the real limits of the hardware, zero is only accepted for
* legacy drivers
* @lp_rate: maximum lane frequency for low power mode in hertz, this should
* be set to the real limits of the hardware, zero is only accepted for
* legacy drivers
*/
struct mipi_dsi_device {
struct mipi_dsi_host *host;
struct udevice *dev;
char name[DSI_DEV_NAME_SIZE];
unsigned int channel;
unsigned int lanes;
enum mipi_dsi_pixel_format format;
unsigned long mode_flags;
unsigned long hs_rate;
unsigned long lp_rate;
};
/**
* mipi_dsi_pixel_format_to_bpp - obtain the number of bits per pixel for any
* given pixel format defined by the MIPI DSI
* specification
* @fmt: MIPI DSI pixel format
*
* Returns: The number of bits per pixel of the given pixel format.
*/
static inline int mipi_dsi_pixel_format_to_bpp(enum mipi_dsi_pixel_format fmt)
{
switch (fmt) {
case MIPI_DSI_FMT_RGB888:
case MIPI_DSI_FMT_RGB666:
return 24;
case MIPI_DSI_FMT_RGB666_PACKED:
return 18;
case MIPI_DSI_FMT_RGB565:
return 16;
}
return -EINVAL;
}
int mipi_dsi_attach(struct mipi_dsi_device *dsi);
int mipi_dsi_detach(struct mipi_dsi_device *dsi);
int mipi_dsi_shutdown_peripheral(struct mipi_dsi_device *dsi);
int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi);
int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi,
u16 value);
ssize_t mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable);
ssize_t mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi,
const struct drm_dsc_picture_parameter_set *pps);
ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload,
size_t size);
ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
size_t num_params, void *data, size_t size);
/**
* enum mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode
* @MIPI_DSI_DCS_TEAR_MODE_VBLANK: the TE output line consists of V-Blanking
* information only
* @MIPI_DSI_DCS_TEAR_MODE_VHBLANK : the TE output line consists of both
* V-Blanking and H-Blanking information
*/
enum mipi_dsi_dcs_tear_mode {
MIPI_DSI_DCS_TEAR_MODE_VBLANK,
MIPI_DSI_DCS_TEAR_MODE_VHBLANK,
};
#define MIPI_DSI_DCS_POWER_MODE_DISPLAY BIT(2)
#define MIPI_DSI_DCS_POWER_MODE_NORMAL BIT(3)
#define MIPI_DSI_DCS_POWER_MODE_SLEEP BIT(4)
#define MIPI_DSI_DCS_POWER_MODE_PARTIAL BIT(5)
#define MIPI_DSI_DCS_POWER_MODE_IDLE BIT(6)
ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi,
const void *data, size_t len);
ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd,
const void *data, size_t len);
ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data,
size_t len);
int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi);
int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi);
int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode);
int mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device *dsi, u8 *format);
int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi);
int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi);
int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi);
int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi);
int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start,
u16 end);
int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start,
u16 end);
int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi);
int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi,
enum mipi_dsi_dcs_tear_mode mode);
int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format);
int mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device *dsi, u16 scanline);
int mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device *dsi,
u16 brightness);
int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi,
u16 *brightness);
#endif /* __DRM_MIPI_DSI__ */

View File

@@ -0,0 +1,143 @@
/*
* Defines for Mobile Industry Processor Interface (MIPI(R))
* Display Working Group standards: DSI, DCS, DBI, DPI
*
* Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
* Copyright (C) 2006 Nokia Corporation
* Author: Imre Deak <imre.deak@nokia.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef MIPI_DISPLAY_H
#define MIPI_DISPLAY_H
/* MIPI DSI Processor-to-Peripheral transaction types */
enum {
MIPI_DSI_V_SYNC_START = 0x01,
MIPI_DSI_V_SYNC_END = 0x11,
MIPI_DSI_H_SYNC_START = 0x21,
MIPI_DSI_H_SYNC_END = 0x31,
MIPI_DSI_COMPRESSION_MODE = 0x07,
MIPI_DSI_COLOR_MODE_OFF = 0x02,
MIPI_DSI_COLOR_MODE_ON = 0x12,
MIPI_DSI_SHUTDOWN_PERIPHERAL = 0x22,
MIPI_DSI_TURN_ON_PERIPHERAL = 0x32,
MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM = 0x03,
MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM = 0x13,
MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM = 0x23,
MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM = 0x04,
MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM = 0x14,
MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM = 0x24,
MIPI_DSI_DCS_SHORT_WRITE = 0x05,
MIPI_DSI_DCS_SHORT_WRITE_PARAM = 0x15,
MIPI_DSI_DCS_READ = 0x06,
MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE = 0x37,
MIPI_DSI_END_OF_TRANSMISSION = 0x08,
MIPI_DSI_NULL_PACKET = 0x09,
MIPI_DSI_BLANKING_PACKET = 0x19,
MIPI_DSI_GENERIC_LONG_WRITE = 0x29,
MIPI_DSI_DCS_LONG_WRITE = 0x39,
MIPI_DSI_PICTURE_PARAMETER_SET = 0x0a,
MIPI_DSI_COMPRESSED_PIXEL_STREAM = 0x0b,
MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20 = 0x0c,
MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24 = 0x1c,
MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16 = 0x2c,
MIPI_DSI_PACKED_PIXEL_STREAM_30 = 0x0d,
MIPI_DSI_PACKED_PIXEL_STREAM_36 = 0x1d,
MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12 = 0x3d,
MIPI_DSI_PACKED_PIXEL_STREAM_16 = 0x0e,
MIPI_DSI_PACKED_PIXEL_STREAM_18 = 0x1e,
MIPI_DSI_PIXEL_STREAM_3BYTE_18 = 0x2e,
MIPI_DSI_PACKED_PIXEL_STREAM_24 = 0x3e,
};
/* MIPI DSI Peripheral-to-Processor transaction types */
enum {
MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT = 0x02,
MIPI_DSI_RX_END_OF_TRANSMISSION = 0x08,
MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE = 0x11,
MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE = 0x12,
MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE = 0x1a,
MIPI_DSI_RX_DCS_LONG_READ_RESPONSE = 0x1c,
MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE = 0x21,
MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE = 0x22,
};
/* MIPI DCS commands */
enum {
MIPI_DCS_NOP = 0x00,
MIPI_DCS_SOFT_RESET = 0x01,
MIPI_DCS_GET_DISPLAY_ID = 0x04,
MIPI_DCS_GET_RED_CHANNEL = 0x06,
MIPI_DCS_GET_GREEN_CHANNEL = 0x07,
MIPI_DCS_GET_BLUE_CHANNEL = 0x08,
MIPI_DCS_GET_DISPLAY_STATUS = 0x09,
MIPI_DCS_GET_POWER_MODE = 0x0A,
MIPI_DCS_GET_ADDRESS_MODE = 0x0B,
MIPI_DCS_GET_PIXEL_FORMAT = 0x0C,
MIPI_DCS_GET_DISPLAY_MODE = 0x0D,
MIPI_DCS_GET_SIGNAL_MODE = 0x0E,
MIPI_DCS_GET_DIAGNOSTIC_RESULT = 0x0F,
MIPI_DCS_ENTER_SLEEP_MODE = 0x10,
MIPI_DCS_EXIT_SLEEP_MODE = 0x11,
MIPI_DCS_ENTER_PARTIAL_MODE = 0x12,
MIPI_DCS_ENTER_NORMAL_MODE = 0x13,
MIPI_DCS_EXIT_INVERT_MODE = 0x20,
MIPI_DCS_ENTER_INVERT_MODE = 0x21,
MIPI_DCS_SET_GAMMA_CURVE = 0x26,
MIPI_DCS_SET_DISPLAY_OFF = 0x28,
MIPI_DCS_SET_DISPLAY_ON = 0x29,
MIPI_DCS_SET_COLUMN_ADDRESS = 0x2A,
MIPI_DCS_SET_PAGE_ADDRESS = 0x2B,
MIPI_DCS_WRITE_MEMORY_START = 0x2C,
MIPI_DCS_WRITE_LUT = 0x2D,
MIPI_DCS_READ_MEMORY_START = 0x2E,
MIPI_DCS_SET_PARTIAL_AREA = 0x30,
MIPI_DCS_SET_SCROLL_AREA = 0x33,
MIPI_DCS_SET_TEAR_OFF = 0x34,
MIPI_DCS_SET_TEAR_ON = 0x35,
MIPI_DCS_SET_ADDRESS_MODE = 0x36,
MIPI_DCS_SET_SCROLL_START = 0x37,
MIPI_DCS_EXIT_IDLE_MODE = 0x38,
MIPI_DCS_ENTER_IDLE_MODE = 0x39,
MIPI_DCS_SET_PIXEL_FORMAT = 0x3A,
MIPI_DCS_WRITE_MEMORY_CONTINUE = 0x3C,
MIPI_DCS_READ_MEMORY_CONTINUE = 0x3E,
MIPI_DCS_SET_TEAR_SCANLINE = 0x44,
MIPI_DCS_GET_SCANLINE = 0x45,
MIPI_DCS_SET_DISPLAY_BRIGHTNESS = 0x51, /* MIPI DCS 1.3 */
MIPI_DCS_GET_DISPLAY_BRIGHTNESS = 0x52, /* MIPI DCS 1.3 */
MIPI_DCS_WRITE_CONTROL_DISPLAY = 0x53, /* MIPI DCS 1.3 */
MIPI_DCS_GET_CONTROL_DISPLAY = 0x54, /* MIPI DCS 1.3 */
MIPI_DCS_WRITE_POWER_SAVE = 0x55, /* MIPI DCS 1.3 */
MIPI_DCS_GET_POWER_SAVE = 0x56, /* MIPI DCS 1.3 */
MIPI_DCS_SET_CABC_MIN_BRIGHTNESS = 0x5E, /* MIPI DCS 1.3 */
MIPI_DCS_GET_CABC_MIN_BRIGHTNESS = 0x5F, /* MIPI DCS 1.3 */
MIPI_DCS_READ_DDB_START = 0xA1,
MIPI_DCS_READ_DDB_CONTINUE = 0xA8,
};
/* MIPI DCS pixel formats */
#define MIPI_DCS_PIXEL_FMT_24BIT 7
#define MIPI_DCS_PIXEL_FMT_18BIT 6
#define MIPI_DCS_PIXEL_FMT_16BIT 5
#define MIPI_DCS_PIXEL_FMT_12BIT 3
#define MIPI_DCS_PIXEL_FMT_8BIT 2
#define MIPI_DCS_PIXEL_FMT_3BIT 1
#endif

View File

@@ -7,8 +7,9 @@
#include <Library/TimerLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/errno.h>
#include <Soc.h>
#include "errno.h"
#define __maybe_unused
@@ -21,6 +22,7 @@ typedef UINTN ulong;
typedef INTN ssize_t;
typedef UINTN size_t;
typedef BOOLEAN bool;
typedef UINT16 __be16;
#define true TRUE
#define false FALSE
@@ -35,6 +37,10 @@ typedef BOOLEAN bool;
#define debug(args...) DEBUG ((DEBUG_INFO, args))
#define WARN(x, args...) DEBUG ((DEBUG_WARN, args))
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
#define BIT(x) (1 << (x))
#define BITS_PER_LONG (sizeof(UINTN) * 8)
#define GENMASK(h, l) \
(((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
@@ -51,6 +57,8 @@ typedef BOOLEAN bool;
(typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \
})
#define fls(x) HighBitSet32(x)
#define min(x,y) ({ \
typeof(x) _x = (x); \
typeof(y) _y = (y); \
@@ -66,6 +74,35 @@ typedef BOOLEAN bool;
#define min_t(type, a, b) min(((type) a), ((type) b))
#define max_t(type, a, b) max(((type) a), ((type) b))
#define do_div(n,base) ({ \
uint32_t __base = (base); \
uint32_t __rem; \
__rem = ((uint64_t)(n)) % __base; \
(n) = ((uint64_t)(n)) / __base; \
__rem; \
})
#define DIV_ROUND_CLOSEST(x, divisor) (((x) + ((divisor) / 2)) / (divisor))
#define writel(val, addr) MmioWrite32(addr, val)
#define readl(addr) MmioRead32(addr)
//
// TODO: Actually check for timeout below...
//
#define readx_poll_timeout(op, addr, val, cond, timeout_us) \
({ \
for (;;) { \
(val) = op(addr); \
if (cond) \
break; \
} \
(cond) ? 0 : -ETIMEDOUT; \
})
#define readl_poll_timeout(addr, val, cond, timeout_us) \
readx_poll_timeout(readl, addr, val, cond, timeout_us)
#define regmap_read_poll_timeout(map, addr, val, cond, sleep_us, \
timeout_ms) \
({ \
@@ -133,6 +170,39 @@ static inline u32 get_unaligned_le32(const void *p)
return __get_unaligned_le32((const u8 *)p);
}
static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
{
*remainder = dividend % divisor;
return dividend / divisor;
}
static inline u64 div_u64(u64 dividend, u32 divisor)
{
u32 remainder;
return div_u64_rem(dividend, divisor, &remainder);
}
#define div64_ul(x, y) div_u64((x), (y))
#define abs(x) ({ \
long ret; \
if (sizeof(x) == sizeof(long)) { \
long __x = (x); \
ret = (__x < 0) ? -__x : __x; \
} else { \
int __x = (x); \
ret = (__x < 0) ? -__x : __x; \
} \
ret; \
})
#define uswap_16(x) \
((((x) & 0xff00) >> 8) | \
(((x) & 0x00ff) << 8))
#define cpu_to_be16(x) uswap_16(x)
#define be16_to_cpu(x) uswap_16(x)
#define memcpy(dest, source, count) CopyMem(dest,source, (UINTN)(count))
#define memset(dest, ch, count) SetMem(dest, (UINTN)(count),(UINT8)(ch))
#define memchr(buf, ch, count) ScanMem8(buf, (UINTN)(count),(UINT8)ch)
@@ -145,4 +215,8 @@ static inline u32 get_unaligned_le32(const void *p)
#define strcmp(string1, string2, count) (int)(AsciiStrCmp(string1, string2))
#define strncmp(string1, string2, count) (int)(AsciiStrnCmp(string1, string2, (UINTN)(count)))
#define malloc(sz) AllocatePool(sz)
#define calloc(num, sz) AllocateZeroPool((num) * (sz));
#define free(buf) FreePool(buf)
#endif // _UBOOT_ENV_H

View File

@@ -0,0 +1,50 @@
/** @file
*
* Copyright (c) 2024, Mario Bălănică <mariobalanica02@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*
**/
#ifndef _ROCKCHIP_DSI_PANEL_PROTOCOL_H_
#define _ROCKCHIP_DSI_PANEL_PROTOCOL_H_
#include <Library/RockchipDisplayLib.h>
#include <Library/drm_mipi_dsi.h>
#define ROCKCHIP_DSI_PANEL_PROTOCOL_GUID \
{ 0xb4bcf881, 0xc8b3, 0x46d7, { 0xaf, 0xbe, 0x5a, 0x2d, 0x94, 0x9d, 0x93, 0xc3 } }
typedef struct _ROCKCHIP_DSI_PANEL_PROTOCOL ROCKCHIP_DSI_PANEL_PROTOCOL;
typedef
EFI_STATUS
(EFIAPI *ROCKCHIP_DSI_PANEL_PREPARE)(
IN ROCKCHIP_DSI_PANEL_PROTOCOL *This
);
struct _ROCKCHIP_DSI_PANEL_PROTOCOL {
UINT32 DsiId;
UINT32 DsiLaneRate;
UINT32 DsiLanes;
UINT32 DsiFlags;
UINT32 DsiFormat;
BOOLEAN DscEnable;
BOOLEAN CPhyEnable;
BOOLEAN ScramblingEnable;
UINT32 SliceWidth;
UINT32 SliceHeight;
UINT32 VersionMajor;
UINT32 VersionMinor;
UINT8 *InitSequence;
UINT32 InitSequenceLength;
DISPLAY_MODE NativeMode;
ROCKCHIP_DSI_PANEL_PREPARE Prepare;
};
extern EFI_GUID gRockchipDsiPanelProtocolGuid;
#endif // _ROCKCHIP_DSI_PANEL_PROTOCOL_H_

View File

@@ -24,7 +24,7 @@
#include <Uefi/UefiBaseType.h>
#include "uboot-env.h"
#include <Library/uboot-env.h>
# define DP_MAX_LINK_RATE 0x001
# define DP_MAX_LANE_COUNT 0x002

View File

@@ -32,13 +32,12 @@
#include <Library/DrmModes.h>
#include <Library/MediaBusFormat.h>
#include <Library/DrmModes.h>
#include <Library/uboot-env.h>
#include <Library/drm_dp_helper.h>
#include <Protocol/RockchipConnectorProtocol.h>
#include <Protocol/DpPhy.h>
#include "uboot-env.h"
#include "drm_dp_helper.h"
#define DPTX_VERSION_NUMBER 0x0000
#define DPTX_VERSION_TYPE 0x0004
#define DPTX_ID 0x0008

View File

@@ -25,7 +25,7 @@
#include <Uefi/UefiBaseType.h>
#include "uboot-env.h"
#include <Library/uboot-env.h>
#define HIWORD_UPDATE(val, mask) (val | (mask) << 16)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,53 @@
#/** @file
#
# Synopsys DesignWare MIPI DSI2 controller driver
#
# Copyright (c) 2023-2024, Mario Bălănică <mariobalanica02@gmail.com>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
#**/
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = DwMipiDsi2Lib
FILE_GUID = aa11f6f3-96a8-45f9-b757-47e1c793d409
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = DwMipiDsi2Init
[Sources.common]
DwMipiDsi2Lib.c
drm_dsc.c
drm_mipi_dsi.c
rockchip_phy.c
samsung_mipi_dcphy.c
[LibraryClasses]
UefiDriverEntryPoint
UefiLib
UefiBootServicesTableLib
TimerLib
DebugLib
IoLib
BaseLib
BaseMemoryLib
MemoryAllocationLib
RockchipDisplayLib
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
Silicon/Rockchip/RockchipPkg.dec
Silicon/Rockchip/RK3588/RK3588.dec
[BuildOptions]
[Pcd]
[Protocols]
gRockchipConnectorProtocolGuid ## PRODUCES
gRockchipDsiPanelProtocolGuid ## CONSUMES
[Depex]
TRUE

View File

@@ -18,7 +18,7 @@
#include <Library/PWMLib.h>
#include <Library/DrmModes.h>
#include "uboot-env.h"
#include <Library/uboot-env.h>
#define RO_REF_CLK_SEL GENMASK(11, 10)
#define LC_REF_CLK_SEL GENMASK(9, 8)

View File

@@ -18,7 +18,7 @@
#include <Library/PWMLib.h>
#include <Library/DrmModes.h>
#include "uboot-env.h"
#include <Library/uboot-env.h>
#define UPDATE(x, h, l) (((x) << (l)) & GENMASK((h), (l)))

View File

@@ -75,3 +75,33 @@ DisplaySetCrtcInfo (
return EFI_SUCCESS;
}
UINT32
EFIAPI
DrmModeVRefresh (
DRM_DISPLAY_MODE *Mode
)
{
UINT32 Refresh = 0;
UINT32 CalcVal;
if (Mode->VRefresh > 0) {
Refresh = Mode->VRefresh;
} else if (Mode->HTotal > 0 && Mode->VTotal > 0) {
int VTotal;
VTotal = Mode->VTotal;
/* work out VRefresh the value will be x1000 */
CalcVal = (Mode->Clock * 1000);
CalcVal /= Mode->HTotal;
Refresh = (CalcVal + VTotal / 2) / VTotal;
if (Mode->Flags & DRM_MODE_FLAG_INTERLACE)
Refresh *= 2;
if (Mode->Flags & DRM_MODE_FLAG_DBLSCAN)
Refresh /= 2;
if (Mode->VScan > 1)
Refresh /= Mode->VScan;
}
return Refresh;
}

View File

@@ -21,8 +21,8 @@
* OF THIS SOFTWARE.
*/
#include "uboot-env.h"
#include "drm_dp_helper.h"
#include <Library/uboot-env.h>
#include <Library/drm_dp_helper.h>
/**
* DOC: dp helpers

View File

@@ -0,0 +1,374 @@
// SPDX-License-Identifier: MIT
/*
* Copyright © 2018 Intel Corp
*
* Author:
* Manasi Navare <manasi.d.navare@intel.com>
*/
#include <Library/uboot-env.h>
#include <Library/drm_dp_helper.h>
#include <Library/drm_dsc.h>
/**
* DOC: dsc helpers
*
* VESA specification for DP 1.4 adds a new feature called Display Stream
* Compression (DSC) used to compress the pixel bits before sending it on
* DP/eDP/MIPI DSI interface. DSC is required to be enabled so that the existing
* display interfaces can support high resolutions at higher frames rates using
* the maximum available link capacity of these interfaces.
*
* These functions contain some common logic and helpers to deal with VESA
* Display Stream Compression standard required for DSC on Display Port/eDP or
* MIPI display interfaces.
*/
/**
* drm_dsc_dp_pps_header_init() - Initializes the PPS Header
* for DisplayPort as per the DP 1.4 spec.
* @pps_header: Secondary data packet header for DSC Picture
* Parameter Set as defined in &struct dp_sdp_header
*
* DP 1.4 spec defines the secondary data packet for sending the
* picture parameter infoframes from the source to the sink.
* This function populates the SDP header defined in
* &struct dp_sdp_header.
*/
void drm_dsc_dp_pps_header_init(struct dp_sdp_header *pps_header)
{
memset(pps_header, 0, sizeof(*pps_header));
pps_header->HB1 = DP_SDP_PPS;
pps_header->HB2 = DP_SDP_PPS_HEADER_PAYLOAD_BYTES_MINUS_1;
}
/**
* drm_dsc_pps_payload_pack() - Populates the DSC PPS
*
* @pps_payload:
* Bitwise struct for DSC Picture Parameter Set. This is defined
* by &struct drm_dsc_picture_parameter_set
* @dsc_cfg:
* DSC Configuration data filled by driver as defined by
* &struct drm_dsc_config
*
* DSC source device sends a picture parameter set (PPS) containing the
* information required by the sink to decode the compressed frame. Driver
* populates the DSC PPS struct using the DSC configuration parameters in
* the order expected by the DSC Display Sink device. For the DSC, the sink
* device expects the PPS payload in big endian format for fields
* that span more than 1 byte.
*/
void drm_dsc_pps_payload_pack(struct drm_dsc_picture_parameter_set *pps_payload,
const struct drm_dsc_config *dsc_cfg)
{
int i;
/* Protect against someone accidentally changing struct size */
BUILD_BUG_ON(sizeof(*pps_payload) !=
DP_SDP_PPS_HEADER_PAYLOAD_BYTES_MINUS_1 + 1);
memset(pps_payload, 0, sizeof(*pps_payload));
/* PPS 0 */
pps_payload->dsc_version =
dsc_cfg->dsc_version_minor |
dsc_cfg->dsc_version_major << DSC_PPS_VERSION_MAJOR_SHIFT;
/* PPS 1, 2 is 0 */
/* PPS 3 */
pps_payload->pps_3 =
dsc_cfg->line_buf_depth |
dsc_cfg->bits_per_component << DSC_PPS_BPC_SHIFT;
/* PPS 4 */
pps_payload->pps_4 =
((dsc_cfg->bits_per_pixel & DSC_PPS_BPP_HIGH_MASK) >>
DSC_PPS_MSB_SHIFT) |
dsc_cfg->vbr_enable << DSC_PPS_VBR_EN_SHIFT |
dsc_cfg->simple_422 << DSC_PPS_SIMPLE422_SHIFT |
dsc_cfg->convert_rgb << DSC_PPS_CONVERT_RGB_SHIFT |
dsc_cfg->block_pred_enable << DSC_PPS_BLOCK_PRED_EN_SHIFT;
/* PPS 5 */
pps_payload->bits_per_pixel_low =
(dsc_cfg->bits_per_pixel & DSC_PPS_LSB_MASK);
/*
* The DSC panel expects the PPS packet to have big endian format
* for data spanning 2 bytes. Use a macro cpu_to_be16() to convert
* to big endian format. If format is little endian, it will swap
* bytes to convert to Big endian else keep it unchanged.
*/
/* PPS 6, 7 */
pps_payload->pic_height = cpu_to_be16(dsc_cfg->pic_height);
/* PPS 8, 9 */
pps_payload->pic_width = cpu_to_be16(dsc_cfg->pic_width);
/* PPS 10, 11 */
pps_payload->slice_height = cpu_to_be16(dsc_cfg->slice_height);
/* PPS 12, 13 */
pps_payload->slice_width = cpu_to_be16(dsc_cfg->slice_width);
/* PPS 14, 15 */
pps_payload->chunk_size = cpu_to_be16(dsc_cfg->slice_chunk_size);
/* PPS 16 */
pps_payload->initial_xmit_delay_high =
((dsc_cfg->initial_xmit_delay &
DSC_PPS_INIT_XMIT_DELAY_HIGH_MASK) >>
DSC_PPS_MSB_SHIFT);
/* PPS 17 */
pps_payload->initial_xmit_delay_low =
(dsc_cfg->initial_xmit_delay & DSC_PPS_LSB_MASK);
/* PPS 18, 19 */
pps_payload->initial_dec_delay =
cpu_to_be16(dsc_cfg->initial_dec_delay);
/* PPS 20 is 0 */
/* PPS 21 */
pps_payload->initial_scale_value =
dsc_cfg->initial_scale_value;
/* PPS 22, 23 */
pps_payload->scale_increment_interval =
cpu_to_be16(dsc_cfg->scale_increment_interval);
/* PPS 24 */
pps_payload->scale_decrement_interval_high =
((dsc_cfg->scale_decrement_interval &
DSC_PPS_SCALE_DEC_INT_HIGH_MASK) >>
DSC_PPS_MSB_SHIFT);
/* PPS 25 */
pps_payload->scale_decrement_interval_low =
(dsc_cfg->scale_decrement_interval & DSC_PPS_LSB_MASK);
/* PPS 26[7:0], PPS 27[7:5] RESERVED */
/* PPS 27 */
pps_payload->first_line_bpg_offset =
dsc_cfg->first_line_bpg_offset;
/* PPS 28, 29 */
pps_payload->nfl_bpg_offset =
cpu_to_be16(dsc_cfg->nfl_bpg_offset);
/* PPS 30, 31 */
pps_payload->slice_bpg_offset =
cpu_to_be16(dsc_cfg->slice_bpg_offset);
/* PPS 32, 33 */
pps_payload->initial_offset =
cpu_to_be16(dsc_cfg->initial_offset);
/* PPS 34, 35 */
pps_payload->final_offset = cpu_to_be16(dsc_cfg->final_offset);
/* PPS 36 */
pps_payload->flatness_min_qp = dsc_cfg->flatness_min_qp;
/* PPS 37 */
pps_payload->flatness_max_qp = dsc_cfg->flatness_max_qp;
/* PPS 38, 39 */
pps_payload->rc_model_size =
cpu_to_be16(DSC_RC_MODEL_SIZE_CONST);
/* PPS 40 */
pps_payload->rc_edge_factor = DSC_RC_EDGE_FACTOR_CONST;
/* PPS 41 */
pps_payload->rc_quant_incr_limit0 =
dsc_cfg->rc_quant_incr_limit0;
/* PPS 42 */
pps_payload->rc_quant_incr_limit1 =
dsc_cfg->rc_quant_incr_limit1;
/* PPS 43 */
pps_payload->rc_tgt_offset = DSC_RC_TGT_OFFSET_LO_CONST |
DSC_RC_TGT_OFFSET_HI_CONST << DSC_PPS_RC_TGT_OFFSET_HI_SHIFT;
/* PPS 44 - 57 */
for (i = 0; i < DSC_NUM_BUF_RANGES - 1; i++)
pps_payload->rc_buf_thresh[i] =
dsc_cfg->rc_buf_thresh[i];
/* PPS 58 - 87 */
/*
* For DSC sink programming the RC Range parameter fields
* are as follows: Min_qp[15:11], max_qp[10:6], offset[5:0]
*/
for (i = 0; i < DSC_NUM_BUF_RANGES; i++) {
pps_payload->rc_range_parameters[i] =
cpu_to_be16((dsc_cfg->rc_range_params[i].range_min_qp <<
DSC_PPS_RC_RANGE_MINQP_SHIFT) |
(dsc_cfg->rc_range_params[i].range_max_qp <<
DSC_PPS_RC_RANGE_MAXQP_SHIFT) |
(dsc_cfg->rc_range_params[i].range_bpg_offset));
}
/* PPS 88 */
pps_payload->native_422_420 = dsc_cfg->native_422 |
dsc_cfg->native_420 << DSC_PPS_NATIVE_420_SHIFT;
/* PPS 89 */
pps_payload->second_line_bpg_offset =
dsc_cfg->second_line_bpg_offset;
/* PPS 90, 91 */
pps_payload->nsl_bpg_offset =
cpu_to_be16(dsc_cfg->nsl_bpg_offset);
/* PPS 92, 93 */
pps_payload->second_line_offset_adj =
cpu_to_be16(dsc_cfg->second_line_offset_adj);
/* PPS 94 - 127 are O */
}
/**
* drm_dsc_compute_rc_parameters() - Write rate control
* parameters to the dsc configuration defined in
* &struct drm_dsc_config in accordance with the DSC 1.2
* specification. Some configuration fields must be present
* beforehand.
*
* @vdsc_cfg:
* DSC Configuration data partially filled by driver
*/
int drm_dsc_compute_rc_parameters(struct drm_dsc_config *vdsc_cfg)
{
unsigned long groups_per_line = 0;
unsigned long groups_total = 0;
unsigned long num_extra_mux_bits = 0;
unsigned long slice_bits = 0;
unsigned long hrd_delay = 0;
unsigned long final_scale = 0;
unsigned long rbs_min = 0;
if (vdsc_cfg->native_420 || vdsc_cfg->native_422) {
/* Number of groups used to code each line of a slice */
groups_per_line = DIV_ROUND_UP(vdsc_cfg->slice_width / 2,
DSC_RC_PIXELS_PER_GROUP);
/* chunksize in Bytes */
vdsc_cfg->slice_chunk_size = DIV_ROUND_UP(vdsc_cfg->slice_width / 2 *
vdsc_cfg->bits_per_pixel,
(8 * 16));
} else {
/* Number of groups used to code each line of a slice */
groups_per_line = DIV_ROUND_UP(vdsc_cfg->slice_width,
DSC_RC_PIXELS_PER_GROUP);
/* chunksize in Bytes */
vdsc_cfg->slice_chunk_size = DIV_ROUND_UP(vdsc_cfg->slice_width *
vdsc_cfg->bits_per_pixel,
(8 * 16));
}
if (vdsc_cfg->convert_rgb)
num_extra_mux_bits = 3 * (vdsc_cfg->mux_word_size +
(4 * vdsc_cfg->bits_per_component + 4)
- 2);
else if (vdsc_cfg->native_422)
num_extra_mux_bits = 4 * vdsc_cfg->mux_word_size +
(4 * vdsc_cfg->bits_per_component + 4) +
3 * (4 * vdsc_cfg->bits_per_component) - 2;
else
num_extra_mux_bits = 3 * vdsc_cfg->mux_word_size +
(4 * vdsc_cfg->bits_per_component + 4) +
2 * (4 * vdsc_cfg->bits_per_component) - 2;
/* Number of bits in one Slice */
slice_bits = 8 * vdsc_cfg->slice_chunk_size * vdsc_cfg->slice_height;
while ((num_extra_mux_bits > 0) &&
((slice_bits - num_extra_mux_bits) % vdsc_cfg->mux_word_size))
num_extra_mux_bits--;
if (groups_per_line < vdsc_cfg->initial_scale_value - 8)
vdsc_cfg->initial_scale_value = groups_per_line + 8;
/* scale_decrement_interval calculation according to DSC spec 1.11 */
if (vdsc_cfg->initial_scale_value > 8)
vdsc_cfg->scale_decrement_interval = groups_per_line /
(vdsc_cfg->initial_scale_value - 8);
else
vdsc_cfg->scale_decrement_interval = DSC_SCALE_DECREMENT_INTERVAL_MAX;
vdsc_cfg->final_offset = vdsc_cfg->rc_model_size -
(vdsc_cfg->initial_xmit_delay *
vdsc_cfg->bits_per_pixel + 8) / 16 + num_extra_mux_bits;
if (vdsc_cfg->final_offset >= vdsc_cfg->rc_model_size) {
printf("FinalOfs < RcModelSze for this InitialXmitDelay\n");
return -ERANGE;
}
final_scale = (vdsc_cfg->rc_model_size * 8) /
(vdsc_cfg->rc_model_size - vdsc_cfg->final_offset);
if (vdsc_cfg->slice_height > 1)
/*
* NflBpgOffset is 16 bit value with 11 fractional bits
* hence we multiply by 2^11 for preserving the
* fractional part
*/
vdsc_cfg->nfl_bpg_offset = DIV_ROUND_UP((vdsc_cfg->first_line_bpg_offset << 11),
(vdsc_cfg->slice_height - 1));
else
vdsc_cfg->nfl_bpg_offset = 0;
/* Number of groups used to code the entire slice */
groups_total = groups_per_line * vdsc_cfg->slice_height;
/* slice_bpg_offset is 16 bit value with 11 fractional bits */
vdsc_cfg->slice_bpg_offset = DIV_ROUND_UP(((vdsc_cfg->rc_model_size -
vdsc_cfg->initial_offset +
num_extra_mux_bits) << 11),
groups_total);
if (final_scale > 9) {
/*
* ScaleIncrementInterval =
* finaloffset/((NflBpgOffset + SliceBpgOffset)*8(finalscale - 1.125))
* as (NflBpgOffset + SliceBpgOffset) has 11 bit fractional value,
* we need divide by 2^11 from pstDscCfg values
*/
vdsc_cfg->scale_increment_interval =
(vdsc_cfg->final_offset * (1 << 11)) /
((vdsc_cfg->nfl_bpg_offset +
vdsc_cfg->slice_bpg_offset) *
(final_scale - 9));
} else {
/*
* If finalScaleValue is less than or equal to 9, a value of 0 should
* be used to disable the scale increment at the end of the slice
*/
vdsc_cfg->scale_increment_interval = 0;
}
/*
* DSC spec mentions that bits_per_pixel specifies the target
* bits/pixel (bpp) rate that is used by the encoder,
* in steps of 1/16 of a bit per pixel
*/
rbs_min = vdsc_cfg->rc_model_size - vdsc_cfg->initial_offset +
DIV_ROUND_UP(vdsc_cfg->initial_xmit_delay *
vdsc_cfg->bits_per_pixel, 16) +
groups_per_line * vdsc_cfg->first_line_bpg_offset;
hrd_delay = DIV_ROUND_UP((rbs_min * 16), vdsc_cfg->bits_per_pixel);
vdsc_cfg->rc_bits = (hrd_delay * vdsc_cfg->bits_per_pixel) / 16;
vdsc_cfg->initial_dec_delay = hrd_delay - vdsc_cfg->initial_xmit_delay;
return 0;
}

View File

@@ -0,0 +1,791 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* MIPI DSI Bus
*
* Copyright (C) 2012-2013, Samsung Electronics, Co., Ltd.
* Andrzej Hajda <a.hajda@samsung.com>
*/
#include <Library/uboot-env.h>
#include <Library/drm_mipi_dsi.h>
/**
* mipi_dsi_attach - attach a DSI device to its DSI host
* @dsi: DSI peripheral
*/
int mipi_dsi_attach(struct mipi_dsi_device *dsi)
{
const struct mipi_dsi_host_ops *ops = dsi->host->ops;
if (!ops || !ops->attach)
return -ENOSYS;
return ops->attach(dsi->host, dsi);
}
/**
* mipi_dsi_detach - detach a DSI device from its DSI host
* @dsi: DSI peripheral
*/
int mipi_dsi_detach(struct mipi_dsi_device *dsi)
{
const struct mipi_dsi_host_ops *ops = dsi->host->ops;
if (!ops || !ops->detach)
return -ENOSYS;
return ops->detach(dsi->host, dsi);
}
static ssize_t mipi_dsi_device_transfer(struct mipi_dsi_device *dsi,
struct mipi_dsi_msg *msg)
{
const struct mipi_dsi_host_ops *ops = dsi->host->ops;
if (!ops || !ops->transfer)
return -ENOSYS;
if (dsi->mode_flags & MIPI_DSI_MODE_LPM)
msg->flags |= MIPI_DSI_MSG_USE_LPM;
return ops->transfer(dsi->host, msg);
}
/**
* mipi_dsi_packet_format_is_short - check if a packet is of the short format
* @type: MIPI DSI data type of the packet
*
* Return: true if the packet for the given data type is a short packet, false
* otherwise.
*/
bool mipi_dsi_packet_format_is_short(u8 type)
{
switch (type) {
case MIPI_DSI_V_SYNC_START:
case MIPI_DSI_V_SYNC_END:
case MIPI_DSI_H_SYNC_START:
case MIPI_DSI_H_SYNC_END:
case MIPI_DSI_COMPRESSION_MODE:
case MIPI_DSI_END_OF_TRANSMISSION:
case MIPI_DSI_COLOR_MODE_OFF:
case MIPI_DSI_COLOR_MODE_ON:
case MIPI_DSI_SHUTDOWN_PERIPHERAL:
case MIPI_DSI_TURN_ON_PERIPHERAL:
case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
case MIPI_DSI_DCS_SHORT_WRITE:
case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
case MIPI_DSI_DCS_READ:
case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
return true;
}
return false;
}
/**
* mipi_dsi_packet_format_is_long - check if a packet is of the long format
* @type: MIPI DSI data type of the packet
*
* Return: true if the packet for the given data type is a long packet, false
* otherwise.
*/
bool mipi_dsi_packet_format_is_long(u8 type)
{
switch (type) {
case MIPI_DSI_NULL_PACKET:
case MIPI_DSI_BLANKING_PACKET:
case MIPI_DSI_GENERIC_LONG_WRITE:
case MIPI_DSI_DCS_LONG_WRITE:
case MIPI_DSI_PICTURE_PARAMETER_SET:
case MIPI_DSI_COMPRESSED_PIXEL_STREAM:
case MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20:
case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24:
case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16:
case MIPI_DSI_PACKED_PIXEL_STREAM_30:
case MIPI_DSI_PACKED_PIXEL_STREAM_36:
case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12:
case MIPI_DSI_PACKED_PIXEL_STREAM_16:
case MIPI_DSI_PACKED_PIXEL_STREAM_18:
case MIPI_DSI_PIXEL_STREAM_3BYTE_18:
case MIPI_DSI_PACKED_PIXEL_STREAM_24:
return true;
}
return false;
}
/**
* mipi_dsi_create_packet - create a packet from a message according to the
* DSI protocol
* @packet: pointer to a DSI packet structure
* @msg: message to translate into a packet
*
* Return: 0 on success or a negative error code on failure.
*/
int mipi_dsi_create_packet(struct mipi_dsi_packet *packet,
const struct mipi_dsi_msg *msg)
{
if (!packet || !msg)
return -EINVAL;
/* do some minimum sanity checking */
if (!mipi_dsi_packet_format_is_short(msg->type) &&
!mipi_dsi_packet_format_is_long(msg->type))
return -EINVAL;
if (msg->channel > 3)
return -EINVAL;
memset(packet, 0, sizeof(*packet));
packet->header[0] = ((msg->channel & 0x3) << 6) | (msg->type & 0x3f);
if (mipi_dsi_packet_format_is_long(msg->type)) {
packet->header[1] = (msg->tx_len >> 0) & 0xff;
packet->header[2] = (msg->tx_len >> 8) & 0xff;
packet->payload_length = msg->tx_len;
packet->payload = msg->tx_buf;
} else {
const u8 *tx = msg->tx_buf;
packet->header[1] = (msg->tx_len > 0) ? tx[0] : 0;
packet->header[2] = (msg->tx_len > 1) ? tx[1] : 0;
}
packet->size = sizeof(packet->header) + packet->payload_length;
return 0;
}
/**
* mipi_dsi_shutdown_peripheral() - sends a Shutdown Peripheral command
* @dsi: DSI peripheral device
*
* Return: 0 on success or a negative error code on failure.
*/
int mipi_dsi_shutdown_peripheral(struct mipi_dsi_device *dsi)
{
struct mipi_dsi_msg msg = {
.channel = dsi->channel,
.type = MIPI_DSI_SHUTDOWN_PERIPHERAL,
.tx_buf = (u8 [2]) { 0, 0 },
.tx_len = 2,
};
int ret = mipi_dsi_device_transfer(dsi, &msg);
return (ret < 0) ? ret : 0;
}
/**
* mipi_dsi_turn_on_peripheral() - sends a Turn On Peripheral command
* @dsi: DSI peripheral device
*
* Return: 0 on success or a negative error code on failure.
*/
int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi)
{
struct mipi_dsi_msg msg = {
.channel = dsi->channel,
.type = MIPI_DSI_TURN_ON_PERIPHERAL,
.tx_buf = (u8 [2]) { 0, 0 },
.tx_len = 2,
};
int ret = mipi_dsi_device_transfer(dsi, &msg);
return (ret < 0) ? ret : 0;
}
/*
* mipi_dsi_set_maximum_return_packet_size() - specify the maximum size of the
* the payload in a long packet transmitted from the peripheral back to the
* host processor
* @dsi: DSI peripheral device
* @value: the maximum size of the payload
*
* Return: 0 on success or a negative error code on failure.
*/
int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi,
u16 value)
{
u8 tx[2] = { value & 0xff, value >> 8 };
struct mipi_dsi_msg msg = {
.channel = dsi->channel,
.type = MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE,
.tx_len = sizeof(tx),
.tx_buf = tx,
};
int ret = mipi_dsi_device_transfer(dsi, &msg);
return (ret < 0) ? ret : 0;
}
/**
* mipi_dsi_compression_mode() - enable/disable DSC on the peripheral
* @dsi: DSI peripheral device
* @enable: Whether to enable or disable the DSC
*
* Enable or disable Display Stream Compression on the peripheral using the
* default Picture Parameter Set and VESA DSC 1.1 algorithm.
*
* Return: 0 on success or a negative error code on failure.
*/
ssize_t mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable)
{
/* Note: Needs updating for non-default PPS or algorithm */
u8 tx[2] = { enable << 0, 0 };
struct mipi_dsi_msg msg = {
.channel = dsi->channel,
.type = MIPI_DSI_COMPRESSION_MODE,
.tx_len = sizeof(tx),
.tx_buf = tx,
};
int ret = mipi_dsi_device_transfer(dsi, &msg);
return (ret < 0) ? ret : 0;
}
/**
* mipi_dsi_picture_parameter_set() - transmit the DSC PPS to the peripheral
* @dsi: DSI peripheral device
* @pps: VESA DSC 1.1 Picture Parameter Set
*
* Transmit the VESA DSC 1.1 Picture Parameter Set to the peripheral.
*
* Return: 0 on success or a negative error code on failure.
*/
ssize_t mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi,
const struct drm_dsc_picture_parameter_set *pps)
{
struct mipi_dsi_msg msg = {
.channel = dsi->channel,
.type = MIPI_DSI_PICTURE_PARAMETER_SET,
.tx_len = sizeof(*pps),
.tx_buf = pps,
};
int ret = mipi_dsi_device_transfer(dsi, &msg);
return (ret < 0) ? ret : 0;
}
/**
* mipi_dsi_generic_write() - transmit data using a generic write packet
* @dsi: DSI peripheral device
* @payload: buffer containing the payload
* @size: size of payload buffer
*
* This function will automatically choose the right data type depending on
* the payload length.
*
* Return: The number of bytes transmitted on success or a negative error code
* on failure.
*/
ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload,
size_t size)
{
struct mipi_dsi_msg msg = {
.channel = dsi->channel,
.tx_buf = payload,
.tx_len = size
};
switch (size) {
case 0:
msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM;
break;
case 1:
msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM;
break;
case 2:
msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM;
break;
default:
msg.type = MIPI_DSI_GENERIC_LONG_WRITE;
break;
}
return mipi_dsi_device_transfer(dsi, &msg);
}
/**
* mipi_dsi_generic_read() - receive data using a generic read packet
* @dsi: DSI peripheral device
* @params: buffer containing the request parameters
* @num_params: number of request parameters
* @data: buffer in which to return the received data
* @size: size of receive buffer
*
* This function will automatically choose the right data type depending on
* the number of parameters passed in.
*
* Return: The number of bytes successfully read or a negative error code on
* failure.
*/
ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
size_t num_params, void *data, size_t size)
{
struct mipi_dsi_msg msg = {
.channel = dsi->channel,
.tx_len = num_params,
.tx_buf = params,
.rx_len = size,
.rx_buf = data
};
switch (num_params) {
case 0:
msg.type = MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM;
break;
case 1:
msg.type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM;
break;
case 2:
msg.type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM;
break;
default:
return -EINVAL;
}
return mipi_dsi_device_transfer(dsi, &msg);
}
/**
* mipi_dsi_dcs_write_buffer() - transmit a DCS command with payload
* @dsi: DSI peripheral device
* @data: buffer containing data to be transmitted
* @len: size of transmission buffer
*
* This function will automatically choose the right data type depending on
* the command payload length.
*
* Return: The number of bytes successfully transmitted or a negative error
* code on failure.
*/
ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi,
const void *data, size_t len)
{
struct mipi_dsi_msg msg = {
.channel = dsi->channel,
.tx_buf = data,
.tx_len = len
};
switch (len) {
case 0:
return -EINVAL;
case 1:
msg.type = MIPI_DSI_DCS_SHORT_WRITE;
break;
case 2:
msg.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM;
break;
default:
msg.type = MIPI_DSI_DCS_LONG_WRITE;
break;
}
return mipi_dsi_device_transfer(dsi, &msg);
}
/**
* mipi_dsi_dcs_write() - send DCS write command
* @dsi: DSI peripheral device
* @cmd: DCS command
* @data: buffer containing the command payload
* @len: command payload length
*
* This function will automatically choose the right data type depending on
* the command payload length.
*
* Return: The number of bytes successfully transmitted or a negative error
* code on failure.
*/
ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd,
const void *data, size_t len)
{
ssize_t err;
size_t size;
u8 *tx;
if (len > 0) {
size = 1 + len;
tx = malloc(size);
if (!tx)
return -ENOMEM;
/* concatenate the DCS command byte and the payload */
tx[0] = cmd;
memcpy(&tx[1], data, len);
} else {
tx = &cmd;
size = 1;
}
err = mipi_dsi_dcs_write_buffer(dsi, tx, size);
if (len > 0)
free(tx);
return err;
}
/**
* mipi_dsi_dcs_read() - send DCS read request command
* @dsi: DSI peripheral device
* @cmd: DCS command
* @data: buffer in which to receive data
* @len: size of receive buffer
* Return: The number of bytes read or a negative error code on failure.
*/
ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data,
size_t len)
{
struct mipi_dsi_msg msg = {
.channel = dsi->channel,
.type = MIPI_DSI_DCS_READ,
.tx_buf = &cmd,
.tx_len = 1,
.rx_buf = data,
.rx_len = len
};
return mipi_dsi_device_transfer(dsi, &msg);
}
/**
* mipi_dsi_dcs_nop() - send DCS nop packet
* @dsi: DSI peripheral device
*
* Return: 0 on success or a negative error code on failure.
*/
int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi)
{
ssize_t err;
err = mipi_dsi_dcs_write(dsi, MIPI_DCS_NOP, NULL, 0);
if (err < 0)
return err;
return 0;
}
/**
* mipi_dsi_dcs_soft_reset() - perform a software reset of the display module
* @dsi: DSI peripheral device
*
* Return: 0 on success or a negative error code on failure.
*/
int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi)
{
ssize_t err;
err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SOFT_RESET, NULL, 0);
if (err < 0)
return err;
return 0;
}
/**
* mipi_dsi_dcs_get_power_mode() - query the display module's current power
* mode
* @dsi: DSI peripheral device
* @mode: return location for the current power mode
*
* Return: 0 on success or a negative error code on failure.
*/
int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode)
{
ssize_t err;
err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_POWER_MODE, mode,
sizeof(*mode));
if (err <= 0) {
if (err == 0)
err = -ENODATA;
return err;
}
return 0;
}
/**
* mipi_dsi_dcs_get_pixel_format() - gets the pixel format for the RGB image
* data used by the interface
* @dsi: DSI peripheral device
* @format: return location for the pixel format
*
* Return: 0 on success or a negative error code on failure.
*/
int mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device *dsi, u8 *format)
{
ssize_t err;
err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_PIXEL_FORMAT, format,
sizeof(*format));
if (err <= 0) {
if (err == 0)
err = -ENODATA;
return err;
}
return 0;
}
/**
* mipi_dsi_dcs_enter_sleep_mode() - disable all unnecessary blocks inside the
* display module except interface communication
* @dsi: DSI peripheral device
*
* Return: 0 on success or a negative error code on failure.
*/
int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi)
{
ssize_t err;
err = mipi_dsi_dcs_write(dsi, MIPI_DCS_ENTER_SLEEP_MODE, NULL, 0);
if (err < 0)
return err;
return 0;
}
/**
* mipi_dsi_dcs_exit_sleep_mode() - enable all blocks inside the display
* module
* @dsi: DSI peripheral device
*
* Return: 0 on success or a negative error code on failure.
*/
int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi)
{
ssize_t err;
err = mipi_dsi_dcs_write(dsi, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0);
if (err < 0)
return err;
return 0;
}
/**
* mipi_dsi_dcs_set_display_off() - stop displaying the image data on the
* display device
* @dsi: DSI peripheral device
*
* Return: 0 on success or a negative error code on failure.
*/
int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi)
{
ssize_t err;
err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0);
if (err < 0)
return err;
return 0;
}
/**
* mipi_dsi_dcs_set_display_on() - start displaying the image data on the
* display device
* @dsi: DSI peripheral device
*
* Return: 0 on success or a negative error code on failure
*/
int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi)
{
ssize_t err;
err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_ON, NULL, 0);
if (err < 0)
return err;
return 0;
}
/**
* mipi_dsi_dcs_set_column_address() - define the column extent of the frame
* memory accessed by the host processor
* @dsi: DSI peripheral device
* @start: first column of frame memory
* @end: last column of frame memory
*
* Return: 0 on success or a negative error code on failure.
*/
int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start,
u16 end)
{
u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff };
ssize_t err;
err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_COLUMN_ADDRESS, payload,
sizeof(payload));
if (err < 0)
return err;
return 0;
}
/**
* mipi_dsi_dcs_set_page_address() - define the page extent of the frame
* memory accessed by the host processor
* @dsi: DSI peripheral device
* @start: first page of frame memory
* @end: last page of frame memory
*
* Return: 0 on success or a negative error code on failure.
*/
int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start,
u16 end)
{
u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff };
ssize_t err;
err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PAGE_ADDRESS, payload,
sizeof(payload));
if (err < 0)
return err;
return 0;
}
/**
* mipi_dsi_dcs_set_tear_off() - turn off the display module's Tearing Effect
* output signal on the TE signal line
* @dsi: DSI peripheral device
*
* Return: 0 on success or a negative error code on failure
*/
int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi)
{
ssize_t err;
err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_OFF, NULL, 0);
if (err < 0)
return err;
return 0;
}
/**
* mipi_dsi_dcs_set_tear_on() - turn on the display module's Tearing Effect
* output signal on the TE signal line.
* @dsi: DSI peripheral device
* @mode: the Tearing Effect Output Line mode
*
* Return: 0 on success or a negative error code on failure
*/
int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi,
enum mipi_dsi_dcs_tear_mode mode)
{
u8 value = mode;
ssize_t err;
err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_ON, &value,
sizeof(value));
if (err < 0)
return err;
return 0;
}
/**
* mipi_dsi_dcs_set_pixel_format() - sets the pixel format for the RGB image
* data used by the interface
* @dsi: DSI peripheral device
* @format: pixel format
*
* Return: 0 on success or a negative error code on failure.
*/
int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format)
{
ssize_t err;
err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PIXEL_FORMAT, &format,
sizeof(format));
if (err < 0)
return err;
return 0;
}
/**
* mipi_dsi_dcs_set_tear_scanline() - set the scanline to use as trigger for
* the Tearing Effect output signal of the display module
* @dsi: DSI peripheral device
* @scanline: scanline to use as trigger
*
* Return: 0 on success or a negative error code on failure
*/
int mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device *dsi, u16 scanline)
{
u8 payload[3] = { MIPI_DCS_SET_TEAR_SCANLINE, scanline >> 8,
scanline & 0xff };
ssize_t err;
err = mipi_dsi_generic_write(dsi, payload, sizeof(payload));
if (err < 0)
return err;
return 0;
}
/**
* mipi_dsi_dcs_set_display_brightness() - sets the brightness value of the
* display
* @dsi: DSI peripheral device
* @brightness: brightness value
*
* Return: 0 on success or a negative error code on failure.
*/
int mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device *dsi,
u16 brightness)
{
u8 payload[2] = { brightness & 0xff, brightness >> 8 };
ssize_t err;
err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
payload, sizeof(payload));
if (err < 0)
return err;
return 0;
}
/**
* mipi_dsi_dcs_get_display_brightness() - gets the current brightness value
* of the display
* @dsi: DSI peripheral device
* @brightness: brightness value
*
* Return: 0 on success or a negative error code on failure.
*/
int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi,
u16 *brightness)
{
ssize_t err;
err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS,
brightness, sizeof(*brightness));
if (err <= 0) {
if (err == 0)
err = -ENODATA;
return err;
}
return 0;
}

View File

@@ -0,0 +1,86 @@
/*
* (C) Copyright 2008-2017 Fuzhou Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <Library/uboot-env.h>
#include "rockchip_phy.h"
int rockchip_phy_init(struct rockchip_phy *phy)
{
if (!phy)
return -ENODEV;
if (phy->funcs && phy->funcs->init)
return phy->funcs->init(phy);
return 0;
}
int rockchip_phy_power_on(struct rockchip_phy *phy)
{
if (!phy)
return -ENODEV;
if (phy->funcs && phy->funcs->power_on)
return phy->funcs->power_on(phy);
return 0;
}
int rockchip_phy_power_off(struct rockchip_phy *phy)
{
if (!phy)
return -ENODEV;
if (phy->funcs && phy->funcs->power_off)
return phy->funcs->power_off(phy);
return 0;
}
unsigned long rockchip_phy_set_pll(struct rockchip_phy *phy,
unsigned long rate)
{
if (!phy)
return -ENODEV;
if (phy->funcs && phy->funcs->set_pll)
return phy->funcs->set_pll(phy, rate);
return 0;
}
int rockchip_phy_set_bus_width(struct rockchip_phy *phy, u32 bus_width)
{
if (!phy)
return -ENODEV;
if (phy->funcs && phy->funcs->set_bus_width)
return phy->funcs->set_bus_width(phy, bus_width);
return 0;
}
long rockchip_phy_round_rate(struct rockchip_phy *phy, unsigned long rate)
{
if (!phy)
return -ENODEV;
if (phy->funcs && phy->funcs->round_rate)
return phy->funcs->round_rate(phy, rate);
return 0;
}
int rockchip_phy_set_mode(struct rockchip_phy *phy, enum phy_mode mode)
{
if (!phy)
return -ENODEV;
if (phy->funcs && phy->funcs->set_mode)
return phy->funcs->set_mode(phy, mode);
return 0;
}

View File

@@ -0,0 +1,44 @@
/*
* (C) Copyright 2008-2017 Fuzhou Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _ROCKCHIP_PHY_H_
#define _ROCKCHIP_PHY_H_
enum phy_mode {
PHY_MODE_INVALID,
PHY_MODE_MIPI_DPHY,
PHY_MODE_VIDEO_LVDS,
PHY_MODE_VIDEO_TTL,
};
struct rockchip_phy;
struct rockchip_phy_funcs {
int (*init)(struct rockchip_phy *phy);
int (*power_on)(struct rockchip_phy *phy);
int (*power_off)(struct rockchip_phy *phy);
unsigned long (*set_pll)(struct rockchip_phy *phy, unsigned long rate);
int (*set_bus_width)(struct rockchip_phy *phy, u32 bus_width);
long (*round_rate)(struct rockchip_phy *phy, unsigned long rate);
int (*set_mode)(struct rockchip_phy *phy, enum phy_mode mode);
};
struct rockchip_phy {
const struct rockchip_phy_funcs *funcs;
};
int rockchip_phy_init(struct rockchip_phy *phy);
int rockchip_phy_power_off(struct rockchip_phy *phy);
int rockchip_phy_power_on(struct rockchip_phy *phy);
unsigned long rockchip_phy_set_pll(struct rockchip_phy *phy,
unsigned long rate);
int rockchip_phy_set_bus_width(struct rockchip_phy *phy, u32 bus_width);
long rockchip_phy_round_rate(struct rockchip_phy *phy, unsigned long rate);
int rockchip_phy_set_mode(struct rockchip_phy *phy, enum phy_mode mode);
struct rockchip_phy *rockchip_phy_by_id(unsigned int id);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -451,6 +451,7 @@ struct PMU1CRU_REG {
#define PHPTOPCRU_BASE 0xFD7C8000U /* PHPTOPCRU base address */
#define PMU1CRU_BASE 0xFD7F0000U /* PMU1CRU base address */
#define UART0_BASE 0xFD890000U /* UART0 base address */
#define SYS_PMU_BASE 0xFD8D8000U /* SYS_PMU base address */
#define WDTPMU_BASE 0xFD8E0000U /* WDTPMU base address */
#define TIMERPMU_BASE 0xFD8F0000U /* TIMERPMU base address */
#define WDTNPU_BASE 0xFDAF8000U /* WDTNPU base address */

View File

@@ -13,6 +13,7 @@
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/GpioLib.h>
#include <Library/IoLib.h>
#include <Library/RockchipPlatformLib.h>
#include <Protocol/ArmScmiClockProtocol.h>
@@ -45,6 +46,11 @@ RkSdmmcSetIoMux (
VOID
)
{
#define SYS_GRF_SOC_CON6 (0xFD58C000 + 0x0318)
// Clear force_jtag (SD slot is muxed with JTAG)
MmioWrite32(SYS_GRF_SOC_CON6, 0x40000000);
GpioPinSetDirection (0, GPIO_PIN_PA4, GPIO_PIN_INPUT);
SdmmcIoMux ();
}

View File

@@ -29,4 +29,5 @@
DebugLib
UefiBootServicesTableLib
GpioLib
IoLib
RockchipPlatformLib

View File

@@ -79,6 +79,9 @@
!ifndef RK_AHCI_ENABLE
DEFINE RK_AHCI_ENABLE = TRUE
!endif
!ifndef RK_DW_HDMI_QP_ENABLE
DEFINE RK_DW_HDMI_QP_ENABLE = TRUE
!endif
#
# RK3588-specific flags
@@ -266,8 +269,8 @@
#
# Display
#
gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|0x780
gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|0x438
gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|0
gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|0
gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|0
gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|0

View File

@@ -620,8 +620,11 @@ FspiLib|Silicon/Rockchip/Library/FspiLib/FspiLib.inf
#
Silicon/Rockchip/Drivers/Vop2Dxe/Vop2Dxe.inf
# Silicon/Rockchip/Library/DisplayLib/AnalogixDpLib.inf
!if $(RK_DW_HDMI_QP_ENABLE) == TRUE
Silicon/Rockchip/Library/DisplayLib/DwHdmiQpLib.inf
!endif
Silicon/Rockchip/Library/DisplayLib/DwDpLib.inf
Silicon/Rockchip/Library/DisplayLib/DwMipiDsi2Lib.inf
Silicon/Rockchip/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.inf
#

View File

@@ -27,6 +27,7 @@
gRockchipPlatformConfigAppliedProtocolGuid = { 0xdf0e9b10, 0xcbd6, 0x496f, { 0x83, 0xd6, 0xef, 0xbb, 0x96, 0x9c, 0xe5, 0x3d } }
gDpPhyProtocolGuid = { 0xb4bcf881, 0xc8b3, 0x46d7, { 0xaf, 0xbe, 0x5a, 0x2d, 0x94, 0x9d, 0x93, 0xc3 } }
gPca95xxProtocolGuid = { 0x7e91391b, 0xa23c, 0x4a51, { 0x9d, 0xf7, 0xf6, 0x74, 0xef, 0x1d, 0x51, 0x1b } }
gRockchipDsiPanelProtocolGuid = { 0x07a5d05c, 0x3216, 0x49fc, { 0xb4, 0x22, 0x28, 0x9d, 0x38, 0xd5, 0xdf, 0x7e } }
[Guids]
gRockchipTokenSpaceGuid = { 0xc620b83a, 0x3175, 0x11ec, { 0x95, 0xb4, 0xf4, 0x2a, 0x7d, 0xcb, 0x92, 0x5d } }
@@ -61,6 +62,7 @@
gRockchipTokenSpaceGuid.PcdRtc8563Bus|0|UINT8|0x0200000E
gRockchipTokenSpaceGuid.PcdRkSdmmcBaseAddress|0x0|UINT32|0x40000030
gRockchipTokenSpaceGuid.PcdRkSdmmcCardDetectInverted|FALSE|BOOLEAN|0x40000031
gRockchipTokenSpaceGuid.PcdDwcSdhciBaseAddress|0x0|UINT32|0x40000035
gRockchipTokenSpaceGuid.PcdDwcSdhciForceHighSpeed|FALSE|BOOLEAN|0x40000036