Fix issue with screen init causing brightness flickering and burn-in when booting HM after a splash on IPS panels

- previously, we left brightness voltage and LCD panel voltage on even though we disabled PWM and output signal, causing GSP to misdetect screen state in turn. Fix that (this fixes the issue mentioned above)

- Initialize the LCD controller over I2C, this fixes some rare sync issues some screen have with other Arm9 homebrew

This may not fix 100% of the issues, only the most egregious/dangerous
ones. There's still a lot of tech debt in Luma's baremetal code, that
necessitate a full rewrite to fix (not planned for this year)
This commit is contained in:
TuxSH 2025-07-03 21:02:27 +02:00
parent 59543da23d
commit 97cc70d35d
2 changed files with 36 additions and 3 deletions

View File

@ -40,6 +40,8 @@ typedef enum
I2C_DEV_CAMERA = 1, // Unconfirmed I2C_DEV_CAMERA = 1, // Unconfirmed
I2C_DEV_CAMERA2 = 2, // Unconfirmed I2C_DEV_CAMERA2 = 2, // Unconfirmed
I2C_DEV_MCU = 3, I2C_DEV_MCU = 3,
I2C_DEV_LCD_TOP = 5,
I2C_DEV_LCD_BOT = 6,
I2C_DEV_GYRO = 10, I2C_DEV_GYRO = 10,
I2C_DEV_DEBUG_PAD = 12, I2C_DEV_DEBUG_PAD = 12,
I2C_DEV_IR = 13, I2C_DEV_IR = 13,

View File

@ -70,6 +70,14 @@ void prepareArm11ForFirmlaunch(void)
void deinitScreens(void) void deinitScreens(void)
{ {
if(ARESCREENSINITIALIZED) invokeArm11Function(DEINIT_SCREENS); if(ARESCREENSINITIALIZED) invokeArm11Function(DEINIT_SCREENS);
// Backlight voltage off
I2C_writeReg(I2C_DEV_MCU, 0x22, 0x14);
wait(50);
// LCD panel voltage off
I2C_writeReg(I2C_DEV_MCU, 0x22, 0x01);
wait(50);
} }
void updateBrightness(u32 brightnessIndex) void updateBrightness(u32 brightnessIndex)
@ -102,8 +110,31 @@ void initScreens(void)
memcpy((void *)(ARM11_PARAMETERS_ADDRESS + 4), fbs, sizeof(fbs)); memcpy((void *)(ARM11_PARAMETERS_ADDRESS + 4), fbs, sizeof(fbs));
invokeArm11Function(INIT_SCREENS); invokeArm11Function(INIT_SCREENS);
//Turn on backlight // Fragile code, needs proper fix/total rewrite of the baremetal components anyway
I2C_writeReg(I2C_DEV_MCU, 0x22, 0x2A); // Assume controller revision is not 0x00 for either screen (this revision is extremely
// old and shouldn't be seen in retail units nor normal devunits)
// Controller reset off
I2C_writeReg(I2C_DEV_LCD_TOP, 0xFE, 0xAA);
I2C_writeReg(I2C_DEV_LCD_BOT, 0xFE, 0xAA);
wait(5);
// Controller power on
I2C_writeReg(I2C_DEV_LCD_TOP, 0x01, 0x10);
I2C_writeReg(I2C_DEV_LCD_BOT, 0x01, 0x10);
wait(5);
// Clear error flag
I2C_writeReg(I2C_DEV_LCD_TOP, 0x60, 0x00);
I2C_writeReg(I2C_DEV_LCD_BOT, 0x60, 0x00);
wait(5);
// LCD panel (bias ?) voltage on
I2C_writeReg(I2C_DEV_MCU, 0x22, 0x02);
wait(50);
// Backlight voltage on
I2C_writeReg(I2C_DEV_MCU, 0x22, 0x28);
wait(5); wait(5);
} }
else updateBrightness(MULTICONFIG(BRIGHTNESS)); else updateBrightness(MULTICONFIG(BRIGHTNESS));
@ -122,4 +153,4 @@ void initScreens(void)
void zerofillN3dsAblRegisters(void) void zerofillN3dsAblRegisters(void)
{ {
invokeArm11Function(ZEROFILL_N3DS_ABL_REGISTERS); invokeArm11Function(ZEROFILL_N3DS_ABL_REGISTERS);
} }