Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fixed] UHD 630 No HDMI audio #1189

Closed
black-dragon74 opened this issue Sep 29, 2020 · 7 comments
Closed

[Fixed] UHD 630 No HDMI audio #1189

black-dragon74 opened this issue Sep 29, 2020 · 7 comments

Comments

@black-dragon74
Copy link

This issue has been around since long on the select UHD 630 iGPUs and nobody has had any success so far (none that I know of). This seems to mostly affect ASUS CFL laptops. I did a bit of research and I'm gonna post my findings here for someone to look at it and provide his/her insights on this issue. I'm also gonna list a partial fix for the HDMI video just in case someone ends up here with this issue.

Here are the specifications of my system:
CPU: i7-8750H (issue exists on i5-8300H too)
GPU: Intel UHD 630 (GTX 1050Ti disabled)
Audio Codec: Realtek ALC 295 (alc-layout-id: 0xE)
Video Ports: eDP, HDMI and DP (index 0x00, 0x01 and 0x02 respectively)

The initial issue was of no HDMI video output. This was quite a pain to fix but the fix was to change the bus-id of HDMI port (index 0x1) to 0x1. In the attached debug files one can see that I have disabled the DP port as I don't use it by changing it's index value. I have also changed the pipe values from default to 0xA but this has no effect on HDMI Audio/Video whatsoever.

Also, one will still face HDMI hot-plug issue which can be easily fixed by enabling the complete-modeset property and by providing the list of affected indexes using complete-modeset-framebuffers property (00 01 ff ff ff ff ff ff for LVDS and HDMI modeset).

After the above steps, HDMI Video will work 100% reliably. If one still faces issues, it's a misconfiguration of something else on his/her end.

Now coming to the elephant in the room, HDMI Audio. I started investigating on this quite a while ago. The initial discussions can be found here. It was impossible to get the HDMI Audio to work under any cases. Tried methods include changing ig-platform-id, layout-id, pipe, port, connector-type, trying with DP cable (and port) instead of HDMI, Faking the device-id. None of these work. I eventually gave up all the hope until I accidentally stumbled upon a potential fix maybe? (expert suggestions and reviews needed).

I had my eDP cable unplugged as I was doing some repairs. I turned on my machine and connected the HDMI cable. I was surprised to find HDMI Audio working OOB. So, I guessed it has something to do with internal display. After reconnecting the eDP cable, I disabled the internal display by patching it's index using WEG. As expected, the HDMI audio still worked without any additional patches.

As eDP is a variant of DP, I thought maybe due to some weird reason, it might be the cause. Hence, I tried changing the connector-type of internal display to Dummy/VGA, DP, HDMI. The internal display worked in all cases and HDMI Audio didn't.

