Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/arm11/drivers/pdn.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ void PDN_core123Init(void);
void PDN_setSocmode(PdnSocmode socmode);
void PDN_poweroffCore23(void);
void PDN_controlGpu(const bool enableClk, const bool resetPsc, const bool resetOther);
void PDN_sleep(void);
void PDN_wakeup(void);

#ifdef __cplusplus
} // extern "C"
Expand Down
31 changes: 17 additions & 14 deletions source/arm11/drivers/gfx.c
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,8 @@ void GX_processCommandList(const u32 size, const u32 *const cmdList)

void GFX_sleep(void)
{
GFX_setForceBlack(true, true);

const GfxState *const state = &g_gfxState;
LCD_deinit(state->mcuLcdState);

Expand All @@ -567,30 +569,30 @@ void GFX_sleep(void)
// Stop display controllers.
stopDisplayControllersSafe();

for(u8 i = 0; i < 6; i++)
{
unbindInterruptEvent(IRQ_PSC0 + i);
}

// Wait for at least 1 horizontal line. 40 µs in this case.
// 16713.680875044929009032708 / 413 = 40.468960956525251837852 µs.
// TODO: 40 µs may not be enough in legacy mode?
TIMER_sleepUs(40);

// Flush caches to VRAM.
flushDCacheRange((void*)VRAM_BASE, VRAM_SIZE);
flushDCacheRange((void*)VRAM_BASE, VRAM_SIZE);

// Disable VRAM banks. This is needed for PDN sleep mode.
GxRegs *const gx = getGxRegs();
gx->psc_vram |= PSC_VRAM_BANK_DIS_ALL;

// Stop clock.
PDN_controlGpu(false, false, false);
}

void GFX_sleepAwake(void)
{
// Resume clock and reset PSC.
PDN_controlGpu(true, true, false);
for(u8 i = 0; i < 6; i++)
{
bindInterruptToEvent(g_gfxState.events[i], IRQ_PSC0 + i, 14);
}

// Restore PSC settings.
GxRegs *const gx = getGxRegs();
gx->psc_vram &= ~PSC_VRAM_BANK_DIS_ALL;
gx->gpu_clk = 0x70100;
gx->psc_fill0.cnt = 0;
gx->psc_fill1.cnt = 0;
Expand All @@ -610,7 +612,7 @@ void GFX_sleepAwake(void)
// Since both PDCs are not reset in sleep mode this is not strictly necessary.
// Warning: If we decide to change this to a full reinit restore the mode!
const GfxState *const state = &g_gfxState;
gx->pdc0.swap = state->swap; // Bit 1 is not writable.
gx->pdc0.swap = state->swap; // Bit 1 is not writable.
gx->pdc1.swap = state->swap>>1;
gx->pdc0.cnt = PDC_CNT_OUT_EN | GFX_PDC0_IRQS | PDC_CNT_EN;
gx->pdc1.cnt = PDC_CNT_OUT_EN | GFX_PDC1_IRQS | PDC_CNT_EN;
Expand All @@ -620,15 +622,16 @@ void GFX_sleepAwake(void)
// Power on LCDs and backlights.
LCD_init(state->mcuLcdState<<1, state->lcdLum);

// Active backlight and luminance stuff.
// TODO

// Not from gsp. Wait for VRAM clear finish.
GFX_waitForPSC0();
GFX_waitForPSC1();

// Enable frame buffer output.
GFX_setForceBlack(false, false);

GFX_waitForVBlank0();
GFX_waitForVBlank0();
}

bool GFX_setupExceptionFrameBuffer(void)
Expand Down Expand Up @@ -662,4 +665,4 @@ bool GFX_setupExceptionFrameBuffer(void)
gx->pdc1.swap = PDC_SWAP_IRQ_ACK_ALL; // Set to single buffer mode.

return true;
}
}
35 changes: 35 additions & 0 deletions source/arm11/drivers/pdn.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include "arm11/start.h"
#include "util.h"
#include "arm11/drivers/scu.h"
#include "kevent.h"
#include "arm11/drivers/gx.h"


//#define CORE123_INIT (1)
Expand Down Expand Up @@ -212,4 +214,37 @@ void PDN_controlGpu(const bool enableClk, const bool resetPsc, const bool resetO
wait_cycles(12); // 4x the needed cycles in case we are in LGR2 mode.
pdn->gpu_cnt = reg | PDN_GPU_CNT_NORST_ALL;
}
}

static void pdn_isr(UNUSED u32 intSource)
{
getPdnRegs()->wake_enable = 0;
getPdnRegs()->wake_reason = PDN_WAKE_SHELL_OPENED;
}

void PDN_sleep(void)
{
IRQ_registerIsr(IRQ_PDN, 14, 0, pdn_isr);
getPdnRegs()->wake_enable = PDN_WAKE_SHELL_OPENED;

if (getPdnRegs()->cnt & PDN_CNT_VRAM_OFF)
{
// Disable VRAM banks. This is needed for PDN sleep mode.
GxRegs *const gx = getGxRegs();
gx->psc_vram |= PSC_VRAM_BANK_DIS_ALL;
}

getPdnRegs()->cnt |= PDN_CNT_SLEEP;

// turning off Gpu needs to be done after sleeping
PDN_controlGpu(false, false, false);
__wfi();
}

void PDN_wakeup(void)
{
PDN_controlGpu(true, true, false);
GxRegs *const gx = getGxRegs();
gx->psc_vram &= ~PSC_VRAM_BANK_DIS_ALL;

}