summaryrefslogtreecommitdiff
path: root/arch/arm/mach-mx6/mx6_ddr_freq.S
AgeCommit message (Collapse)Author
2014-10-07MLK-9664 [imx6x] Remove unused commented codeRanjani Vaidyanathan
Remove dead code. Signed-off-by: Ranjani Vaidyanathan <Ranjani.Vaidyanathan@freescale.com>
2014-10-06ENGR00334447 [imx6qdl] Fix random failures caused by ddr frequency change ↵Ranjani Vaidyanathan
procedure Backport busfreq patch from 3.10.x kernel: 2d1f2b76919e13d8744cc8579316c002f832c675 The ddr frequency change code was responsible for some random kernel crashes. This was due to the fact that L1 and L2 caches were not correctly flushed/synced during the frequency change procedure. This patch attempts to fix the issue by: 1. Ensure that every active core put into wfe flushes and disables its L1. 2. All cores (except the one executing the ddr freq change code) informs the SCU that it going into a power down state after flushing and disabling its L1. It also removes itself out the SMP cluster. 3. Variables shared across cores are stored in non-cacheable IRAM space. 4. SCU power status register is used to identify if all cores have reached a quiscent state before the core running the ddr freq change code proceeds further. Signed-off-by: Ranjani Vaidyanathan <Ranjani.Vaidyanathan@freescale.com>
2014-09-24ENGR00331050 [imx6qdl] Fix the workaround for ERR005778Ranjani Vaidyanathan
The DDR freq code had an incorrect workaround for ERR005778. ERR005778 MMDC: DDR Controller’s measure unit may return an incorrect value when operating below 100 MHz Workarounds: To workaround this issue, following steps should be performed by software: 1. Prior to reducing the DDR frequency (528 MHz), read the measure unit count bits (MU_UNIT_DEL_NUM). 2. Bypass the automatic measure unit when below 100 MHz, by setting the measure unit bypass enable bit (MU_BYP_EN). 3. Double the measure unit count value read in step 1 and program it in the measure unit bypass bit (MU_BYP_VAL) of the MMDC PHY Measure Unit Register, for the reduced frequency operation below 100 MHz. Software should re-enable the measure unit when operating at the higher frequencies, by clearing the measure unit bypass enable bit (MU_BYP_EN). This code should be executed out of Internal RAM or a non-DDR based external memory. This patch fixes the code to follow the workaround specified in the errata document. Signed-off-by: Ranjani Vaidyanathan <Ranjani.Vaidyanathan@freescale.com>
2014-08-28ENGR00320182 [iMX6DQ/iMX6DL] Fix bug in DLL off mode code in DDR3 frequency ↵Ranjani Vaidyanathan
change procedure A missing end of comment inadvertently ensured that the DLL off procedure was executed even when the DLL was already disabled (switching from 24MHz to 50MHz and vice-versa). This patch fixes the above issue. And also ensures that automatic entry into self-refresh is enabled for both DLL ON and DLL OFF modes. Signed-off-by: Ranjani Vaidyanathan <Ranjani.Vaidyanathan@freescale.com>
2014-06-06ENGR00316180: [iMX6x] Support IRAM page table when DDR is in self-refresh.Ranjani Vaidyanathan
Whenever DDR is explicitly put into self-refresh, we need to ensure that no access are made to the DDR. All the bus masters excpet ARM are shutdown gracefully. The ARM core can continue to access the DDR due to: 1. Speculative accesses This can be prevented by flushing the Branch Target Address Cache 2. Aggressive Prefetching This can be minimized by adding nops. Apart from this the TLB architecture in ARM does not guarantee that an entry remains in the TLB unless its explicitly locked. Even if free slots are available an entry maybe evicted. So flushing the TLB does not guarantee a page table walk will not happen. The solution is to put a minimized page table in IRAM that can be used when DDR is in self-refresh. The IRAM page tables should have entries for IRAM, AIPS1 and AIPS2 as these entries will be needed by the code that puts DDR into self-refresh. It should not contain any entries that point to the DDR. This patch set accomplishes the following: 1. Set the IRAM to be mapped as 1M sections in the high mem region. This makes it possible to create entries for the IRAM code in the IRAM page table. We need to ensure that both the DDR and IRAM page table have mapping for the IRAM code. 2. Ensure the IRAM, AIPS1, AIPS2 have entries in the IRAM page table. 3. Save TTBR1 4. Set TTBR1 to point to the page tables stored in IRAM. Switch to using TTBR1 before DDR is put into self-refresh. Ensure the following settings: a. TTBCR.N = 1 This means the 0-2G virtual address space is translated using TTBR0 and 2G-4G is translated using TTBR1. b. Set TTBCR.PD0 = 1 With this setting page table walks using TTBR0 are disabled. 4. After the DDR has exited self-refresh, reset TTBCR to 0 (TTBR0 will be used for translations now). 5. Restore TTBR1 Even though TTBR1 is only used to decode the top 2G of virtual address space, ARM requires that we allocate the entire 16KB for the page table. To minimize IRAM/OCRAM required, we put the code in the bottom 8K and page table entries in the top 8K. This requires the low power code be optimized to occupy as little space as possible. Only the WFI and suspend code that puts DDR into self-refresh is located in this 8k. The DDR frequency code that also puts the DDR into self-refresh need not be located in this 8K region. Currently this patch allocates a separate 4K region in IRAM for the DDR frequency change code. Additional conditions to be met: 1. Disable L2 when DDR is in self-refresh. 2. Ensure that L1 and branch prediction are disabled when we are switching to IRAM page tables, based on recommendation from ARM. This patch also dynamically calculate size of all the code that puts DDR into self-refresh (low power and ddr freq change). Signed-off-by: Ranjani Vaidyanathan <Ranjani.Vaidyanathan@freescale.com> (cherry picked from commit 67779bf67ebf4daddea33693f42cf01eced14bd9)
2014-06-03ENGR00262435 MX6x-Drain L1/L2 buffers before DDR enters self-refresh.Ranjani Vaidyanathan
The DDR freq change code and the low power WFI code in MX6SL runs from non-cacheable but bufferable IRAM space. Its possible for an eviction to occur from the L1 and/or L2 sync buffers after the DDR has been put into self-refresh. This will cause the system to hang. To avoid this ensure that the L1/L2 sync buffers are drained properly. Following is the info from ARM on L2 store buffers: ********************************************************** You can use L2 sync operation to drain L2store buffer manually, and the store buffer would be drained in such conditions: * store buffer slot is immediately drained if targeting device memory area * store buffer slots are drained as soon as they are full * store buffer is drained at each strongly ordered read occurrence in slave ports * store buffer is drained at each strongly ordered write occurrence in slave ports * as soon as all three slots of the store buffer contain data, the least recently accessed slot starts draining * if a hazard is detected in a store buffer slot , that slot is drained to resolve the hazard * store buffer slots are drained when a lock ed transaction is received by one slave port * store buffer slots are drained when a transaction targeting the configuration registers is received by one slave port * store buffer slots are automatically drained after 256 cycles of presence in the store buffer. You can refer to 2.5.3 Store buffer operation of PL310 trm(r3p3, DDI0246H) for the detail. You have to apply the explicit cache sync operation, which should be followed by DSB, before entering the low power mode. And the bit0 of the cache sync register(base offset 0x730) should be polling to guarantee that the PL310 has finished sync operation. PL310 owns three 256 bit entry store buffer & eviction buffer, and four 256 bit LFB & LRB, and Cache sync would complete when all buffers, LRB, LFB, STB, and EB, are empty. The actual overhead should be close to your L3 access latency. ************************************************************************* ~ ~ Signed-off-by: Ranjani Vaidyanathan <ra5478@freescale.com>
2014-06-03ENGR00237742 busfreq:fix IPG_PERCLK will be decreased to 6M once exit low busRobin Gong
on Sabresd board, IPG_PERCLK will be fixed on 6Mhz once system enter low bus, and never restore to 22Mhz which be set in boot. It means some device clock which sourcing from IPG_PERCLK such as I2C will be slow down. The root cause is that there is workaround for GPT timer of Arik TO1.0 in mx6_ddr_freq.S. GPT clock source from IPG_PERCLK on TO1.0 and should be fixed on 6Mhz. But for TO1.1 and TO1.2 ,the workaround should be removed. Signed-off-by: Robin Gong <B38343@freescale.com>
2014-06-03ENGR00214810 [MX6]Fix bus freq 50M->528M change issueAnson Huang
50M -> 528M bus freq change will cause system hang, root cause is that we didn't set 50M as DLL off mode, it should be DLL off mode. And make sure bus, axi, ahb, ipg and ipg_perclk are at right freq during all setpoints. Can't disable PU LDO again if it is not enabled. Signed-off-by: Anson Huang <b20788@freescale.com>
2014-06-03ENGR00180919 [MX6]Update clock tree if BUS freq is changedAnson Huang
As DDR freq change is by modifying CCM register directly, we need to update the clock tree as well, or the clock tree will be broken. Also, we need to make sure the clock rate counting is right. Signed-off-by: Anson Huang <b20788@freescale.com>
2014-06-03ENGR00209621 MX6-Fixed random CON_ACK stallRanjani Vaidyanathan
DLL ON/OFF code randomly hangs waiting for the CON_ACK bit to be set when a CON_REQ is asserted. Fix this by adding a delay after the MMDC automatic power savings mode is disabled. Signed-off-by: Ranjani Vaidyanathan <ra5478@freescale.com>
2014-06-03ENGR00181068: MX6 Source IPU_HSP and AXI clocks from 540M PFD.Ranjani Vaidyanathan
IPU_HSP clocks should NOT be sourced from MMDC clock since the MMDC clock can be scaled. Move the IPU_HSP clock to be sourced from PLL3_PFD_540M instead. Also don't source AXI_CLK from periph_clk as this domain is scaled between 528MHz, 400MHz and 24MHz. Move AXI_CLK clock to be sourced from PLL3_PFD_540M too. When the system needs to enter low power mode, AXI_CLK is switched from PLL3_PFD_540M to periph_clk. And then switched back when low power mode is exited. The code will print a warning message if PLL3_PFD_540M is relocked to a different frequency when IPU_HSP or axi_clk is sourced from it. Currently remove the support for 400Mhz DDR working point for MX6Q since we can get IPU underruns during the DDR frequency transitions. The DDR freq change code needs to ensure that all bus clocks donot exceed max frequency during the frequency transition. Signed-off-by: Ranjani Vaidyanathan <ra5478@freescale.com>
2014-06-03ENGR00180882- MX6DL Add bus frequency scaling support.Ranjani Vaidyanathan
Added support for changing DDR frequency on MX6DL. During system IDLE, DDR freq can drop down to 24MHz if none of the devices that need high AHB frequency are active. Changed the DDR code to handle both MX6Q and MX6DL DDR and IOMUX settings. Fixed bug associated incorrect IRAM memory allocation used to store DDR and IOMUX data. Signed-off-by: Ranjani Vaidyanathan <ra5478@freescale.com>
2014-06-03ENGR00180185: MX6-Add support for low power audio playbackRanjani Vaidyanathan
The DDR frequency needs to be at 50MHz for low power audio playback. So added a new low power mode for audio. Set the AHB to 25MHz, AXI to 50MHz and DDR to 50MHz in this mode. Signed-off-by: Ranjani Vaidyanathan <ra5478@freescale.com>
2014-06-03ENGR00179574: MX6- Add bus frequency scaling supportRanjani Vaidyanathan
Add support for scaling the bus frequency (both DDR and ahb_clk). The DDR and AHB_CLK are dropped to 24MHz when all devices that need high AHB frequency are disabled and the CORE frequency is at the lowest setpoint. The DDR is dropped to 400MHz for the video playback usecase. In this mode the GPU, FEC, SATA etc are disabled. To scale the bus frequency, its necessary that all cores except the core that is executing the DDR frequency change are in WFE. This is achieved by generating interrupts on un-used interrupts (Int no 139, 144, 145 and 146). Signed-off-by: Ranjani Vaidyanathan <ra5478@freescale.com>