-
Notifications
You must be signed in to change notification settings - Fork 7
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
Add PDN_sleep and PDN_wakeup #2
base: master
Are you sure you want to change the base?
Conversation
source/arm11/drivers/gfx.c
Outdated
GFX_waitForVBlank0(); | ||
GFX_waitForVBlank0(); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a little confused why you added new functions here. GFX_sleep() and GFX_sleepAwake() were supposed to be the functions to call to bring the GFX driver into and out of sleep state.
The problem that PDN stuff is hardcoded in this driver also remains.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you so much for your comment. My apologies, I think when playing around, I was trying to first get the old function from the old commit to work, and rebase. I think I forgot to remove these 2 functions. I intend to use the GFX_sleep and GFX_sleepAwake.
Let me try to address your other comments...
source/arm11/drivers/gfx.c
Outdated
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; | ||
displayControllerInit(GFX_TOP_2D); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note the warning i had in the comments. If we fully reinitialize PDC here the current display mode is not restored. For example 2D, 3D or wide mode.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have reverted this change. Turns out I made a mistake in the open agb firm changes which errorneously made me think this was required.
source/arm11/drivers/pdn.c
Outdated
waitForEvent(pdnWakeEvent); | ||
getPdnRegs()->wake_enable = 0; | ||
getPdnRegs()->wake_reason = PDN_WAKE_SHELL_OPENED; | ||
unbindInterruptEvent(IRQ_PDN); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me summarize what i know about hardware sleep mode:
HOS first notifies the sysmodules about sleep so they can prepare sleep mode. This is for example the GFX_sleep() function that's being called. Other ones to call are CODEC_deinit() (poorly documented, sleep is basically the same as deinit). And the power LED is set to the sleep mode animation via the MCU.
After all the hardware we don't need in sleep mode is in sleep mode Kernel11 does check this bit:
https://github.com/profi200/libn3ds/blob/master/include/arm11/drivers/pdn.h#L71
If it's set it does extra steps to disable VRAM banks and clock via:
https://github.com/profi200/libn3ds/blob/master/include/arm11/drivers/pdn.h#L103
Then it disables FCRAM clock. In GBA mode we already did this but just for reference:
https://github.com/profi200/libn3ds/blob/master/include/arm11/drivers/pdn.h#L114
https://github.com/profi200/libn3ds/blob/master/source/arm11/drivers/lgy11.c#L59
Then finally comes the sleep mode part. This bit is set and the CPU has to enter wait for interrupt state somewhere. This would likely be the kernel idle thread if nothing has to be done:
https://github.com/profi200/libn3ds/blob/master/include/arm11/drivers/pdn.h#L70
I think PDN wake reasons are managed externall by some sysmodule. Not sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have modified this part again.
I have moved the PDN related function calls from gfx.c to pdn.c, so disabling GPU clock and VRAM now is handled by pdn.c
I haven't implemented disabling FCRAM clock mostly because I'm not familiar with it, and my motivation is mostly on the GBA side, but please let me know if here's any reference that I can follow, especially for re-enabling it after waking up.
After testing with the sleep mode again, it seems that calling _wfi is enough to ensure that it stays asleep until next interrupt, which is when the lid is opened again. I haven't found other source of interrupt other than opening the lid when it's sleeping, so I'm guessing it would work.
As for PDN wake reasons, from my testing, it doesn't seem to do anything other than flags for the developer. i.e., I could change it to PDN_WAKE_TOUCHPEN_DOWN
and it will still behave the same.
I have reverted the previous use of bindEvent on IRQ_PDN, since it seems there are different expectations of what should happen during the ISR of sleep mode.
GFX_enterLowPowerState and GFX_returnFromLowPowerState was introduced because the branch was based on old commmit
PDN_sleep now blocks. Also, controlling pdn is now done in pdn.c instead of gfx.c
Supersedes #1
This change is mostly to support open_agb_firm sleep functionality.
Waking up from sleep is achieved by binding IRQ_PDN to a handler and disabling wake_enable and confirming by writing to wake_reason.