The technical findings from the above experiments are:

  • DigitalAudioCapabilities property (dict) not being injected on HDEF
  • AppleHDAHDMI_DPDriver not loading when internal display is connected
  • PinConfigurations property is 4 bytes shorter when HDMI audio is not working (tried injecting the longer property, doesn't help)

Also, the checklist for working HDMI audio is completely checked and is in place (one can verify from the attached files)

Description of attached files:
HDAU_eDP_Unplugged is when HDMI Audio is working but eDP cable is unplugged.
HDAU_eDP_Disabled is when HDMI Audio is working but eDP is disabled (index set to 0xFFFFFFFF)
NoHDAU_eDP_Plugged is when HDMI Audio is not working with internal display and analog audio working.
DEBUG FILE: HDAU_Debug.zip

Regards

@black-dragon74
Copy link
Author

I managed a bit more of free time and I'm happy to say that the fix for this issue has been found. We now know that CNUnknownFlag_100 has something to do with HDMI Audio. Adding this flag results in working HDMI audio. Tested on 2 affected systems and it seems to work. No further edits are required. Like, for ig-platform-id 0x3e9b0000 you would have to add 100 to the existing flags for index 0. The stock flags for index 0 were 0x98, after applying the fix the flags would be: 0x198.

@vit9696 maybe you have any insights on it's inner workings? Sorry but I haven't been able to dig too deep just yet.

CC: @headkaze, @andreszerocross, @Bimoaryo5

@black-dragon74 black-dragon74 changed the title [WHATEVERGREEN] UDH630 No HDMI audio [Fixed] UDH630 No HDMI audio Sep 29, 2020
@black-dragon74 black-dragon74 changed the title [Fixed] UDH630 No HDMI audio [Fixed] UHD 630 No HDMI audio Sep 29, 2020
@vit9696
Copy link
Contributor

vit9696 commented Oct 2, 2020

Interesting find, but I am not sure I can look at it any soon. Maybe ping more people. CC @khronokernel @headkaze

@07151129
Copy link

07151129 commented Oct 7, 2020

This makes sense. Basically, these flags indicate whether a power well should be used by the driver. When reading power well state in AppleIntelFramebufferController::getPowerWellState:

__int64 __cdecl AppleIntelFramebufferController::getPowerWellState(AppleIntelFramebufferController *this, AppleIntelFramebuffer *fb)
{
  __int64 v2; // rax
  __int64 v3; // r12
  __int64 v4; // r14
  __int64 v5; // rax
  unsigned __int64 v6; // rbx
  __int8 v7; // r9
  __int8 v8; // r15
  __int8 v9; // r8
  char fb_nr; // cl
  __int64 v11; // rdx
  __int64 v12; // rdx
  __int64 pwr_well_ctl2; // rax
  char SKL_PW_CTL_IDX_PW_2; // si
  bool SKL_PW_CTL_IDX_PW_1; // bl
  char SKL_PW_CTL_IDX_DDI_B; // r11
  bool SKL_PW_CTL_IDX_DDI_A_E; // cl
  char SKL_PW_CTL_IDX_DDI_D; // r10
  bool v19; // r14
  char SKL_PW_CTL_IDX_MISC_IO; // di

  if ( fb )
  {
    if ( LODWORD(fb->fNumDisplayPath) )
    {
      v5 = v2 + 1;
      v6 = 0LL;
      v7 = 0;
      v8 = 0;
      v9 = 0;
      do
      {
        fb_nr = fb->fDisplayPath[v6]->framebufferNumber;
        v11 = (fb->fDisplayPath[v6]->fDisplayFlags >> 7) & 1;
        v4 += v11;
        v7 |= v11 << fb_nr;
        v12 = (fb->fDisplayPath[v6]->fDisplayFlags >> 8) & 1;
        v3 += v12;
        v8 |= v12 << fb_nr;
        v9 |= 1 << fb_nr;
        ++v6;
        v5 += 3LL;
      }
      while ( v6 < LODWORD(fb->fNumDisplayPath) );
    }
    else
    {
      v9 = 0;
      v8 = 0;
      v7 = 0;
    }
  }
  else
  {
    v7 = this->use_SKL_PW_CTL_IDX_MISC_IO;
    v8 = this->use_SKL_PW_CTL_IDX_PW_2;
    v9 = this->use_SKL_PW_CTL_IDX_DDI;
  }
  pwr_well_ctl2 = (LODWORD(this->member881) - 4);
  if ( pwr_well_ctl2 < 0x45405 )
  {
    SKL_PW_CTL_IDX_MISC_IO = 1;
    v19 = 1;
    SKL_PW_CTL_IDX_DDI_A_E = 1;
    SKL_PW_CTL_IDX_PW_1 = 1;
    SKL_PW_CTL_IDX_PW_2 = 1;
    SKL_PW_CTL_IDX_DDI_B = 1;
    SKL_PW_CTL_IDX_DDI_D = 1;
    goto LABEL_18;
  }
  pwr_well_ctl2 = *(this->mmio + HSW_PWR_WELL_CTL2);
  SKL_PW_CTL_IDX_PW_2 = 1;
  SKL_PW_CTL_IDX_PW_1 = !_bittest(&pwr_well_ctl2, 0x1Cu);// SKL_PW_CTL_IDX_PW_1
  if ( _bittest(&pwr_well_ctl2, 0x1Eu) )        // SKL_PW_CTL_IDX_PW_2
    SKL_PW_CTL_IDX_PW_2 = 0;
  SKL_PW_CTL_IDX_DDI_B = 1;
  SKL_PW_CTL_IDX_DDI_A_E = (pwr_well_ctl2 & 4) == 0;// SKL_PW_CTL_IDX_DDI_A_E
  if ( (pwr_well_ctl2 & 0x10) != 0 )            // SKL_PW_CTL_IDX_DDI_B
    SKL_PW_CTL_IDX_DDI_B = 0;
  SKL_PW_CTL_IDX_DDI_D = 1;
  v19 = (pwr_well_ctl2 & 0x40) == 0;            // SKL_PW_CTL_IDX_DDI_C
  if ( _bittest(&pwr_well_ctl2, 8u) )           // SKL_PW_CTL_IDX_DDI_D
    SKL_PW_CTL_IDX_DDI_D = 0;
  SKL_PW_CTL_IDX_MISC_IO = 1;
  if ( (pwr_well_ctl2 & 1) != 0 )               // SKL_PW_CTL_IDX_MISC_IO
  {
    SKL_PW_CTL_IDX_MISC_IO = 0;
LABEL_18:
    ++*pwr_well_ctl2;
  }
  LOBYTE(pwr_well_ctl2) = 1;
  if ( v7 && SKL_PW_CTL_IDX_PW_1 )
    pwr_well_ctl2 = 0LL;
  if ( v8 && SKL_PW_CTL_IDX_PW_2 )
    pwr_well_ctl2 = 0LL;
  if ( v7 && SKL_PW_CTL_IDX_MISC_IO )
    pwr_well_ctl2 = 0LL;
  if ( (v9 & 1) != 0 && SKL_PW_CTL_IDX_DDI_A_E )
    pwr_well_ctl2 = 0LL;
  if ( (v9 & 2) != 0 && SKL_PW_CTL_IDX_DDI_B )
    pwr_well_ctl2 = 0LL;
  if ( (v9 & 4) != 0 && v19 )
    pwr_well_ctl2 = 0LL;
  if ( (v9 & 8) != 0 )
  {
    if ( SKL_PW_CTL_IDX_DDI_D )
      pwr_well_ctl2 = 0LL;
  }
  return pwr_well_ctl2;                         // if flags indicate interest in a PW, and its state was 0, also return 0
}

The usage of variables v7 to v9 indicates interest in a power well. Now, for setting a power well state we have similar code:

 if ( a2 && LODWORD(a2->fNumDisplayPath) )
  {
    v7 = this->use_SKL_PW_CTL_IDX_MISC_IO;
    v8 = this->use_SKL_PW_CTL_IDX_PW_2;
    v25 = this;
    LOBYTE(this) = this->use_SKL_PW_CTL_IDX_DDI;
    v9 = &v25->vtable + 1;
    v10 = 0LL;
    do
    {
      fb_nr = a2->fDisplayPath[v10]->framebufferNumber;
      v3 += (a2->fDisplayPath[v10]->fDisplayFlags & 0x80LL) != 0;// unused?
      v12 = v7 & ~(1 << fb_nr) | ((set & (a2->fDisplayPath[v10]->fDisplayFlags >> 7)) << fb_nr);
      v4 += BYTE1(a2->fDisplayPath[v10]->fDisplayFlags) & 1;// unused?
      v13 = v8 & ~(1 << fb_nr) | ((set & (a2->fDisplayPath[v10]->fDisplayFlags >> 8)) << fb_nr);
      LODWORD(this) = this & ~(1 << fb_nr) | (set << fb_nr);
      ++v10;
      v9 += 3;
      v8 = v13;
      v7 = v12;
    }
    while ( v10 < LODWORD(a2->fNumDisplayPath) );
    v6 = v25;
    v25->use_SKL_PW_CTL_IDX_MISC_IO = v12;
    v25->use_SKL_PW_CTL_IDX_PW_2 = v13;
    v25->use_SKL_PW_CTL_IDX_DDI = this;
    v5 = set;
  }

...

v17 = v6->use_SKL_PW_CTL_IDX_PW_2;
  v18 = ((v17 != 0) << 31) | v16 | (2 * (v6->use_SKL_PW_CTL_IDX_MISC_IO != 0));
  if ( v17 )
  {
    if ( _bittest(&v14, 0x1Eu) )
      goto LABEL_38;
    AppleIntelFramebufferController::hwWriteMailbox(v6, 0x21u, 0);
    AppleIntelFramebufferController::hwSetPowerWellState(v6, v5, v18);
    IODelay(1u);
    if ( LODWORD(v6->member881) - 4 <= SKL_FUSE_STATUS || !_bittest((v6->mmio + SKL_FUSE_STATUS), 0x19u) )
    {
      if ( (v6->member878 & 0x10) != 0 )
        panic(
          "\"[IGFB][PANIC] \" \"PG2 fuse distribution failed\\n\"@/Library/Caches/com.apple.xbs/Sources/GPUDriversIntel/G"
          "PUDriversIntel-12.10.16/Common/IONDRV/Intel/CFL/AppleIntelFramebuffer/AppleIntelController.cpp:6416");
      kprintf("[IGFB][ERROR  ] PG2 fuse distribution failed\n");
    }
    v14 = LODWORD(v6->member881) - 4 <= HSW_PWR_WELL_CTL2 ? 0 : *(v6->mmio + HSW_PWR_WELL_CTL2);
    AppleIntelFramebufferController::resetAudioRegisters(v6);
    if ( !BYTE1(v6->member1772) )
      goto LABEL_38;
    if ( LODWORD(v6->member881) - 4 <= &dword_138154 )
      v19 = -2147483647;
    else
      v19 = *(v6->mmio + 0x138154) | 0x80000001;
    goto LABEL_37;
  }

Flag 0x100 corresponds to SKL_PW_CTL_IDX_PW_2, and 0x80 to use_SKL_PW_CTL_IDX_MISC_IO. resetAudioRegisters is called when 0x100 is set. Furthermore, it is known that audio is in power domain of PW2:

#define SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS (		\
	BIT_ULL(POWER_DOMAIN_TRANSCODER_A) |		\
	BIT_ULL(POWER_DOMAIN_PIPE_B) |			\
	BIT_ULL(POWER_DOMAIN_TRANSCODER_B) |		\
	BIT_ULL(POWER_DOMAIN_PIPE_C) |			\
	BIT_ULL(POWER_DOMAIN_TRANSCODER_C) |		\
	BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) |		\
	BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) |		\
	BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) |		\
	BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) |		\
	BIT_ULL(POWER_DOMAIN_PORT_DDI_D_LANES) |		\
	BIT_ULL(POWER_DOMAIN_PORT_DDI_E_LANES) |		\
	BIT_ULL(POWER_DOMAIN_AUX_B) |                       \
	BIT_ULL(POWER_DOMAIN_AUX_C) |			\
	BIT_ULL(POWER_DOMAIN_AUX_D) |			\
	BIT_ULL(POWER_DOMAIN_AUDIO) |			\
	BIT_ULL(POWER_DOMAIN_VGA) |				\
	BIT_ULL(POWER_DOMAIN_INIT))

