diff options
Diffstat (limited to 'firmware/target/mips/ingenic_jz47xx/system-jz4740.c')
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/system-jz4740.c | 171 |
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 | ||
666 | static 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 | |||
692 | static 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 | |||
708 | static 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 | |||
739 | static 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 | |||
779 | static 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 | |||
666 | extern int main(void); | 828 | extern int main(void); |
667 | extern void except_common_entry(void); | 829 | extern 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(); |