summaryrefslogtreecommitdiff
path: root/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/mips/ingenic_jz47xx/system-jz4740.c')
-rw-r--r--firmware/target/mips/ingenic_jz47xx/system-jz4740.c171
1 files changed, 171 insertions, 0 deletions
diff --git a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
index 48fb192810..c741d9f311 100644
--- a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
@@ -663,6 +663,168 @@ void dma_disable(void)
663 } 663 }
664} 664}
665 665
666static inline void pll_convert(unsigned int pllin, unsigned int *pll_cfcr, unsigned int *pll_plcr1)
667{
668 register unsigned int cfcr, plcr1;
669 int div[5] = {1, 3, 3, 3, 3}; /* divisors of I:S:P:L:M */
670 int nf;
671
672 cfcr = CPM_CPCCR_CLKOEN |
673 (div[0] << CPM_CPCCR_CDIV_BIT) |
674 (div[1] << CPM_CPCCR_HDIV_BIT) |
675 (div[2] << CPM_CPCCR_PDIV_BIT) |
676 (div[3] << CPM_CPCCR_MDIV_BIT) |
677 (div[4] << CPM_CPCCR_LDIV_BIT);
678
679 //nf = pllin * 2 / CFG_EXTAL;
680 nf = pllin * 2 / 375299969;
681 plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */
682 (0 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */
683 (0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */
684 (0xa << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */
685 CPM_CPPCR_PLLEN; /* enable PLL */
686
687 /* init PLL */
688 *pll_cfcr = cfcr;
689 *pll_plcr1 = plcr1;
690}
691
692static inline void sdram_convert(unsigned int pllin, unsigned int *sdram_freq)
693{
694 register unsigned int ns, tmp;
695
696 ns = 1000000000 / pllin;
697 tmp = 15625 / ns;
698
699 /* Set refresh registers */
700 tmp = tmp / 64 + 1;
701
702 if(tmp > 0xff)
703 tmp = 0xff;
704
705 *sdram_freq = tmp;
706}
707
708static inline void set_cpu_freq(unsigned int pllin, unsigned int div)
709{
710 unsigned int sdram_freq;
711 unsigned int pll_cfcr, pll_plcr1;
712 int div_preq[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
713
714 if(pllin < 25000000 || pllin > 420000000)
715 panicf("PLL should be >25000000 and <420000000 !");
716
717 unsigned long t = read_c0_status();
718 write_c0_status(t & ~1);
719
720 pll_convert(pllin, &pll_cfcr, &pll_plcr1);
721
722 sdram_convert(pllin / div_preq[div], &sdram_freq);
723
724 REG_CPM_CPCCR &= ~CPM_CPCCR_CE;
725
726 REG_CPM_CPCCR = pll_cfcr;
727 REG_CPM_CPPCR = pll_plcr1;
728
729 REG_EMC_RTCOR = sdram_freq;
730 REG_EMC_RTCNT = sdram_freq;
731
732 REG_CPM_CPCCR |= CPM_CPCCR_CE;
733
734 detect_clock();
735
736 write_c0_status(t);
737}
738
739static void OF_init_clocks(void)
740{
741 unsigned int prog_entry = ((unsigned int)OF_init_clocks >> 5) << 5;
742 unsigned int i, prog_size = 1024;
743
744 for(i = prog_entry; i < prog_entry + prog_size; i += 32)
745 __asm__ __volatile__("cache 0x1c, 0x00(%0) \n"
746 :
747 : "r" (i)
748 );
749
750 /* disable PLL clock */
751 REG_CPM_CPPCR &= ~CPM_CPPCR_PLLEN;
752 REG_CPM_CPCCR |= CPM_CPCCR_CE;
753
754 unsigned long old_clocks = REG_CPM_CLKGR;
755 /*
756 REG_CPM_CLKGR = ~( CPM_CLKGR_UART0 | CPM_CLKGR_TCU |
757 CPM_CLKGR_RTC | CPM_CLKGR_SADC |
758 CPM_CLKGR_LCD );
759 */
760
761 unsigned long old_scr = REG_CPM_SCR;
762 REG_CPM_SCR &= ~CPM_SCR_OSC_ENABLE; /* O1SE: 12M oscillator is disabled in Sleep mode */
763
764 REG_EMC_DMCR |= (EMC_DMCR_RMODE | EMC_DMCR_RFSH); /* self refresh + refresh is performed */
765 REG_EMC_DMCR = (REG_EMC_DMCR & ~EMC_DMCR_RMODE) | 1; /* -> RMODE = auto refresh
766 -> CAS mode = 2 cycles */
767 __asm__ __volatile__("wait \n");
768
769 REG_CPM_CLKGR = old_clocks;
770 REG_CPM_SCR = old_scr;
771
772 for(i=0; i<90; i++);
773
774 set_cpu_freq(336000000, 1);
775
776 for(i=0; i<60; i++);
777}
778
779static void my_init_clocks(void)
780{
781 unsigned long t = read_c0_status();
782 write_c0_status(t & ~1);
783
784 unsigned int prog_entry = ((unsigned int)my_init_clocks / 32 - 1) * 32;
785 unsigned int i, prog_size = 1024;
786
787 for(i = prog_entry; i < prog_entry + prog_size; i += 32)
788 __asm__ __volatile__("cache 0x1c, 0x00(%0) \n"
789 :
790 : "r" (i)
791 );
792
793 unsigned int sdram_freq, plcr1, cfcr;
794
795 sdram_convert(336000000/3, &sdram_freq);
796
797 cfcr = CPM_CPCCR_CLKOEN |
798 (6 << CPM_CPCCR_UDIV_BIT) |
799 CPM_CPCCR_UCS |
800 CPM_CPCCR_PCS |
801 (0 << CPM_CPCCR_CDIV_BIT) |
802 (2 << CPM_CPCCR_HDIV_BIT) |
803 (2 << CPM_CPCCR_PDIV_BIT) |
804 (2 << CPM_CPCCR_MDIV_BIT) |
805 (2 << CPM_CPCCR_LDIV_BIT);
806
807 plcr1 = (54 << CPM_CPPCR_PLLM_BIT) | /* FD */
808 (0 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */
809 (0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */
810 (0x20 << CPM_CPPCR_PLLST_BIT)| /* PLL stable time */
811 CPM_CPPCR_PLLEN; /* enable PLL */
812
813 REG_CPM_CPCCR &= ~CPM_CPCCR_CE;
814
815 REG_CPM_CPCCR = cfcr;
816 REG_CPM_CPPCR = plcr1;
817
818 REG_EMC_RTCOR = sdram_freq;
819 REG_EMC_RTCNT = sdram_freq;
820
821 REG_CPM_CPCCR |= CPM_CPCCR_CE;
822
823 REG_CPM_LPCDR = (REG_CPM_LPCDR & ~CPM_LPCDR_PIXDIV_MASK) | (11 << CPM_LPCDR_PIXDIV_BIT);
824
825 write_c0_status(t);
826}
827
666extern int main(void); 828extern int main(void);
667extern void except_common_entry(void); 829extern void except_common_entry(void);
668 830
@@ -696,6 +858,15 @@ void system_main(void)
696 858
697 /* Disable unneeded clocks, clocks are enabled when needed */ 859 /* Disable unneeded clocks, clocks are enabled when needed */
698 __cpm_stop_all(); 860 __cpm_stop_all();
861 __cpm_suspend_usbhost();
862
863#if 0
864 my_init_clocks();
865 /*__cpm_stop_udc();
866 REG_CPM_CPCCR |= CPM_CPCCR_UCS;
867 REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_UDIV_MASK) | (3 << CPM_CPCCR_UDIV_BIT);
868 __cpm_start_udc();*/
869#endif
699 870
700 /* Enable interrupts at core level */ 871 /* Enable interrupts at core level */
701 sti(); 872 sti();