/*++ Copyright (c) 2012 Minoca Corp. All Rights Reserved Module Name: video.c Abstract: This module implements support for the Texas Instruments OMAP4 DSS/DISPC display controller. Author: Evan Green 25-Mar-2014 Environment: Firmware --*/ // // ------------------------------------------------------------------- Includes // #include #include #include "pandafw.h" // // --------------------------------------------------------------------- Macros // // // These macros read from and write to a display controller register. // #define READ_DISPLAY_REGISTER(_Register) \ *(volatile UINT32 *)((UINT8 *)EfiOmap4DispcAddress + (_Register)) #define WRITE_DISPLAY_REGISTER(_Register, _Value) \ *((volatile UINT32 *)((UINT8 *)EfiOmap4DispcAddress + (_Register))) = \ (_Value) // // These macros read from and write to the display subsystem. // #define READ_DISPLAY_SUBSYSTEM_REGISTER(_Register) \ *(volatile UINT32 *)((UINT8 *)EfiOmap4DssAddress + (_Register)) #define WRITE_DISPLAY_SUBSYSTEM_REGISTER(_Register, _Value) \ *((volatile UINT32 *)((UINT8 *)EfiOmap4DssAddress + (_Register))) = (_Value) // // These macros read from and write to the DSS PRM (Power and Reset Manager). // #define READ_DSS_PRM_REGISTER(_Register) \ *(volatile UINT32 *)((UINT8 *)EfiOmap4DssPrmAddress + (_Register)) #define WRITE_DSS_PRM_REGISTER(_Register, _Value) \ *((volatile UINT32 *)((UINT8 *)EfiOmap4DssPrmAddress + (_Register))) = \ (_Value) // // These macros read from and write to the DSS CM (Clock Manager). // #define READ_DSS_CM_REGISTER(_Register) \ *(volatile UINT32 *)((UINT8 *)EfiOmap4DssCm2Address + (_Register)) #define WRITE_DSS_CM_REGISTER(_Register, _Value) \ *((volatile UINT32 *)((UINT8 *)EfiOmap4DssCm2Address + (_Register))) = \ (_Value) // // ---------------------------------------------------------------- Definitions // #define EFI_OMAP4_VIDEO_DEVICE_GUID \ { \ 0x19EEE1EB, 0x8F2A, 0x4DFA, \ {0xB0, 0xF9, 0xB1, 0x0B, 0xD5, 0xB8, 0x71, 0x04} \ } #define EFI_OMAP4_VIDEO_DEVICE_MAGIC 0x6469564F // 'diVO' // // Define the default mode to initialize in. // #define EFI_OMAP4_VIDEO_DEFAULT_MODE 1 #define EFI_OMAP4_VIDEO_MODE_COUNT \ (sizeof(EfiOmap4VideoModes) / sizeof(EfiOmap4VideoModes[0])) // // Define the size of the frame buffer to allocate, which should be large // enough to support the largest resolution. // #define EFI_OMAP4_FRAME_BUFFER_SIZE (1024 * 768 * sizeof(UINT32)) // // Define the default physical address of the DISPC module on OMAP4 chips. // #define OMAP4_DISPC_BASE 0x58001000 // // Define the default physical address of the DSS module on OMAP4 chips. // #define OMAP4_DSS_BASE 0x48040000 // // Define the default physical address of the DSS Power and Reset Manager (PRM). // #define OMAP4_DSS_PRM_BASE 0x4A307100 // // Define the default physical address of the DSS Clock Manager (CM). // #define OMAP4_DSS_CM2_BASE 0x4A009100 // // Define the timing parameters to use. // #define OMAP4_DISPLAY_SUBSYSTEM_DIVISOR 1 #define OMAP4_HORIZONTAL_BACK_PORCH 47 #define OMAP4_HORIZONTAL_FRONT_PORCH 15 #define OMAP4_VERTICAL_BACK_PORCH 32 #define OMAP4_VERTICAL_FRONT_PORCH 9 #define OMAP4_HORIZONTAL_SYNC_PULSE_WIDTH 95 #define OMAP4_VERTICAL_SYNC_PULSE_WIDTH 2 #define OMAP4_DISPLAY_SUBSYSTEM_DIVISOR 1 // // Define the number of 128-bit words to pre-load into the video DMA pipeline. // #define OMAP4_VIDEO_PRELOAD_VALUE 0x100 // // Define DMA buffer attributes. // #define OMAP_VIDEO_BUFFER_LOW_THRESHOLD 0x00C0 #define OMAP_VIDEO_BUFFER_HIGH_THRESHOLD 0x00FC #define OMAP_VIDEO_BUFFER_SIZE 0x00000400 // // Define register bit definitions for the DSS control register. // // // Set this bit to select the HDMI encoder. // #define OMAP_DSS_CONTROL_SELECT_HDMI (1 << 15) // // Define register bit definitions for the system configuration register. // // // Set this bit to allow auto idling. // #define OMAP_VIDEO_SYSTEM_CONFIGURATION_AUTO_IDLE (1 << 0) // // Set this bit to enable the wakeup feature. // #define OMAP_VIDEO_SYSTEM_CONFIGURATION_ENABLE_WAKEUP (1 << 2) // // Set this bit to tell the controller to never idle out. // #define OMAP_VIDEO_SYSTEM_CONFIGURATION_NO_IDLE (1 << 3) // // Set these bits to enable smart idle. // #define OMAP_VIDEO_SYSTEM_CONFIGURATION_SMART_IDLE (2 << 3) // // Set this bit to tell the controller never to assert standby. // #define OMAP_VIDEO_SYSTEM_CONIGURATION_NO_STANDBY (1 << 12) // // Set this bit to enable smart standby. // #define OMAP_VIDEO_SYSTEM_CONFIGURATION_SMART_STANDBY (2 << 12) // // Define register bit definitions for the attributes register. // // // Set this bit to enable the given video pipeline. // #define OMAP_VIDEO_ATTRIBUTES_ENABLED (1 << 0) // // This format sets the frame buffer to be in ARGB32-8888 mode. // #define OMAP_VIDEO_ATTRIBUTES_FORMAT_ARGB32_8888 (0xC << 1) // // This format sets the frame buffer to be in xRGB24-8888 mode // (32-bit container). // #define OMAP_VIDEO_ATTRIBUTES_FORMAT_XRGB24_8888 (0x8 << 1) // // Set this bit to enable a DMA burst size of 8x128 bits. // #define OMAP_VIDEO_ATTRIBUTES_BURST_8X128_BITS (0x2 << 6) // // Set this bit to make this video pipeline high priority in the DMA arbiter. // #define OMAP_VIDEO_ATTRIBUTES_ARBITRATION (1 << 14) // // Set this bit to select the TV out over the LCD0, LCD1, or WB pipelines. // #define OMAP_VIDEO_ATTRIBUTES_TV_OUTPUT (1 << 16) // // Set this bit to cause the video pipeline to fetch from teh DMA buffer. // #define OMAP_VIDEO_ATTRIBUTES_SELF_REFRESH (1 << 24) // // Set this bit to send the output to the secondary LCD. // #define OMAP_VIDEO_ATTRIBUTES_LCD2_OUTPUT (1 << 30) // // Define register bit definitions for the picture size register. // // // Define the shift amounts for picture size fields. // #define OMAP_VIDEO_PICTURE_SIZE_X_SHIFT 0 #define OMAP_VIDEO_PICTURE_SIZE_Y_SHIFT 16 // // Define register bit definitions for the size register. // // // Define the shift amounts for the size fields. // #define OMAP_VIDEO_SIZE_X_SHIFT 0 #define OMAP_VIDEO_SIZE_Y_SHIFT 16 // // Define register bit definitions for the TV size register. // // // Define the shift amounts for the size fields. // #define OMAP_VIDEO_TV_SIZE_X_SHIFT 0 #define OMAP_VIDEO_TV_SIZE_Y_SHIFT 16 // // Define register bit definitions for the LCD size registers. // // // Define the shift amounts for the size fields. // #define OMAP_VIDEO_LCD_SIZE_X_SHIFT 0 #define OMAP_VIDEO_LCD_SIZE_Y_SHIFT 16 // // Define the buffer threshold register. // #define OMAP_VIDEO_BUFFER_THRESHOLD_HIGH_SHIFT 16 // // Define register bit definitions for the control 1 register. // // // Set this bit to enable TV output. // #define OMAP_VIDEO_CONTROL1_TV_ENABLED (1 << 1) // // Set this bit for Active matrix (TFT) displays. // #define OMAP_VIDEO_CONTROL1_ACTIVE_TFT (1 << 3) // // Set this bit to snap all configured shadow registers into service at the // next VSYNC. // #define OMAP_VIDEO_CONTROL1_GO_TV (1 << 6) // // Set this bit to set the first GPIO line to high. // #define OMAP_VIDEO_CONTROL1_GPIO0_SET (1 << 15) // // Set this bit to set the second GPIO line to high. // #define OMAP_VIDEO_CONTROL1_GPIO1_SET (1 << 16) // // Define register bit definitions for the configuration 1 register. // #define OMAP_VIDEO_CONFIGURATION1_LOAD_ONLY_FRAME_DATA (2 << 1) // // Define register bit definitions for the control 2 register. // // // Set this bit to enable LCD2. // #define OMAP_VIDEO_CONTROL2_LCD2_ENABLED (1 << 0) // // Set this bit for Active matrix (TFT) displays. // #define OMAP_VIDEO_CONTROL2_ACTIVE_TFT (1 << 3) // // Set this bit to pull the configured pipeline values into service. // #define OMAP_VIDEO_CONTROL2_GO_LCD2 (1 << 5) // // Set these bits to output 24-bits of data aligned on the LSB of the pixel // data interface. // #define OMAP_VIDEO_CONTROL2_24_BIT_TFT_DATA (3 << 8) // // Define the register definitions for the horizontal timing registers. // // // Define the shifts for the horizontal back porch and horizontal front porch. // #define OMAP_VIDEO_TIMING_HORIZONTAL_BACK_PORCH_SHIFT 20 #define OMAP_VIDEO_TIMING_HORIZONTAL_FRONT_PORCH_SHIFT 8 // // Define the register definitions for the vertical timing registers. // // // Define the shifts for the vertical back porch, and veritical front porch. // #define OMAP_VIDEO_TIMING_VERTICAL_BACK_PORCH_SHIFT 20 #define OMAP_VIDEO_TIMING_VERTICAL_FRONT_PORCH_SHIFT 8 // // Define the register definitions for the divisor registers. // // // Define the shifts for the display subsystem divisor. // #define OMAP_VIDEO_DIVISOR_DISPLAY_SUBSYSTEM_DIVISOR_SHIFT 16 // // Define register definitions for the DSS PRM Power state control register. // // // Set these bits to enable power to the DSS subsystem. // #define OMAP_DSS_PRM_POWER_CONTROL_POWER_ON (0x3 << 0) // // Define register definitions for the DSS CM Clock state control register. // // // Set this bit to force a software wakeup of the DSS clock domain. // #define OMAP_DSS_CM_CLOCK_STATE_CONTROL_SOFTWARE_WAKEUP (0x2 << 0) // // Define register definitions for the DSS CM Clock control register. // // // These bits define the idle state mask. // #define OMAP_DSS_CM_CLOCK_CONTROL_IDLE_STATE_MASK (0x3 << 16) // // This bit is set if the module is in standby. // #define OMAP_DSS_CM_CLOCK_CONTROL_STANDBY (1 << 18) // // Set these bits to enable various optional clocks. // #define OMAP_DSS_CM_CLOCK_CONTROL_TV_CLOCK_ENABLED (1 << 11) #define OMAP_DSS_CM_CLOCK_CONTROL_SYSTEM_CLOCK_ENABLED (1 << 10) #define OMAP_DSS_CM_CLOCK_CONTROL_48MHZ_CLOCK_ENABLED (1 << 9) #define OMAP_DSS_CM_CLOCK_CONTROL_DSS_CLOCK_ENABLED (1 << 8) // // Set this bit to explicitly enable the functional clock. // #define OMAP_DSS_CM_CLOCK_CONTROL_ENABLE (0x2 << 0) // // ------------------------------------------------------ Data Type Definitions // // // Define register offsets in the DISPC Display controller. All offsets are in // bytes. // typedef enum _OMAP_DISPLAY_CONTROLLER_REGISTER { OmapDisplaySystemConfiguration = 0x010, // DISPC_SYSCONFIG OmapDisplayInterruptStatus = 0x018, // DISPC_IRQSTATUS OmapDisplayControl1 = 0x040, // DISPC_CONTROL1 OmapDisplayConfiguration1 = 0x044, // DISPC_CONFIG1 OmapDisplayDefaultColor0 = 0x04C, // DISPC_DEFAULT_COLOR0 OmapDisplayDefaultColor1 = 0x050, // DISPC_DEFAULT_COLOR1 OmapDisplayDivisor1 = 0x070, // DISPC_DIVISOR1 OmapDisplayGlobalAlpha = 0x074, // DISPC_GLOBAL_ALPHA OmapDisplayTvSize = 0x078, // DISPC_SIZE_TV OmapDisplayGraphicsFrameBufferAddress0 = 0x080, // DISPC_GFX_BA_0 OmapDisplayGraphicsFrameBufferAddress1 = 0x084, // DISPC_GFX_BA_1 OmapDisplayGraphicsPosition = 0x088, // DISPC_GFX_POSITION OmapDisplayGraphicsSize = 0x08C, // DISPC_GFX_SIZE OmapDisplayGraphicsAttributes = 0x0A0, // DISPC_GFX_ATTRIBUTES OmapDisplayGraphicsBufferThreshold = 0x0A4, // DISPC_GFX_BUF_THRESHOLD OmapDisplayGraphicsBufferSize = 0x0A8, // DISPC_GFX_BUF_SIZE_STATUS OmapDisplayGraphicsRowIncrement = 0x0AC, // DISPC_GFX_ROW_INC OmapDisplayGraphicsPixelIncrement = 0x0B0, // DISPC_GFX_PIXEL_INC OmapDisplayGraphicsWindowSkip = 0x0B4, // DISPC_GFX_WINDOW_SKIP OmapDisplayVideo1FrameBufferAddress0 = 0x0BC, // DISPC_VID1_BA_0 OmapDisplayVideo1FrameBufferAddress1 = 0x0C0, // DISPC_VID1_BA_1 OmapDisplayVideo1Position = 0x0C4, // DISPC_VID1_POSITION OmapDisplayVideo1Size = 0x0C8, // DISPC_VID1_SIZE OmapDisplayVideo1Attributes = 0x0CC, // DISPC_VID1_ATTRIBUTES OmapDisplayVideo1PictureSize = 0x0E4, // DISPC_VID1_PICTURE_SIZE OmapDisplayGraphicsDmaPreload = 0x22C, // DISPC_GFX_PRELOAD OmapDisplayVideo1DmaPreload = 0x230, // DISPC_VID1_PRELOAD OmapDisplayControl2 = 0x238, // DISPC_CONTROL2 OmapDisplayDefaultColor2 = 0x3AC, // DISPC_DEFAULT_COLOR2 OmapDisplayData2Cycle1 = 0x3C0, // DISPC_DATA2_CYCLE1 OmapDisplayLcd2Size = 0x3CC, // DISPC_SIZE_LCD2 OmapDisplayHorizontalTiming2 = 0x400, // DISPC_TIMING_H2 OmapDisplayVerticalTiming2 = 0x404, // DISPC_TIMING_V2 OmapDisplayPolarity2 = 0x408, // DISPC_POL_FREQ2 OmapDisplayDivisor2 = 0x40C, // DISPC_DIVISOR2 OmapDisplayConfiguration2 = 0x620, // DISPC_CONFIG2 OmapDisplayVideo1Attributes2 = 0x624, // DISPC_VID1_ATTRIBUTES2 } OMAP_DISPLAY_CONTROLLER_REGISTER, *POMAP_DISPLAY_CONTROLLER_REGISTER; // // Define register offsets in the DSS (Display Subsystem) module. All offsets // are in bytes. // typedef enum _OMAP_DISPLAY_SUBSYSTEM_REGISTER { OmapDisplaySubsystemControl = 0x040, // DSS_CTRL } OMAP_DISPLAY_SUBSYSTEM_REGISTER, *POMAP_DISPLAY_SUBSYSTEM_REGISTER; // // Define register offsets for the DSS PRM. All offsets are in bytes. // typedef enum _DSS_PRM_REGISTER { OmapDssPrmPowerStateControl = 0x0 } DSS_PRM_REGISTER, *PDSS_PRM_REGISTER; // // Define register offsets for the DSS CM. All offsets are in bytes. // typedef enum _DSS_CM2_REGISTER { OmapDssCmClockStateControl = 0x00, // CM_DSS_CLKSTCTRL OmapDssCmClockControl = 0x20, // CM_DSS_DSS_CLKCTRL } DSS_CM2_REGISTER, *PDSS_CM2_REGISTER; /*++ Structure Description: This structure stores the OMAP4 graphics output mode information. Members: Information - Stores the information structure. PixelClockDivisor - Stores the pixel clock divisor to set for that mode. --*/ typedef struct _EFI_OMAP4_VIDEO_MODE { EFI_GRAPHICS_OUTPUT_MODE_INFORMATION Information; UINT32 PixelClockDivisor; } EFI_OMAP4_VIDEO_MODE, *PEFI_OMAP4_VIDEO_MODE; /*++ Structure Description: This structure stores the structure of an OMAP4 video device path. Members: VendorPath - Stores the vendor path portion of the device path. End - Stores the end device path node. --*/ typedef struct _EFI_OMAP4_VIDEO_DEVICE_PATH { VENDOR_DEVICE_PATH VendorPath; EFI_DEVICE_PATH_PROTOCOL End; } EFI_OMAP4_VIDEO_DEVICE_PATH, *PEFI_OMAP4_VIDEO_DEVICE_PATH; /*++ Structure Description: This structure stores the internal context for an OMAP4 video device. Members: Magic - Stores the constant magic value EFI_OMAP4_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_OMAP4_VIDEO_DEVICE { UINT32 Magic; EFI_HANDLE Handle; EFI_GRAPHICS_OUTPUT_PROTOCOL GraphicsOut; EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE GraphicsOutMode; } EFI_OMAP4_VIDEO_DEVICE, *PEFI_OMAP4_VIDEO_DEVICE; // // ----------------------------------------------- Internal Function Prototypes // EFIAPI EFI_STATUS EfipOmap4GraphicsQueryMode ( EFI_GRAPHICS_OUTPUT_PROTOCOL *This, UINT32 ModeNumber, UINTN *SizeOfInfo, EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info ); EFIAPI EFI_STATUS EfipOmap4GraphicsSetMode ( EFI_GRAPHICS_OUTPUT_PROTOCOL *This, UINT32 ModeNumber ); EFIAPI EFI_STATUS EfipOmap4GraphicsBlt ( 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 ); VOID EfipOmap4VideoInitialize ( EFI_PHYSICAL_ADDRESS FrameBufferBase, UINT32 FrameBufferWidth, UINT32 FrameBufferHeight, UINT32 PixelClockDivisor ); // // -------------------------------------------------------------------- Globals // // // Store a pointer to the DISPC module. // VOID *EfiOmap4DispcAddress = (VOID *)OMAP4_DISPC_BASE; // // Store a pointer to the more global DSS (Display Subsystem) module. // VOID *EfiOmap4DssAddress = (VOID *)OMAP4_DSS_BASE; // // Store a pointer to the DSS Power and Reset Manager (PRM). // VOID *EfiOmap4DssPrmAddress = (VOID *)OMAP4_DSS_PRM_BASE; // // Store a pointer to the DSS Clock Manager (CM). // VOID *EfiOmap4DssCm2Address = (VOID *)OMAP4_DSS_CM2_BASE; // // Store the device path of the video controller. // EFI_OMAP4_VIDEO_DEVICE_PATH EfiOmap4VideoDevicePathTemplate = { { { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, sizeof(VENDOR_DEVICE_PATH) }, EFI_OMAP4_VIDEO_DEVICE_GUID, }, { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, END_DEVICE_PATH_LENGTH } }; // // Define the supported video modes. // EFI_OMAP4_VIDEO_MODE EfiOmap4VideoModes[] = { { { 0, 1024, 600, PixelBitMask, { 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }, 1024 }, 18 }, { { 0, 1024, 768, PixelBitMask, { 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }, 1024 }, 13 }, }; // // ------------------------------------------------------------------ Functions // EFI_STATUS EfipPandaEnumerateVideo ( VOID ) /*++ Routine Description: This routine enumerates the display on the PandaBoard. Arguments: None. Return Value: EFI status code. --*/ { PEFI_OMAP4_VIDEO_DEVICE Device; EFI_PHYSICAL_ADDRESS FrameBufferBase; PEFI_OMAP4_VIDEO_MODE Mode; EFI_STATUS Status; FrameBufferBase = -1; Device = NULL; Mode = &(EfiOmap4VideoModes[EFI_OMAP4_VIDEO_DEFAULT_MODE]); // // Allocate space for the frame buffer. // Status = EfiAllocatePages(AllocateAnyPages, EfiMemoryMappedIO, EFI_SIZE_TO_PAGES(EFI_OMAP4_FRAME_BUFFER_SIZE), &FrameBufferBase); if (EFI_ERROR(Status)) { return Status; } // // Initialize the video to the default mode. // EfipOmap4VideoInitialize(FrameBufferBase, Mode->Information.HorizontalResolution, Mode->Information.VerticalResolution, Mode->PixelClockDivisor); // // Everything's all set up, create the graphics output protocol. // Status = EfiAllocatePool(EfiBootServicesData, sizeof(EFI_OMAP4_VIDEO_DEVICE), (VOID **)&Device); if (EFI_ERROR(Status)) { goto EnumerateVideoEnd; } EfiSetMem(Device, sizeof(EFI_OMAP4_VIDEO_DEVICE), 0); Device->Magic = EFI_OMAP4_VIDEO_DEVICE_MAGIC; Device->GraphicsOut.QueryMode = EfipOmap4GraphicsQueryMode; Device->GraphicsOut.SetMode = EfipOmap4GraphicsSetMode; Device->GraphicsOut.Blt = EfipOmap4GraphicsBlt; Device->GraphicsOut.Mode = &(Device->GraphicsOutMode); Device->GraphicsOutMode.MaxMode = EFI_OMAP4_VIDEO_MODE_COUNT; Device->GraphicsOutMode.Mode = EFI_OMAP4_VIDEO_DEFAULT_MODE; Device->GraphicsOutMode.Info = &(Mode->Information); Device->GraphicsOutMode.SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); Device->GraphicsOutMode.FrameBufferBase = FrameBufferBase; Device->GraphicsOutMode.FrameBufferSize = EFI_OMAP4_FRAME_BUFFER_SIZE; Status = EfiInstallMultipleProtocolInterfaces( &(Device->Handle), &EfiGraphicsOutputProtocolGuid, &(Device->GraphicsOut), &EfiDevicePathProtocolGuid, &EfiOmap4VideoDevicePathTemplate, NULL); if (EFI_ERROR(Status)) { goto EnumerateVideoEnd; } EnumerateVideoEnd: if (EFI_ERROR(Status)) { if (FrameBufferBase != -1) { EfiFreePages(FrameBufferBase, EFI_SIZE_TO_PAGES(EFI_OMAP4_FRAME_BUFFER_SIZE)); } if (Device != NULL) { EfiFreePool(Device); } } return Status; } // // --------------------------------------------------------- Internal Functions // EFIAPI EFI_STATUS EfipOmap4GraphicsQueryMode ( 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 >= EFI_OMAP4_VIDEO_MODE_COUNT) || (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, &(EfiOmap4VideoModes[ModeNumber].Information), sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION)); *Info = Information; *SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); return EFI_SUCCESS; } EFIAPI EFI_STATUS EfipOmap4GraphicsSetMode ( 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. --*/ { PEFI_OMAP4_VIDEO_MODE Mode; EFI_STATUS Status; if (ModeNumber >= EFI_OMAP4_VIDEO_MODE_COUNT) { return EFI_UNSUPPORTED; } Mode = &(EfiOmap4VideoModes[ModeNumber]); EfipOmap4VideoInitialize(This->Mode->FrameBufferBase, Mode->Information.HorizontalResolution, Mode->Information.VerticalResolution, Mode->PixelClockDivisor); This->Mode->Info = &(Mode->Information); This->Mode->Mode = ModeNumber; This->Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); return Status; } EFIAPI EFI_STATUS EfipOmap4GraphicsBlt ( 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; } VOID EfipOmap4VideoInitialize ( EFI_PHYSICAL_ADDRESS FrameBufferBase, UINT32 FrameBufferWidth, UINT32 FrameBufferHeight, UINT32 PixelClockDivisor ) /*++ Routine Description: This routine initialize the video subsystem on the TI OMAP4. Arguments: FrameBufferBase - Supplies the physical address where the frame buffer is located. FrameBufferWidth - Supplies the width of the frame buffer in pixels. FrameBufferHeight - Supplies the height of the frame buffer in pixels. PixelClockDivisor - Supplies the pixel clock divisor to set. Return Value: None. --*/ { UINT32 Value; // // Set GPIO0 to HI to enable the TFP410PAP. For the output enable register, // when a bit is 0, then the GPIO is in output mode. // Value = READ_GPIO1_REGISTER(OmapGpioOutputEnable); WRITE_GPIO1_REGISTER(OmapGpioOutputEnable, Value & ~(1 << 0)); WRITE_GPIO1_REGISTER(OmapGpioOutputSet, (1 << 0)); // // Enable clocks and power for the Display Subsystem. // WRITE_DSS_PRM_REGISTER(OmapDssPrmPowerStateControl, OMAP_DSS_PRM_POWER_CONTROL_POWER_ON); WRITE_DSS_CM_REGISTER(OmapDssCmClockStateControl, OMAP_DSS_CM_CLOCK_STATE_CONTROL_SOFTWARE_WAKEUP); Value = OMAP_DSS_CM_CLOCK_CONTROL_DSS_CLOCK_ENABLED | OMAP_DSS_CM_CLOCK_CONTROL_ENABLE; WRITE_DSS_CM_REGISTER(OmapDssCmClockControl, Value); // // Wait for the module to exit an idle state before attempting to access it. // while (TRUE) { if ((READ_DSS_CM_REGISTER(OmapDssCmClockControl) & OMAP_DSS_CM_CLOCK_CONTROL_IDLE_STATE_MASK) == 0) { break; } } // // Reset DSS control to its default value. // WRITE_DISPLAY_SUBSYSTEM_REGISTER(OmapDisplaySubsystemControl, 0); // // Set up smart auto-idling. // Value = OMAP_VIDEO_SYSTEM_CONFIGURATION_SMART_STANDBY | OMAP_VIDEO_SYSTEM_CONFIGURATION_SMART_IDLE | OMAP_VIDEO_SYSTEM_CONFIGURATION_ENABLE_WAKEUP | OMAP_VIDEO_SYSTEM_CONFIGURATION_AUTO_IDLE; WRITE_DISPLAY_REGISTER(OmapDisplaySystemConfiguration, Value); // // Set up the configuration register to only load frame data (and not // palette/gamma tables) every frame. // WRITE_DISPLAY_REGISTER(OmapDisplayConfiguration1, OMAP_VIDEO_CONFIGURATION1_LOAD_ONLY_FRAME_DATA); // // Set up the divisor. // Value = (OMAP4_DISPLAY_SUBSYSTEM_DIVISOR << OMAP_VIDEO_DIVISOR_DISPLAY_SUBSYSTEM_DIVISOR_SHIFT) | PixelClockDivisor; WRITE_DISPLAY_REGISTER(OmapDisplayDivisor2, Value); // // Disable the global alpha channel on all video pipelines. // WRITE_DISPLAY_REGISTER(OmapDisplayGlobalAlpha, 0xFFFFFFFF); // // Set the address of the frame buffer. // WRITE_DISPLAY_REGISTER(OmapDisplayGraphicsFrameBufferAddress0, (UINT32)FrameBufferBase); WRITE_DISPLAY_REGISTER(OmapDisplayGraphicsFrameBufferAddress1, (UINT32)FrameBufferBase); // // Set the position of this frame buffer in the overlay manager. This is // the only frame buffer, so set it to the top left. // WRITE_DISPLAY_REGISTER(OmapDisplayGraphicsPosition, 0); // // Set up the dimensions of the frame buffer itself. // Value = ((FrameBufferWidth - 1) << OMAP_VIDEO_SIZE_X_SHIFT) | ((FrameBufferHeight - 1) << OMAP_VIDEO_SIZE_Y_SHIFT); WRITE_DISPLAY_REGISTER(OmapDisplayGraphicsSize, Value); // // Set up the attributes register, which sets up the pixel format, enables // the pipeline, and sets LCD2 as the destination. // Value = OMAP_VIDEO_ATTRIBUTES_LCD2_OUTPUT | OMAP_VIDEO_ATTRIBUTES_BURST_8X128_BITS | OMAP_VIDEO_ATTRIBUTES_FORMAT_XRGB24_8888 | OMAP_VIDEO_ATTRIBUTES_ENABLED; WRITE_DISPLAY_REGISTER(OmapDisplayGraphicsAttributes, Value); Value = (OMAP_VIDEO_BUFFER_HIGH_THRESHOLD << OMAP_VIDEO_BUFFER_THRESHOLD_HIGH_SHIFT) | OMAP_VIDEO_BUFFER_LOW_THRESHOLD; WRITE_DISPLAY_REGISTER(OmapDisplayGraphicsBufferThreshold, Value); Value = OMAP_VIDEO_BUFFER_SIZE; WRITE_DISPLAY_REGISTER(OmapDisplayGraphicsBufferSize, Value); WRITE_DISPLAY_REGISTER(OmapDisplayGraphicsWindowSkip, 0); // // Set up the row and pixel increments to nothing fancy. // WRITE_DISPLAY_REGISTER(OmapDisplayGraphicsRowIncrement, 1); WRITE_DISPLAY_REGISTER(OmapDisplayGraphicsPixelIncrement, 1); // // Set the preload value to its default. // WRITE_DISPLAY_REGISTER(OmapDisplayGraphicsDmaPreload, OMAP4_VIDEO_PRELOAD_VALUE); // // Set the default color to red. // WRITE_DISPLAY_REGISTER(OmapDisplayDefaultColor0, 0x00FF0000); WRITE_DISPLAY_REGISTER(OmapDisplayDefaultColor1, 0x00FF0000); WRITE_DISPLAY_REGISTER(OmapDisplayDefaultColor2, 0x00FF0000); // // Configure all the pin polarities to their normal values. // WRITE_DISPLAY_REGISTER(OmapDisplayPolarity2, 0); // // Set up the dimensions to output to LCD2. // Value = ((FrameBufferWidth - 1) << OMAP_VIDEO_LCD_SIZE_X_SHIFT) | ((FrameBufferHeight - 1) << OMAP_VIDEO_LCD_SIZE_Y_SHIFT); WRITE_DISPLAY_REGISTER(OmapDisplayLcd2Size, Value); // // Set up the timing parameters. // Value = (OMAP4_HORIZONTAL_BACK_PORCH << OMAP_VIDEO_TIMING_HORIZONTAL_BACK_PORCH_SHIFT) | (OMAP4_HORIZONTAL_FRONT_PORCH << OMAP_VIDEO_TIMING_HORIZONTAL_FRONT_PORCH_SHIFT) | OMAP4_HORIZONTAL_SYNC_PULSE_WIDTH; WRITE_DISPLAY_REGISTER(OmapDisplayHorizontalTiming2, Value); Value = (OMAP4_VERTICAL_BACK_PORCH << OMAP_VIDEO_TIMING_VERTICAL_BACK_PORCH_SHIFT) | (OMAP4_VERTICAL_FRONT_PORCH << OMAP_VIDEO_TIMING_HORIZONTAL_FRONT_PORCH_SHIFT) | OMAP4_VERTICAL_SYNC_PULSE_WIDTH; WRITE_DISPLAY_REGISTER(OmapDisplayVerticalTiming2, Value); // // Set up the control 2 register to turn on LCD2. // Value = OMAP_VIDEO_CONTROL2_24_BIT_TFT_DATA | OMAP_VIDEO_CONTROL2_ACTIVE_TFT | OMAP_VIDEO_CONTROL2_LCD2_ENABLED; WRITE_DISPLAY_REGISTER(OmapDisplayControl2, Value); WRITE_DISPLAY_REGISTER(OmapDisplayControl2, Value | OMAP_VIDEO_CONTROL2_GO_LCD2); // // Wait for the pipeline to suck up the new parameters. // while (TRUE) { if ((READ_DISPLAY_REGISTER(OmapDisplayControl2) & OMAP_VIDEO_CONTROL2_GO_LCD2) == 0) { break; } } // // Clear any pending interrupts. // WRITE_DISPLAY_REGISTER(OmapDisplayInterruptStatus, 0xFFFFFFFF); return; }