vit9696 added a commit to acidanthera/WhateverGreen that referenced this issue Oct 7, 2020
@black-dragon74
Copy link
Author

Perfect. Thank you so much @07151129 for your investigation.

@mackonsti
Copy link

mackonsti commented Apr 1, 2021

Hi @black-dragon74 thank you from me too for your investigation results. I wanted to post my situation for you and @vit9696 to perhaps comment. Here are my details on my Intel NUC 10 with Core i7-10710U (no other GFX card, only IGPU):

  • Big Sur 11.2.3 on Intel ; WhateverGreen official release 1.4.8 ; OpenCore v0.6.7 ; AppleALC v1.5.8 (all latest)
  • lspci reports Intel Corporation Comet Lake UHD 630 Graphics [8086:9bca]
  • lspci reports Intel Corporation High Definition Audio Controller [8086:02c8] or in other terms ALC256 (ALC3246)
  • After few tests, to activate acceleration for this UHD 630 Graphics IGPU in OpenCore, I have to define both needed IDs without any other change whatsoever (i.e. no further patching, no change of pipes, connectors, bus ID, flags, index):
    AAPL,ig-platform-id = 0x3E9B0007
    device-id = 0x3E9B0000
  • This platform/device shows 3 connectors (plus dummy) ; I connect via USB-C-to-DisplayPort on my monitor, but previous HDMI connection resulted to the same lack of HDMI or Digital Audio.

