i.MX8MP - Windows IoT Brightness Control

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

i.MX8MP - Windows IoT Brightness Control

172 Views
MRoesner
Contributor I

Hello,

we utilize Windows 10 IoT on our boards equipped with an imx8mp processor. For video output (on an integrated display), we use the Windows i.MX GPU driver provided by you, consisting of the GPU driver galcore.sys and the display controller driver dispctrl.dll.

Now, we would like to control the brightness of our display via the display controller driver. Unfortunately, the driver does not support brightness control. We know that brightness control is a board-specific activity, but we are wondering how we can communicate between Windows IoT (hotkeys/controllers) and your display controller driver, in case, for instance, the brightness is increased.

Our approach was as follows:

We were hoping that the system-supplied monitor driver (monitor.sys) would call the dxgkDdiQueryInterface method of your dispctrl.dll and request a specific Brightness Control Interface, which we would provide accordingly. However, the interface is never requested. What could be the reason for this?

Have you considered implementing brightness control in the GPU driver (dispctrl)? Do you have any other approach in mind?

0 Kudos
1 Reply

90 Views
AldoG
NXP TechSupport
NXP TechSupport

Hello,

I have contacted internal team for this, please see below:

This feature was not part of the SOW with Microsoft and as such was not implemented nor planed. We are occupied with testing of new BSP version at the moment, but we would like to have a look at after, if situation will allowed it.

Directions for the implementation of brightness control received from Microsoft are:

    For brightness control in GPU/display driver, please direct the customer to Supporting Brightness Controls on Integrated Display Panels - Windows drivers | Microsoft Learn

    We recommend the customer to implement DXGK_BRIGHTNESS_INTERFACE_2, Windows brightness UI calls into this interface's member functions for brightness control.

 

    This interface should be exposed from GcKmBaseDisplayController::QueryInterface().

    One quirk about the brightness interface is that QueryInterface->DeviceUid is DISPLAY_ADAPTER_HW_ID (-1)

    Conceptually we can think of brightness as a global state, so monitors have the same brightness/Windows doesn't change brightness of monitors individually.

 

    QueryInterface->Interface is a pointer of DXGK_BRIGHTNESS_INTERFACE_2, driver should follow MSDN doc to fill it in.

    The GcKmBaseDisplayController pointer can be return as DXGK_BRIGHTNESS_INTERFACE_2::Context

    

    For member functions of DXGK_BRIGHTNESS_INTERFACE_2, in general the Display Controller need to call Set functions for all active displays but handle Get functions by itself.

 

    The customer is probably using the LVDS or MIPI display, so they need to add a SetBrightness() virtual function to GcKmBaseDisplay and GcKmImx8mpDisplay (for LVDS) or GcKmImx8mpMipiDsiDisplay (for MIPI).

    Brightness control is not supported for external monitor like HDMI on Windows.

    It is best that GcKmBaseDisplay::SetBrightness() has an empty/default implementation.

 

    For sample code of driver interface, the customer can take a look at GcKmImx8mpHdmiDisplay::QueryInterface() for a custom audio interface.

 

    It is possible the customer uses PWM or I2C to control the panel's brightness,

    We do have some code for display controller to call into I2C driver, please see imx-windows-iot\driver\display\dispdll\os\windows\src\comm.cpp

    PWM flow should be similar.

// The display controller's code is in imx-windows-iot\driver\display\dispdll
NTSTATUS GcKmBaseDisplayController::QueryInterface(
    IN_PQUERY_INTERFACE QueryInterface)
{
    NTSTATUS    Status = STATUS_NOT_SUPPORTED;
    GcKmDisplay* pDisplayPipeline = FindDisplayPipeline(QueryInterface->DeviceUid);
    if (pDisplayPipeline) {
        Status = pDisplayPipeline->QueryInterface(QueryInterface);
    }
    return Status;
}

3: kd> dv
           this = 0xffffcd05`cc248000
 QueryInterface = 0xfffff20f`6b0fb910
         Status = <value unavailable>
//
// C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\km\dispmprt.h 
// DEFINE_GUID(GUID_DEVINTERFACE_BRIGHTNESS_2, 0x148A3C98, 0x0ECD, 0x465A, 0xB6, 0x34, 0xB0, 0x5F, 0x19, 0x5F, 0x77, 0x39);
3: kd> dx QueryInterface
QueryInterface                 : 0xfffff20f6b0fb910 [Type: _QUERY_INTERFACE *]
    [+0x000] InterfaceType    : 0xfffff80330750210 : {148A3C98-0ECD-465A-B634-B05F195F7739} [Type: _GUID *]
    [+0x008] Size             : 0x58 [Type: unsigned short]
    [+0x00a] Version          : 0x2 [Type: unsigned short]
    [+0x010] Interface        : 0xffffcd05caedd400 [Type: _INTERFACE *]
    [+0x018] InterfaceSpecificData : 0x0 [Type: void *]
    [+0x020] DeviceUid        : 0xffffffff [Type: unsigned long]
