1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081 |
- /*++
- Copyright (c) 2014 Minoca Corp.
- This file is licensed under the terms of the GNU General Public License
- version 3. Alternative licensing terms are available. Contact
- info@minocacorp.com for details. See the LICENSE file at the root of this
- project for complete licensing information.
- Module Name:
- video.c
- Abstract:
- This module implements support for the BCM2709 SoC Family display
- controller.
- Author:
- Chris Stevens 21-Dec-2014
- Environment:
- Firmware
- --*/
- //
- // ------------------------------------------------------------------- Includes
- //
- #include <uefifw.h>
- #include <dev/bcm2709.h>
- #include <minoca/uefi/protocol/graphout.h>
- //
- // --------------------------------------------------------------------- Macros
- //
- //
- // ---------------------------------------------------------------- Definitions
- //
- #define EFI_BCM2709_VIDEO_DEVICE_GUID \
- { \
- 0x87FC0212, 0x9519, 0x11E4, \
- {0x92, 0x76, 0x04, 0x01, 0x0F, 0xDD, 0x74, 0x01} \
- }
- #define EFI_BCM2709_VIDEO_DEVICE_MAGIC 0x64695642 // 'diVB'
- #define EFI_BCM2709_VIDEO_MODE_ARRAY_LENGTH \
- (sizeof(EfiBcm2709VideoModes) / sizeof(EfiBcm2709VideoModes[0]))
- //
- // ------------------------------------------------------ Data Type Definitions
- //
- /*++
- Structure Description:
- This structure defines the data necessary to get the current mode.
- Members:
- Header - Stores a header that defines the total size of the messages being
- received from the mailbox.
- PhysicalResolution - Stores a request for the physical resolution when sent
- to the mailbox and receives the current physical resolution on return.
- EndTag - Stores the tag to denote the end of the mailbox message.
- --*/
- typedef struct _EFI_BCM2709_VIDEO_GET_MODE {
- BCM2709_MAILBOX_HEADER Header;
- BCM2709_MAILBOX_RESOLUTION PhysicalResolution;
- UINT32 EndTag;
- } EFI_BCM2709_VIDEO_GET_MODE, *PEFI_BCM2709_VIDEO_GET_MODE;
- /*++
- Structure Description:
- This structure defines the data necessary to initialize video and get a
- frame buffer.
- Members:
- Header - Stores a header that defines the total size of the messages being
- sent to and received from the mailbox.
- PhysicalResolution - Stores a request to set the physical resolution and
- receives the current physical resolution.
- VirtualResolution - Stores a request to set the virtual resolution and
- receives the current virtual resolution.
- BitsPerPixel - Stores a request to set the bits per pixel and receives the
- current bits per pixel.
- PixelOrder - Stores a request to set the pixel order and receives the
- current pixel order.
- AlphaMode - Stores a request to set the alpha mode.
- VirtualOffset - Stores a request to set the virtual offset.
- Overscan - Stores a request to set the screen's overscan.
- Pitch - Stores a request to get the pitch information.
- FrameBuffer - Stores a request to get the frame buffer.
- EndTag - Stores the tag to denote the end of the mailbox message.
- --*/
- typedef struct _EFI_BCM2709_VIDEO_INITIALIZE {
- BCM2709_MAILBOX_HEADER Header;
- BCM2709_MAILBOX_RESOLUTION PhysicalResolution;
- BCM2709_MAILBOX_RESOLUTION VirtualResolution;
- BCM2709_MAILBOX_BITS_PER_PIXEL BitsPerPixelMessage;
- BCM2709_MAILBOX_PIXEL_ORDER PixelOrderMessage;
- BCM2709_MAILBOX_ALPHA_MODE AlphaModeMessage;
- BCM2709_MAILBOX_VIRTUAL_OFFSET VirtualOffset;
- BCM2709_MAILBOX_OVERSCAN OverscanMessage;
- BCM2709_MAILBOX_PITCH Pitch;
- BCM2709_MAILBOX_FRAME_BUFFER FrameBufferMessage;
- UINT32 EndTag;
- } EFI_BCM2709_VIDEO_INITIALIZE, *PEFI_BCM2709_VIDEO_INITIALIZE;
- /*++
- Structure Description:
- This structure stores the structure of an BCM2709 video device path.
- Members:
- VendorPath - Stores the vendor path portion of the device path.
- End - Stores the end device path node.
- --*/
- typedef struct _EFI_BCM2709_VIDEO_DEVICE_PATH {
- VENDOR_DEVICE_PATH VendorPath;
- EFI_DEVICE_PATH_PROTOCOL End;
- } EFI_BCM2709_VIDEO_DEVICE_PATH, *PEFI_BCM2709_VIDEO_DEVICE_PATH;
- /*++
- Structure Description:
- This structure stores the internal context for an BCM2709 video device.
- Members:
- Magic - Stores the constant magic value EFI_BCM2709_VIDEO_DEVICE_MAGIC.
- Handle - Stores the graphics out handle.
- GraphicsOut - Stores the graphics output protocol.
- GraphicsOutMode - Stores the graphics output protocol mode.
- --*/
- typedef struct _EFI_BCM2709_VIDEO_DEVICE {
- UINT32 Magic;
- EFI_HANDLE Handle;
- EFI_GRAPHICS_OUTPUT_PROTOCOL GraphicsOut;
- EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE GraphicsOutMode;
- } EFI_BCM2709_VIDEO_DEVICE, *PEFI_BCM2709_VIDEO_DEVICE;
- //
- // ----------------------------------------------- Internal Function Prototypes
- //
- EFIAPI
- EFI_STATUS
- EfipBcm2709GraphicsQueryMode (
- EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
- UINT32 ModeNumber,
- UINTN *SizeOfInfo,
- EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
- );
- EFIAPI
- EFI_STATUS
- EfipBcm2709GraphicsSetMode (
- EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
- UINT32 ModeNumber
- );
- EFIAPI
- EFI_STATUS
- EfipBcm2709GraphicsBlt (
- EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer,
- EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
- UINTN SourceX,
- UINTN SourceY,
- UINTN DestinationX,
- UINTN DestinationY,
- UINTN Width,
- UINTN Height,
- UINTN Delta
- );
- EFI_STATUS
- EfipBcm2709VideoInitialize (
- EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Mode,
- EFI_PHYSICAL_ADDRESS *FrameBufferBase,
- UINTN *FrameBufferSize
- );
- VOID
- EfipBcm2709VideoInitializeModes (
- VOID
- );
- //
- // -------------------------------------------------------------------- Globals
- //
- //
- // Define a template for the call to get the video mode.
- //
- EFI_BCM2709_VIDEO_GET_MODE EfiBcm2709GetModeTemplate = {
- {
- sizeof(EFI_BCM2709_VIDEO_GET_MODE),
- 0
- },
- {
- {
- BCM2709_MAILBOX_TAG_GET_PHYSICAL_RESOLUTION,
- sizeof(BCM2709_RESOLUTION),
- 0
- },
- {
- 0,
- 0
- }
- },
- 0
- };
- //
- // Define a template for the call to initialize the video core and get a frame
- // buffer.
- //
- EFI_BCM2709_VIDEO_INITIALIZE EfiBcm2709InitializeVideoTemplate = {
- {
- sizeof(EFI_BCM2709_VIDEO_INITIALIZE),
- 0
- },
- {
- {
- BCM2709_MAILBOX_TAG_SET_PHYSICAL_RESOLUTION,
- sizeof(BCM2709_RESOLUTION),
- sizeof(BCM2709_RESOLUTION)
- },
- {
- 0,
- 0
- }
- },
- {
- {
- BCM2709_MAILBOX_TAG_SET_VIRTUAL_RESOLUTION,
- sizeof(BCM2709_RESOLUTION),
- sizeof(BCM2709_RESOLUTION)
- },
- {
- 0,
- 0
- }
- },
- {
- {
- BCM2709_MAILBOX_TAG_SET_BITS_PER_PIXEL,
- sizeof(UINT32),
- sizeof(UINT32)
- },
- BCM2709_DEFAULT_BITS_PER_PIXEL
- },
- {
- {
- BCM2709_MAILBOX_TAG_SET_PIXEL_ORDER,
- sizeof(UINT32),
- sizeof(UINT32)
- },
- BCM2709_MAILBOX_PIXEL_ORDER_BGR
- },
- {
- {
- BCM2709_MAILBOX_TAG_SET_ALPHA_MODE,
- sizeof(UINT32),
- sizeof(UINT32)
- },
- BCM2709_MAILBOX_ALPHA_MODE_IGNORED
- },
- {
- {
- BCM2709_MAILBOX_TAG_SET_VIRTUAL_OFFSET,
- sizeof(BCM2709_OFFSET),
- sizeof(BCM2709_OFFSET)
- },
- {
- 0,
- 0
- }
- },
- {
- {
- BCM2709_MAILBOX_TAG_SET_OVERSCAN,
- sizeof(BCM2709_OVERSCAN),
- sizeof(BCM2709_OVERSCAN)
- },
- {
- 0,
- 0,
- 0,
- 0
- }
- },
- {
- {
- BCM2709_MAILBOX_TAG_GET_PITCH,
- sizeof(UINT32),
- 0,
- },
- 0
- },
- {
- {
- BCM2709_MAILBOX_TAG_GET_FRAME_BUFFER,
- sizeof(BCM2709_FRAME_BUFFER),
- 0
- },
- {
- 0,
- 0
- }
- },
- 0
- };
- //
- // Store the device path of the video controller.
- //
- EFI_BCM2709_VIDEO_DEVICE_PATH EfiBcm2709VideoDevicePathTemplate = {
- {
- {
- HARDWARE_DEVICE_PATH,
- HW_VENDOR_DP,
- sizeof(VENDOR_DEVICE_PATH)
- },
- EFI_BCM2709_VIDEO_DEVICE_GUID,
- },
- {
- END_DEVICE_PATH_TYPE,
- END_ENTIRE_DEVICE_PATH_SUBTYPE,
- END_DEVICE_PATH_LENGTH
- }
- };
- EFI_GRAPHICS_OUTPUT_MODE_INFORMATION EfiBcm2709VideoModes[] = {
- {
- 0,
- 1024,
- 600,
- PixelBitMask,
- {
- BCM2709_BGR_RED_MASK,
- BCM2709_BGR_GREEN_MASK,
- BCM2709_BGR_BLUE_MASK,
- BCM2709_BGR_RESERVED_MASK
- },
- 1024
- },
- {
- 0,
- 1024,
- 768,
- PixelBitMask,
- {
- BCM2709_BGR_RED_MASK,
- BCM2709_BGR_GREEN_MASK,
- BCM2709_BGR_BLUE_MASK,
- BCM2709_BGR_RESERVED_MASK
- },
- 1024
- },
- {
- 0,
- 0,
- 0,
- PixelBitMask,
- {
- BCM2709_BGR_RED_MASK,
- BCM2709_BGR_GREEN_MASK,
- BCM2709_BGR_BLUE_MASK,
- BCM2709_BGR_RESERVED_MASK
- },
- 0
- },
- };
- UINT32 EfiBcm2709VideoModeCount = 2;
- //
- // ------------------------------------------------------------------ Functions
- //
- EFI_STATUS
- EfipBcm2709EnumerateVideo (
- VOID
- )
- /*++
- Routine Description:
- This routine enumerates the display on BCM2709 SoCs.
- Arguments:
- None.
- Return Value:
- EFI status code.
- --*/
- {
- PEFI_BCM2709_VIDEO_DEVICE Device;
- EFI_PHYSICAL_ADDRESS FrameBufferBase;
- UINTN FrameBufferSize;
- UINT32 Index;
- EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Mode;
- UINT32 ModeIndex;
- EFI_STATUS Status;
- Device = NULL;
- //
- // If the BCM2709 device library is not initialized, fail.
- //
- if (EfiBcm2709Initialized == FALSE) {
- return EFI_NOT_READY;
- }
- //
- // Initialize the set of available video modes.
- //
- EfipBcm2709VideoInitializeModes();
- //
- // Iterate over the list of available modes backwards until a suitable mode
- // is found.
- //
- Status = EFI_UNSUPPORTED;
- for (Index = EfiBcm2709VideoModeCount; Index != 0; Index -= 1) {
- ModeIndex = Index - 1;
- Mode = &(EfiBcm2709VideoModes[ModeIndex]);
- Status = EfipBcm2709VideoInitialize(Mode,
- &FrameBufferBase,
- &FrameBufferSize);
- if (!EFI_ERROR(Status)) {
- break;
- }
- //
- // That mode didn't work, so don't advertise it.
- //
- EfiBcm2709VideoModeCount -= 1;
- }
- if (EFI_ERROR(Status)) {
- goto EnumerateVideoEnd;
- }
- //
- // Everything's all set up, create the graphics output protocol.
- //
- Status = EfiAllocatePool(EfiBootServicesData,
- sizeof(EFI_BCM2709_VIDEO_DEVICE),
- (VOID **)&Device);
- if (EFI_ERROR(Status)) {
- goto EnumerateVideoEnd;
- }
- EfiSetMem(Device, sizeof(EFI_BCM2709_VIDEO_DEVICE), 0);
- Device->Magic = EFI_BCM2709_VIDEO_DEVICE_MAGIC;
- Device->GraphicsOut.QueryMode = EfipBcm2709GraphicsQueryMode;
- Device->GraphicsOut.SetMode = EfipBcm2709GraphicsSetMode;
- Device->GraphicsOut.Blt = EfipBcm2709GraphicsBlt;
- Device->GraphicsOut.Mode = &(Device->GraphicsOutMode);
- Device->GraphicsOutMode.MaxMode = EfiBcm2709VideoModeCount;
- Device->GraphicsOutMode.Mode = ModeIndex;
- Device->GraphicsOutMode.Info = Mode;
- Device->GraphicsOutMode.SizeOfInfo =
- sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
- Device->GraphicsOutMode.FrameBufferBase = FrameBufferBase;
- Device->GraphicsOutMode.FrameBufferSize = FrameBufferSize;
- Status = EfiInstallMultipleProtocolInterfaces(
- &(Device->Handle),
- &EfiGraphicsOutputProtocolGuid,
- &(Device->GraphicsOut),
- &EfiDevicePathProtocolGuid,
- &EfiBcm2709VideoDevicePathTemplate,
- NULL);
- if (EFI_ERROR(Status)) {
- goto EnumerateVideoEnd;
- }
- EnumerateVideoEnd:
- if (EFI_ERROR(Status)) {
- if (Device != NULL) {
- EfiFreePool(Device);
- }
- }
- return Status;
- }
- //
- // --------------------------------------------------------- Internal Functions
- //
- EFIAPI
- EFI_STATUS
- EfipBcm2709GraphicsQueryMode (
- EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
- UINT32 ModeNumber,
- UINTN *SizeOfInfo,
- EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
- )
- /*++
- Routine Description:
- This routine returns information about available graphics modes that the
- graphics device and set of active video output devices support.
- Arguments:
- This - Supplies a pointer to the protocol instance.
- ModeNumber - Supplies the mode number to return information about.
- SizeOfInfo - Supplies a pointer that on input contains the size in bytes of
- the information buffer.
- Info - Supplies a pointer where a callee-allocated buffer will be returned
- containing information about the mode. The caller is responsible for
- calling FreePool to free this data.
- Return Value:
- EFI_SUCCESS on success.
- EFI_DEVICE_ERROR if a hardware error occurred trying to retrieve the video
- mode.
- EFI_INVALID_PARAMETER if the mode number is not valid.
- --*/
- {
- EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Information;
- EFI_STATUS Status;
- if ((ModeNumber >= EfiBcm2709VideoModeCount) || (SizeOfInfo == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
- Status = EfiAllocatePool(EfiBootServicesData,
- sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),
- (VOID **)&Information);
- if (EFI_ERROR(Status)) {
- return Status;
- }
- EfiCopyMem(Information,
- &(EfiBcm2709VideoModes[ModeNumber]),
- sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
- *Info = Information;
- *SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
- return EFI_SUCCESS;
- }
- EFIAPI
- EFI_STATUS
- EfipBcm2709GraphicsSetMode (
- EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
- UINT32 ModeNumber
- )
- /*++
- Routine Description:
- This routine sets the video device into the specified mode and clears the
- visible portions of the output display to black.
- Arguments:
- This - Supplies a pointer to the protocol instance.
- ModeNumber - Supplies the mode number to set.
- Return Value:
- EFI_SUCCESS on success.
- EFI_DEVICE_ERROR if a hardware error occurred trying to set the video mode.
- EFI_UNSUPPORTED if the mode number is not supported by this device.
- --*/
- {
- EFI_PHYSICAL_ADDRESS FrameBufferBase;
- UINTN FrameBufferSize;
- EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Mode;
- EFI_STATUS Status;
- if (ModeNumber >= EfiBcm2709VideoModeCount) {
- return EFI_UNSUPPORTED;
- }
- Mode = &(EfiBcm2709VideoModes[ModeNumber]);
- Status = EfipBcm2709VideoInitialize(Mode,
- &FrameBufferBase,
- &FrameBufferSize);
- if (EFI_ERROR(Status)) {
- return Status;
- }
- This->Mode->Info = Mode;
- This->Mode->Mode = ModeNumber;
- This->Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
- This->Mode->FrameBufferBase = FrameBufferBase;
- This->Mode->FrameBufferSize = FrameBufferSize;
- return Status;
- }
- EFIAPI
- EFI_STATUS
- EfipBcm2709GraphicsBlt (
- EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer,
- EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
- UINTN SourceX,
- UINTN SourceY,
- UINTN DestinationX,
- UINTN DestinationY,
- UINTN Width,
- UINTN Height,
- UINTN Delta
- )
- /*++
- Routine Description:
- This routine performs a Blt (copy) operation of pixels on the graphics
- screen. Blt stands for Block Transfer for those not up on their video lingo.
- Arguments:
- This - Supplies a pointer to the protocol instance.
- BltBuffer - Supplies an optional pointer to the data to transfer to the
- graphics screen. The size must be at least width * height *
- sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL).
- BltOperation - Supplies the operation to perform when copying the buffer to
- the screen.
- SourceX - Supplies the X coordinate of the source of the operation.
- SourceY - Supplies the Y coordinate of the source of the operation.
- DestinationX - Supplies the X coordinate of the destination of the
- operation.
- DestinationY - Supplies the Y coordinate of the destination of the
- operation.
- Width - Supplies the width of the rectangle in pixels.
- Height - Supplies the height of the rectangle in pixels.
- Delta - Supplies an optional number of bytes in a row of the given buffer.
- If a delta of zero is used, the entire buffer is being operated on.
- This is not used for EfiBltVideoFill or EfiBltVideoToVideo operations.
- Return Value:
- EFI_SUCCESS on success.
- EFI_INVALID_PARAMETER if the operation was not valid.
- EFI_DEVICE_ERROR if a hardware error occurred and the request could not be
- completed.
- --*/
- {
- return EFI_UNSUPPORTED;
- }
- EFI_STATUS
- EfipBcm2709VideoInitialize (
- EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Mode,
- EFI_PHYSICAL_ADDRESS *FrameBufferBase,
- UINTN *FrameBufferSize
- )
- /*++
- Routine Description:
- This routine initializes video by setting the controller to the given video
- mode.
- Arguments:
- Mode - Supplies a pointer to the desired video mode.
- FrameBufferBase - Supplies a pointer that receives the base address of the
- frame buffer.
- FrameBufferSize - Supplies a pointer that receives the size of the frame
- buffer in bytes.
- Return Value:
- Status code.
- --*/
- {
- UINT32 ExpectedLength;
- UINT32 Height;
- EFI_BCM2709_VIDEO_INITIALIZE InitializeVideo;
- UINT32 Length;
- UINT32 PixelOrder;
- UINT32 PixelsPerScanLine;
- EFI_STATUS Status;
- UINT32 Width;
- //
- // Update the video initialization template with the given mode information.
- //
- EfiCopyMem(&InitializeVideo,
- &EfiBcm2709InitializeVideoTemplate,
- sizeof(EFI_BCM2709_VIDEO_INITIALIZE));
- Width = Mode->HorizontalResolution;
- Height = Mode->VerticalResolution;
- InitializeVideo.PhysicalResolution.Resolution.Width = Width;
- InitializeVideo.PhysicalResolution.Resolution.Height = Height;
- InitializeVideo.VirtualResolution.Resolution.Width = Width;
- InitializeVideo.VirtualResolution.Resolution.Height = Height;
- //
- // Determine the pixel order and update the template if necessary.
- //
- if ((Mode->PixelFormat == PixelRedGreenBlueReserved8BitPerColor) ||
- ((Mode->PixelFormat == PixelBitMask) &&
- (Mode->PixelInformation.RedMask == BCM2709_BGR_RED_MASK))) {
- PixelOrder = BCM2709_MAILBOX_PIXEL_ORDER_BGR;
- } else {
- PixelOrder = BCM2709_MAILBOX_PIXEL_ORDER_RGB;
- }
- InitializeVideo.PixelOrderMessage.PixelOrder = PixelOrder;
- //
- // Send the initialization command to the BCM2709 mailbox. This is also a
- // GET operation as the frame buffer will be returned. The set actually
- // triggers a frame buffer allocation and the frame buffer cannot be
- // queried separately.
- //
- Status = EfipBcm2709MailboxSendCommand(
- BCM2709_MAILBOX_PROPERTIES_CHANNEL,
- &InitializeVideo,
- sizeof(EFI_BCM2709_VIDEO_INITIALIZE),
- FALSE);
- if (EFI_ERROR(Status)) {
- goto Bcm2709VideoInitializeEnd;
- }
- //
- // Check the values that are going to be used.
- //
- Length = InitializeVideo.PhysicalResolution.TagHeader.Length;
- ExpectedLength = sizeof(BCM2709_MAILBOX_RESOLUTION) -
- sizeof(BCM2709_MAILBOX_TAG);
- if (BCM2709_MAILBOX_CHECK_TAG_LENGTH(Length, ExpectedLength) == FALSE) {
- Status = EFI_DEVICE_ERROR;
- goto Bcm2709VideoInitializeEnd;
- }
- Length = InitializeVideo.VirtualResolution.TagHeader.Length;
- ExpectedLength = sizeof(BCM2709_MAILBOX_RESOLUTION) -
- sizeof(BCM2709_MAILBOX_TAG);
- if (BCM2709_MAILBOX_CHECK_TAG_LENGTH(Length, ExpectedLength) == FALSE) {
- Status = EFI_DEVICE_ERROR;
- goto Bcm2709VideoInitializeEnd;
- }
- Length = InitializeVideo.BitsPerPixelMessage.TagHeader.Length;
- ExpectedLength = sizeof(BCM2709_MAILBOX_BITS_PER_PIXEL) -
- sizeof(BCM2709_MAILBOX_TAG);
- if (BCM2709_MAILBOX_CHECK_TAG_LENGTH(Length, ExpectedLength) == FALSE) {
- Status = EFI_DEVICE_ERROR;
- goto Bcm2709VideoInitializeEnd;
- }
- Length = InitializeVideo.PixelOrderMessage.TagHeader.Length;
- ExpectedLength = sizeof(BCM2709_MAILBOX_PIXEL_ORDER) -
- sizeof(BCM2709_MAILBOX_TAG);
- if (BCM2709_MAILBOX_CHECK_TAG_LENGTH(Length, ExpectedLength) == FALSE) {
- Status = EFI_DEVICE_ERROR;
- goto Bcm2709VideoInitializeEnd;
- }
- Length = InitializeVideo.Pitch.TagHeader.Length;
- ExpectedLength = sizeof(BCM2709_MAILBOX_PITCH) -
- sizeof(BCM2709_MAILBOX_TAG);
- if (BCM2709_MAILBOX_CHECK_TAG_LENGTH(Length, ExpectedLength) == FALSE) {
- Status = EFI_DEVICE_ERROR;
- goto Bcm2709VideoInitializeEnd;
- }
- Length = InitializeVideo.FrameBufferMessage.TagHeader.Length;
- ExpectedLength = sizeof(BCM2709_MAILBOX_FRAME_BUFFER) -
- sizeof(BCM2709_MAILBOX_TAG);
- if (BCM2709_MAILBOX_CHECK_TAG_LENGTH(Length, ExpectedLength) == FALSE) {
- Status = EFI_DEVICE_ERROR;
- goto Bcm2709VideoInitializeEnd;
- }
- //
- // Make sure the virtual and physical resolutions match.
- //
- if ((InitializeVideo.PhysicalResolution.Resolution.Width !=
- InitializeVideo.VirtualResolution.Resolution.Width) ||
- (InitializeVideo.PhysicalResolution.Resolution.Height !=
- InitializeVideo.VirtualResolution.Resolution.Height)) {
- Status = EFI_DEVICE_ERROR;
- goto Bcm2709VideoInitializeEnd;
- }
- //
- // Make sure the resolution matches the requested modes resolution.
- //
- if ((InitializeVideo.PhysicalResolution.Resolution.Width != Width) ||
- (InitializeVideo.PhysicalResolution.Resolution.Height != Height)) {
- Status = EFI_DEVICE_ERROR;
- goto Bcm2709VideoInitializeEnd;
- }
- //
- // Make sure the result pixel order matches the requested pixel order.
- //
- if (InitializeVideo.PixelOrderMessage.PixelOrder != PixelOrder) {
- Status = EFI_DEVICE_ERROR;
- goto Bcm2709VideoInitializeEnd;
- }
- //
- // Check the pitch. The pixels per scan line better match that of the
- // requested mode.
- //
- PixelsPerScanLine = InitializeVideo.Pitch.BytesPerScanLine /
- (InitializeVideo.BitsPerPixelMessage.BitsPerPixel / 8);
- if (PixelsPerScanLine != Mode->PixelsPerScanLine) {
- Status = EFI_DEVICE_ERROR;
- goto Bcm2709VideoInitializeEnd;
- }
- //
- // The video core may return an aliased address out of range for the ARM
- // core. Shift the base address until it is accessible by the ARM core.
- //
- *FrameBufferBase = InitializeVideo.FrameBufferMessage.FrameBuffer.Base;
- *FrameBufferBase &= BCM2709_ARM_PHYSICAL_ADDRESS_MASK;
- *FrameBufferSize = InitializeVideo.FrameBufferMessage.FrameBuffer.Size;
- Status = EFI_SUCCESS;
- Bcm2709VideoInitializeEnd:
- return Status;
- }
- VOID
- EfipBcm2709VideoInitializeModes (
- VOID
- )
- /*++
- Routine Description:
- This routine initializes the video modes by adding a mode with the current
- resolution to the globally defined list if such a mode does not already
- exist.
- Arguments:
- None.
- Return Value:
- None.
- --*/
- {
- UINT32 ExpectedLength;
- UINT32 Height;
- UINT32 Index;
- UINT32 Length;
- EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Mode;
- EFI_STATUS Status;
- EFI_BCM2709_VIDEO_GET_MODE VideoMode;
- UINT32 Width;
- //
- // Get the current video mode's resolution.
- //
- EfiCopyMem(&VideoMode,
- &EfiBcm2709GetModeTemplate,
- sizeof(EFI_BCM2709_VIDEO_GET_MODE));
- Status = EfipBcm2709MailboxSendCommand(
- BCM2709_MAILBOX_PROPERTIES_CHANNEL,
- &VideoMode,
- sizeof(EFI_BCM2709_VIDEO_GET_MODE),
- FALSE);
- if (EFI_ERROR(Status)) {
- goto Bcm2709VideoInitializeModesEnd;
- }
- //
- // Validate the returned data.
- //
- Length = VideoMode.PhysicalResolution.TagHeader.Length;
- ExpectedLength = sizeof(BCM2709_MAILBOX_RESOLUTION) -
- sizeof(BCM2709_MAILBOX_TAG);
- if (BCM2709_MAILBOX_CHECK_TAG_LENGTH(Length, ExpectedLength) == FALSE) {
- goto Bcm2709VideoInitializeModesEnd;
- }
- Width = VideoMode.PhysicalResolution.Resolution.Width;
- Height = VideoMode.PhysicalResolution.Resolution.Height;
- //
- // Check to see if this resolution matches any of the current resolutions.
- //
- for (Index = 0; Index < EfiBcm2709VideoModeCount; Index += 1) {
- Mode = &(EfiBcm2709VideoModes[Index]);
- if ((Mode->HorizontalResolution == Width) &&
- (Mode->VerticalResolution == Height)) {
- EfiBcm2709VideoModeCount = Index + 1;
- goto Bcm2709VideoInitializeModesEnd;
- }
- }
- //
- // If there is no more space in the array, then skip it.
- //
- if (Index >= EFI_BCM2709_VIDEO_MODE_ARRAY_LENGTH) {
- goto Bcm2709VideoInitializeModesEnd;
- }
- //
- // Otherwise add this resolution as the next element in the array. The
- // pixel format is already set.
- //
- Mode = &(EfiBcm2709VideoModes[Index]);
- Mode->HorizontalResolution = Width;
- Mode->VerticalResolution = Height;
- Mode->PixelsPerScanLine = Width;
- EfiBcm2709VideoModeCount += 1;
- Bcm2709VideoInitializeModesEnd:
- return;
- }
|