Although not sure how to force flags, in Hackintool.app (tab Patch > Connectors > Active connection list) in the flags list displayed, I do see CNUnknownFlag_100 being checked/active alongside others... All 3 connectors are shown as "DP" and with the same flags 0x000003C7.

  • So I was wondering what is your reported IGPU device ID @black-dragon74 and how do you define it in config.plist ?
  • I confirm having hda-gfx=onboard-1 on both HDEF and IGPU; any idea if the alcid choice of codec plays some part in the Digital Audio detection? I could not confirm that anywhere in the various threads.
  • Would either -igfxnohdmi and igfxfw boot arguments have any impact on Digital Audio perhaps @vit9696 ?

Thank you in advance, looking to receiving your feedback from both of you, let me know if you need any more details.

@asrath242
Copy link

@mackonsti Hehoo, I am facing a similar problem. Have an ASROCK Z490 PGITX/TB3 and i7-10700K, 11.2.3 installation was easy with OC. Even the only iGPU gave 4k and 60Hz out of the box using HDMI, but no sound. Hackintool only shows the alc (1220) under sound, regardless if I connect the display by HDMI, a usb-c to HDMI cable or by my tb3 dock.

By mistake I connected an old screen by usb-c, while my main screen was still connected by HDMI and baaam, both displays popped up in the sound app, giving me the option to play sound by hdmi on both devices. Closer look shows in hackintool, that an additional new device was presented under sound (Intel Kabylake HDMI) and a AppleHDAHDMI_DPDriver was loaded to it. I could even disconnect on display and still use the other to play sound via HDMI - till next reboot. So in short: I con only play sound via HDMI, when the board is connected by two cablles either to two displays or to two HDMI ports on one display. I cant get sound to work with only on connection. I am still unable to trigger the Intel Kabylake HDMI to load following @black-dragon74 idea.

Perhaps give it a try and connect two displays before booting to check.

@Asturias05
Copy link

I do not understand much of all thats is discused here. What can I do to fix the audio problem with the HDMI port?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

8 participants
@mackonsti @07151129 @vit9696 @black-dragon74 @Andrey1970AppleLife @asrath242 @Asturias05 and others