//
// QueryInterface() comes directly from dxgkrnl.sys, not monitor.sys. Later on monitor.sys calls into driver through dxgkrnl.sys

3: kd> k
 # Child-SP          RetAddr               Call Site
00 fffff20f`6b0fb800 fffff803`32e584e8     dispctrl!GcKmBaseDisplayController::QueryInterface+0x18 [C:\nxp-bsp\imx-windows-iot\driver\display\dispdll\GcKmdBaseDisplayController.cpp @ 174]
01 fffff20f`6b0fb830 fffff803`32e56b64     galcore!GcKmAdapter::QueryInterface+0x48 [N:\imx8m-3\drivers\wddmfw\lib\GcKmdAdapter.cpp @ 853]
02 fffff20f`6b0fb860 fffff803`3082d2c4     galcore!GcKmdDdi::DdiQueryInterface+0x64 [N:\imx8m-3\drivers\wddmfw\lib\GcKmdDdi.cpp @ 498]
03 fffff20f`6b0fb890 fffff803`3082d204     dxgkrnl!DpiDxgkDdiQueryInterface+0x74 [onecoreuap\windows\core\dxkernel\dxgkrnl\port\dpetw.cxx @ 412]
04 fffff20f`6b0fb900 fffff803`3082c1ac     dxgkrnl!DpiQueryMiniportInterface+0x4c [onecoreuap\windows\core\dxkernel\dxgkrnl\port\dpsup.cxx @ 2461]
05 fffff20f`6b0fb950 fffff803`3082c3f0     dxgkrnl!DpiBrightnessSetupInterfaceV2+0x4c [onecoreuap\windows\core\dxkernel\dxgkrnl\port\dpbright.cxx @ 457]
06 fffff20f`6b0fb990 fffff803`3082b708     dxgkrnl!DpiBrightnessStartDevice+0x98 [onecoreuap\windows\core\dxkernel\dxgkrnl\port\dpbright.cxx @ 581]
07 fffff20f`6b0fb9c0 fffff803`3082a8d4     dxgkrnl!DpiFdoStartAdapter+0x830 [onecoreuap\windows\core\dxkernel\dxgkrnl\port\dpfdo.cxx @ 13704]
08 fffff20f`6b0fbae0 fffff803`30843084     dxgkrnl!DpiFdoStartAdapterThreadImpl+0x2a4 [onecoreuap\windows\core\dxkernel\dxgkrnl\port\dpfdo.cxx @ 14743]
09 fffff20f`6b0fbce0 fffff802`e6020f1c     dxgkrnl!DpiFdoStartAdapterThread+0x34 [onecoreuap\windows\core\dxkernel\dxgkrnl\port\dpfdo.cxx @ 14207]
0a fffff20f`6b0fbd30 fffff802`e600c208     nt!PspSystemThreadStartup+0x4c [minkernel\ntos\ps\psexec.c @ 9746]
0b fffff20f`6b0fbd90 00000000`00000000     nt!KiStartSystemThread+0x20 [minkernel\ntos\ke\arm64\threadbg.asm @ 73] 

//
// C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\km\dispmprt.h 
typedef struct
{
    IN USHORT                                       Size;
    IN USHORT                                       Version;
    OUT PVOID                                       Context;
    OUT PINTERFACE_REFERENCE                        InterfaceReference;
    OUT PINTERFACE_DEREFERENCE                      InterfaceDereference;
    OUT DXGK_BRIGHTNESS_GET_POSSIBLE                GetPossibleBrightness;
    OUT DXGK_BRIGHTNESS_SET                         SetBrightness;
    OUT DXGK_BRIGHTNESS_GET                         GetBrightness;
    OUT DXGK_BRIGHTNESS_GET_CAPS                    GetBrightnessCaps;
    OUT DXGK_BRIGHTNESS_SET_STATE                   SetBrightnessState;
    OUT DXGK_BRIGHTNESS_SET_BACKLIGHT_OPTIMIZATION  SetBacklightOptimization;
    OUT DXGK_BRIGHTNESS_GET_BACKLIGHT_REDUCTION     GetBacklightReduction;
} DXGK_BRIGHTNESS_INTERFACE_2, *PDXGK_BRIGHTNESS_INTERFACE_2;

 
Best regards/Saludos,
Aldo.

0 Kudos