# HG changeset patch # User Paul Boddie # Date 1499724210 -7200 # Node ID 217a6336c5088ef5184b3359343dc413d30abe75 # Parent 6cf4059ed4474774695f4f9475e09c58b15c6a8d Introduced a separate clock and power management module, simplifying the LCD initialisation code, also simplifying the frequency calculations in the stage1 payload. diff -r 6cf4059ed447 -r 217a6336c508 include/jz4730.h --- a/include/jz4730.h Sun Jul 09 19:04:49 2017 +0200 +++ b/include/jz4730.h Tue Jul 11 00:03:30 2017 +0200 @@ -33,6 +33,10 @@ #define CONFIG_SYS_EXTAL 3686400 /* EXTAL freq: 3.7 MHz */ #define CONFIG_SYS_HZ (CONFIG_SYS_CPU_SPEED / (3*256)) /* incrementer freq */ +#define JZ_EXTAL CONFIG_SYS_EXTAL +#define JZ_EXTAL2 32768 /* RTC clock */ + +/* Register Definitions */ #define HARB_BASE 0xB3000000 #define EMC_BASE 0xB3010000 #define DMAC_BASE 0xB3020000 @@ -2198,41 +2202,8 @@ /************************************************************************* * CPM *************************************************************************/ -#define CPM_CFCR (CPM_BASE+0x00) -#define CPM_PLCR1 (CPM_BASE+0x10) -#define CPM_OCR (CPM_BASE+0x1c) -#define CPM_CFCR2 (CPM_BASE+0x60) -#define CPM_LPCR (CPM_BASE+0x04) -#define CPM_RSTR (CPM_BASE+0x08) -#define CPM_MSCR (CPM_BASE+0x20) -#define CPM_SCR (CPM_BASE+0x24) -#define CPM_WRER (CPM_BASE+0x28) -#define CPM_WFER (CPM_BASE+0x2c) -#define CPM_WER (CPM_BASE+0x30) -#define CPM_WSR (CPM_BASE+0x34) -#define CPM_GSR0 (CPM_BASE+0x38) -#define CPM_GSR1 (CPM_BASE+0x3c) -#define CPM_GSR2 (CPM_BASE+0x40) -#define CPM_SPR (CPM_BASE+0x44) -#define CPM_GSR3 (CPM_BASE+0x48) - -#define REG_CPM_CFCR REG32(CPM_CFCR) -#define REG_CPM_PLCR1 REG32(CPM_PLCR1) -#define REG_CPM_OCR REG32(CPM_OCR) -#define REG_CPM_CFCR2 REG32(CPM_CFCR2) -#define REG_CPM_LPCR REG32(CPM_LPCR) -#define REG_CPM_RSTR REG32(CPM_RSTR) -#define REG_CPM_MSCR REG32(CPM_MSCR) -#define REG_CPM_SCR REG32(CPM_SCR) -#define REG_CPM_WRER REG32(CPM_WRER) -#define REG_CPM_WFER REG32(CPM_WFER) -#define REG_CPM_WER REG32(CPM_WER) -#define REG_CPM_WSR REG32(CPM_WSR) -#define REG_CPM_GSR0 REG32(CPM_GSR0) -#define REG_CPM_GSR1 REG32(CPM_GSR1) -#define REG_CPM_GSR2 REG32(CPM_GSR2) -#define REG_CPM_SPR REG32(CPM_SPR) -#define REG_CPM_GSR3 REG32(CPM_GSR3) + +/* Register definitions with absolute positioning have been removed. */ #define CPM_CFCR_SSI (1 << 31) #define CPM_CFCR_LCD (1 << 30) @@ -4477,204 +4448,8 @@ /*************************************************************************** * CPM ***************************************************************************/ -#define __cpm_plcr1_fd() \ - ((REG_CPM_PLCR1 & CPM_PLCR1_PLL1FD_MASK) >> CPM_PLCR1_PLL1FD_BIT) -#define __cpm_plcr1_rd() \ - ((REG_CPM_PLCR1 & CPM_PLCR1_PLL1RD_MASK) >> CPM_PLCR1_PLL1RD_BIT) -#define __cpm_plcr1_od() \ - ((REG_CPM_PLCR1 & CPM_PLCR1_PLL1OD_MASK) >> CPM_PLCR1_PLL1OD_BIT) -#define __cpm_cfcr_mfr() \ - ((REG_CPM_CFCR & CPM_CFCR_MFR_MASK) >> CPM_CFCR_MFR_BIT) -#define __cpm_cfcr_pfr() \ - ((REG_CPM_CFCR & CPM_CFCR_PFR_MASK) >> CPM_CFCR_PFR_BIT) -#define __cpm_cfcr_sfr() \ - ((REG_CPM_CFCR & CPM_CFCR_SFR_MASK) >> CPM_CFCR_SFR_BIT) -#define __cpm_cfcr_ifr() \ - ((REG_CPM_CFCR & CPM_CFCR_IFR_MASK) >> CPM_CFCR_IFR_BIT) - -static __inline__ unsigned int __cpm_divisor_encode(unsigned int n) -{ - unsigned int encode[10] = {1,2,3,4,6,8,12,16,24,32}; - int i; - for (i=0;i<10;i++) - if (n < encode[i]) - break; - return i; -} - -#define __cpm_set_mclk_div(n) \ -do { \ - REG_CPM_CFCR = (REG_CPM_CFCR & ~CPM_CFCR_MFR_MASK) | \ - ((n) << (CPM_CFCR_MFR_BIT)); \ -} while (0) - -#define __cpm_set_pclk_div(n) \ -do { \ - REG_CPM_CFCR = (REG_CPM_CFCR & ~CPM_CFCR_PFR_MASK) | \ - ((n) << (CPM_CFCR_PFR_BIT)); \ -} while (0) - -#define __cpm_set_sclk_div(n) \ -do { \ - REG_CPM_CFCR = (REG_CPM_CFCR & ~CPM_CFCR_SFR_MASK) | \ - ((n) << (CPM_CFCR_SFR_BIT)); \ -} while (0) - -#define __cpm_set_iclk_div(n) \ -do { \ - REG_CPM_CFCR = (REG_CPM_CFCR & ~CPM_CFCR_IFR_MASK) | \ - ((n) << (CPM_CFCR_IFR_BIT)); \ -} while (0) - -#define __cpm_set_lcdclk_div(n) \ -do { \ - REG_CPM_CFCR = (REG_CPM_CFCR & ~CPM_CFCR_LFR_MASK) | \ - ((n) << (CPM_CFCR_LFR_BIT)); \ -} while (0) - -#define __cpm_enable_cko1() (REG_CPM_CFCR |= CPM_CFCR_CKOEN1) -#define __cpm_enable_cko2() (REG_CPM_CFCR |= CPM_CFCR_CKOEN2) -#define __cpm_disable_cko1() (REG_CPM_CFCR &= ~CPM_CFCR_CKOEN1) -#define __cpm_disable_cko2() (REG_CPM_CFCR &= ~CPM_CFCR_CKOEN2) - -#define __cpm_idle_mode() \ - (REG_CPM_LPCR = (REG_CPM_LPCR & ~CPM_LPCR_LPM_MASK) | \ - CPM_LPCR_LPM_IDLE) -#define __cpm_sleep_mode() \ - (REG_CPM_LPCR = (REG_CPM_LPCR & ~CPM_LPCR_LPM_MASK) | \ - CPM_LPCR_LPM_SLEEP) -#define __cpm_hibernate_mode() \ - (REG_CPM_LPCR = (REG_CPM_LPCR & ~CPM_LPCR_LPM_MASK) | \ - CPM_LPCR_LPM_HIBERNATE) - -#define __cpm_start_uart0() \ - (REG_CPM_MSCR &= ~(1 << CPM_MSCR_MSTP_UART0)) -#define __cpm_start_uart1() \ - (REG_CPM_MSCR &= ~(1 << CPM_MSCR_MSTP_UART1)) -#define __cpm_start_uart2() \ - (REG_CPM_MSCR &= ~(1 << CPM_MSCR_MSTP_UART2)) -#define __cpm_start_uart3() \ - (REG_CPM_MSCR &= ~(1 << CPM_MSCR_MSTP_UART3)) -#define __cpm_start_ost() \ - (REG_CPM_MSCR &= ~(1 << CPM_MSCR_MSTP_OST)) -#define __cpm_start_dmac() \ - (REG_CPM_MSCR &= ~(1 << CPM_MSCR_MSTP_DMAC)) -#define __cpm_start_uhc() \ - (REG_CPM_MSCR &= ~(1 << CPM_MSCR_MSTP_UHC)) -#define __cpm_start_lcd() \ - (REG_CPM_MSCR &= ~(1 << CPM_MSCR_MSTP_LCD)) -#define __cpm_start_i2c() \ - (REG_CPM_MSCR &= ~(1 << CPM_MSCR_MSTP_I2C)) -#define __cpm_start_aic_pclk() \ - (REG_CPM_MSCR &= ~(1 << CPM_MSCR_MSTP_AICPCLK)) -#define __cpm_start_aic_bitclk() \ - (REG_CPM_MSCR &= ~(1 << CPM_MSCR_MSTP_AICBCLK)) -#define __cpm_start_pwm0() \ - (REG_CPM_MSCR &= ~(1 << CPM_MSCR_MSTP_PWM0)) -#define __cpm_start_pwm1() \ - (REG_CPM_MSCR &= ~(1 << CPM_MSCR_MSTP_PWM1)) -#define __cpm_start_ssi() \ - (REG_CPM_MSCR &= ~(1 << CPM_MSCR_MSTP_SSI)) -#define __cpm_start_msc() \ - (REG_CPM_MSCR &= ~(1 << CPM_MSCR_MSTP_MSC)) -#define __cpm_start_scc() \ - (REG_CPM_MSCR &= ~(1 << CPM_MSCR_MSTP_SCC)) -#define __cpm_start_eth() \ - (REG_CPM_MSCR &= ~(1 << CPM_MSCR_MSTP_ETH)) -#define __cpm_start_kbc() \ - (REG_CPM_MSCR &= ~(1 << CPM_MSCR_MSTP_KBC)) -#define __cpm_start_cim() \ - (REG_CPM_MSCR &= ~(1 << CPM_MSCR_MSTP_CIM)) -#define __cpm_start_udc() \ - (REG_CPM_MSCR &= ~(1 << CPM_MSCR_MSTP_UDC)) -#define __cpm_start_uprt() \ - (REG_CPM_MSCR &= ~(1 << CPM_MSCR_MSTP_UPRT)) -#define __cpm_start_all() (REG_CPM_MSCR = 0) - -#define __cpm_stop_uart0() \ - (REG_CPM_MSCR |= (1 << CPM_MSCR_MSTP_UART0)) -#define __cpm_stop_uart1() \ - (REG_CPM_MSCR |= (1 << CPM_MSCR_MSTP_UART1)) -#define __cpm_stop_uart2() \ - (REG_CPM_MSCR |= (1 << CPM_MSCR_MSTP_UART2)) -#define __cpm_stop_uart3() \ - (REG_CPM_MSCR |= (1 << CPM_MSCR_MSTP_UART3)) -#define __cpm_stop_ost() \ - (REG_CPM_MSCR |= (1 << CPM_MSCR_MSTP_OST)) -#define __cpm_stop_dmac() \ - (REG_CPM_MSCR |= (1 << CPM_MSCR_MSTP_DMAC)) -#define __cpm_stop_uhc() \ - (REG_CPM_MSCR |= (1 << CPM_MSCR_MSTP_UHC)) -#define __cpm_stop_lcd() \ - (REG_CPM_MSCR |= (1 << CPM_MSCR_MSTP_LCD)) -#define __cpm_stop_i2c() \ - (REG_CPM_MSCR |= (1 << CPM_MSCR_MSTP_I2C)) -#define __cpm_stop_aic_pclk() \ - (REG_CPM_MSCR |= (1 << CPM_MSCR_MSTP_AICPCLK)) -#define __cpm_stop_aic_bitclk() \ - (REG_CPM_MSCR |= (1 << CPM_MSCR_MSTP_AICBCLK)) -#define __cpm_stop_pwm0() \ - (REG_CPM_MSCR |= (1 << CPM_MSCR_MSTP_PWM0)) -#define __cpm_stop_pwm1() \ - (REG_CPM_MSCR |= (1 << CPM_MSCR_MSTP_PWM1)) -#define __cpm_stop_ssi() \ - (REG_CPM_MSCR |= (1 << CPM_MSCR_MSTP_SSI)) -#define __cpm_stop_msc() \ - (REG_CPM_MSCR |= (1 << CPM_MSCR_MSTP_MSC)) -#define __cpm_stop_scc() \ - (REG_CPM_MSCR |= (1 << CPM_MSCR_MSTP_SCC)) -#define __cpm_stop_eth() \ - (REG_CPM_MSCR |= (1 << CPM_MSCR_MSTP_ETH)) -#define __cpm_stop_kbc() \ - (REG_CPM_MSCR |= (1 << CPM_MSCR_MSTP_KBC)) -#define __cpm_stop_cim() \ - (REG_CPM_MSCR |= (1 << CPM_MSCR_MSTP_CIM)) -#define __cpm_stop_udc() \ - (REG_CPM_MSCR |= (1 << CPM_MSCR_MSTP_UDC)) -#define __cpm_stop_uprt() \ - (REG_CPM_MSCR |= (1 << CPM_MSCR_MSTP_UPRT)) -#define __cpm_stop_all() (REG_CPM_MSCR = 0xffffffff) - -#define __cpm_set_pin(n) \ -do { \ - unsigned int p, o; \ - p = (n) / 32; \ - o = (n) % 32; \ - if (p == 0) \ - REG_CPM_GSR0 |= (1 << o); \ - else if (p == 1) \ - REG_CPM_GSR1 |= (1 << o); \ - else if (p == 2) \ - REG_CPM_GSR2 |= (1 << o); \ - else if (p == 3) \ - REG_CPM_GSR3 |= (1 << o); \ -} while (0) - -#define __cpm_clear_pin(n) \ -do { \ - unsigned int p, o; \ - p = (n) / 32; \ - o = (n) % 32; \ - if (p == 0) \ - REG_CPM_GSR0 &= ~(1 << o); \ - else if (p == 1) \ - REG_CPM_GSR1 &= ~(1 << o); \ - else if (p == 2) \ - REG_CPM_GSR2 &= ~(1 << o); \ - else if (p == 3) \ - REG_CPM_GSR3 &= ~(1 << o); \ -} while (0) - - -#define __cpm_select_msc_clk(type) \ -do { \ - if (type == 0) \ - REG_CPM_CFCR &= ~CPM_CFCR_MSC; \ - else \ - REG_CPM_CFCR |= CPM_CFCR_MSC; \ - REG_CPM_CFCR |= CPM_CFCR_UPE; \ -} while(0) - + +/* Register operations using absolute positioning have been removed. */ /*************************************************************************** * SSI @@ -4837,101 +4612,6 @@ #define __wdt_start() ( REG_WDT_WTCSR |= WDT_WTCSR_START ) #define __wdt_stop() ( REG_WDT_WTCSR &= ~WDT_WTCSR_START ) - -/*************************************************************************** - ***************************************************************************/ - -/* - * CPU clocks - */ -#define JZ_EXTAL CONFIG_SYS_EXTAL -#define JZ_EXTAL2 32768 /* RTC clock */ - -static __inline__ unsigned int __cpm_get_pllout(void) -{ - unsigned int nf, nr, no, pllout; - unsigned long plcr = REG_CPM_PLCR1; - unsigned long od[4] = {1, 2, 2, 4}; - if (plcr & CPM_PLCR1_PLL1EN) { - nf = (plcr & CPM_PLCR1_PLL1FD_MASK) >> CPM_PLCR1_PLL1FD_BIT; - nr = (plcr & CPM_PLCR1_PLL1RD_MASK) >> CPM_PLCR1_PLL1RD_BIT; - no = od[((plcr & CPM_PLCR1_PLL1OD_MASK) >> CPM_PLCR1_PLL1OD_BIT)]; - pllout = (JZ_EXTAL) / ((nr+2) * no) * (nf+2); - } else - pllout = JZ_EXTAL; - return pllout; -} - -static __inline__ unsigned int __cpm_get_iclk(void) -{ - unsigned int iclk; - int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; - unsigned long cfcr = REG_CPM_CFCR; - unsigned long plcr = REG_CPM_PLCR1; - if (plcr & CPM_PLCR1_PLL1EN) - iclk = __cpm_get_pllout() / - div[(cfcr & CPM_CFCR_IFR_MASK) >> CPM_CFCR_IFR_BIT]; - else - iclk = JZ_EXTAL; - return iclk; -} - -static __inline__ unsigned int __cpm_get_sclk(void) -{ - unsigned int sclk; - int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; - unsigned long cfcr = REG_CPM_CFCR; - unsigned long plcr = REG_CPM_PLCR1; - if (plcr & CPM_PLCR1_PLL1EN) - sclk = __cpm_get_pllout() / - div[(cfcr & CPM_CFCR_SFR_MASK) >> CPM_CFCR_SFR_BIT]; - else - sclk = JZ_EXTAL; - return sclk; -} - -static __inline__ unsigned int __cpm_get_mclk(void) -{ - unsigned int mclk; - int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; - unsigned long cfcr = REG_CPM_CFCR; - unsigned long plcr = REG_CPM_PLCR1; - if (plcr & CPM_PLCR1_PLL1EN) - mclk = __cpm_get_pllout() / - div[(cfcr & CPM_CFCR_MFR_MASK) >> CPM_CFCR_MFR_BIT]; - else - mclk = JZ_EXTAL; - return mclk; -} - -static __inline__ unsigned int __cpm_get_pclk(void) -{ - unsigned int devclk; - int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; - unsigned long cfcr = REG_CPM_CFCR; - unsigned long plcr = REG_CPM_PLCR1; - if (plcr & CPM_PLCR1_PLL1EN) - devclk = __cpm_get_pllout() / - div[(cfcr & CPM_CFCR_PFR_MASK) >> CPM_CFCR_PFR_BIT]; - else - devclk = JZ_EXTAL; - return devclk; -} - -static __inline__ unsigned int __cpm_get_devclk(void) -{ - unsigned int devclk; - int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; - unsigned long cfcr = REG_CPM_CFCR; - unsigned long plcr = REG_CPM_PLCR1; - if (plcr & CPM_PLCR1_PLL1EN) - devclk = __cpm_get_pllout() / - div[(cfcr & CPM_CFCR_PFR_MASK) >> CPM_CFCR_PFR_BIT]; - else - devclk = JZ_EXTAL; - return devclk; -} - #endif /* !__ASSEMBLY__ */ #endif /* __JZ4730_H__ */ diff -r 6cf4059ed447 -r 217a6336c508 include/jz4730_compat.h --- a/include/jz4730_compat.h Sun Jul 09 19:04:49 2017 +0200 +++ b/include/jz4730_compat.h Tue Jul 11 00:03:30 2017 +0200 @@ -1,7 +1,7 @@ /* * Compatibility definitions for using jz4740 code with the jz4730. * - * Copyright (C) 2015 Paul Boddie + * Copyright (C) 2015, 2017 Paul Boddie * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,9 +20,6 @@ #ifndef __JZ4730_COMPAT_H__ #define __JZ4730_COMPAT_H__ -#define REG_CPM_CPCCR REG_CPM_CFCR -#define REG_CPM_CPPCR REG_CPM_PLCR1 - #define CPM_CPCCR_CE CPM_CFCR_UPE #define CPM_CPCCR_CDIV_BIT CPM_CFCR_IFR_BIT #define CPM_CPCCR_HDIV_BIT CPM_CFCR_SFR_BIT @@ -30,12 +27,16 @@ #define CPM_CPCCR_MDIV_BIT CPM_CFCR_LFR_BIT #define CPM_CPCCR_LDIV_BIT CPM_CFCR_MFR_BIT +#define CPM_CPCCR_LDIV_MASK CPM_CFCR_LFR_MASK + #define CPM_CPPCR_PLLM_BIT CPM_PLCR1_PLL1FD_BIT #define CPM_CPPCR_PLLN_BIT CPM_PLCR1_PLL1RD_BIT #define CPM_CPPCR_PLLOD_BIT CPM_PLCR1_PLL1OD_BIT #define CPM_CPPCR_PLLST_BIT CPM_PLCR1_PLL1ST_BIT #define CPM_CPPCR_PLLEN CPM_PLCR1_PLL1EN -#define __cpm_set_ldiv __cpm_set_lcdclk_div +#define CPM_CPPCR_PLLM_MASK CPM_PLCR1_PLL1FD_MASK +#define CPM_CPPCR_PLLN_MASK CPM_PLCR1_PLL1RD_MASK +#define CPM_CPPCR_PLLOD_MASK CPM_PLCR1_PLL1OD_MASK #endif /* __JZ4730_COMPAT_H__ */ diff -r 6cf4059ed447 -r 217a6336c508 include/jz4740.h --- a/include/jz4740.h Sun Jul 09 19:04:49 2017 +0200 +++ b/include/jz4740.h Tue Jul 11 00:03:30 2017 +0200 @@ -4,7 +4,7 @@ * Copyright (C) 2006 - 2007 Ingenic Semiconductor Inc. * Copyright (C) 2009 Qi Hardware Inc. * Author: Xiangfu Liu - * Copyright (C) 2015 Paul Boddie + * Copyright (C) 2015, 2017 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -32,6 +32,9 @@ #define CONFIG_SYS_EXTAL 12000000 /* EXTAL freq: 12 MHz */ #define CONFIG_SYS_HZ (CONFIG_SYS_EXTAL / 256) /* incrementer freq */ +#define JZ_EXTAL CONFIG_SYS_EXTAL +#define JZ_EXTAL2 32768 /* RTC clock */ + /* Boot ROM Specification */ /* NOR Boot config */ #define JZ4740_NORBOOT_8BIT 0x00000000 /* 8-bit data bus flash */ @@ -180,47 +183,6 @@ /* Register definitions with absolute positioning have been removed. */ -#define CPM_CPCCR (CPM_BASE+0x00) -#define CPM_CPPCR (CPM_BASE+0x10) -#define CPM_I2SCDR (CPM_BASE+0x60) -#define CPM_LPCDR (CPM_BASE+0x64) -#define CPM_MSCCDR (CPM_BASE+0x68) -#define CPM_UHCCDR (CPM_BASE+0x6C) - -#define CPM_LCR (CPM_BASE+0x04) -#define CPM_CLKGR (CPM_BASE+0x20) -#define CPM_SCR (CPM_BASE+0x24) - -#define CPM_HCR (CPM_BASE+0x30) -#define CPM_HWFCR (CPM_BASE+0x34) -#define CPM_HRCR (CPM_BASE+0x38) -#define CPM_HWCR (CPM_BASE+0x3c) -#define CPM_HWSR (CPM_BASE+0x40) -#define CPM_HSPR (CPM_BASE+0x44) - -#define CPM_RSR (CPM_BASE+0x08) - - -#define REG_CPM_CPCCR REG32(CPM_CPCCR) -#define REG_CPM_CPPCR REG32(CPM_CPPCR) -#define REG_CPM_I2SCDR REG32(CPM_I2SCDR) -#define REG_CPM_LPCDR REG32(CPM_LPCDR) -#define REG_CPM_MSCCDR REG32(CPM_MSCCDR) -#define REG_CPM_UHCCDR REG32(CPM_UHCCDR) - -#define REG_CPM_LCR REG32(CPM_LCR) -#define REG_CPM_CLKGR REG32(CPM_CLKGR) -#define REG_CPM_SCR REG32(CPM_SCR) -#define REG_CPM_HCR REG32(CPM_HCR) -#define REG_CPM_HWFCR REG32(CPM_HWFCR) -#define REG_CPM_HRCR REG32(CPM_HRCR) -#define REG_CPM_HWCR REG32(CPM_HWCR) -#define REG_CPM_HWSR REG32(CPM_HWSR) -#define REG_CPM_HSPR REG32(CPM_HSPR) - -#define REG_CPM_RSR REG32(CPM_RSR) - - /* Clock Control Register */ #define CPM_CPCCR_I2CS (1 << 31) #define CPM_CPCCR_CLKOEN (1 << 30) @@ -246,7 +208,7 @@ /* LCD Pixel Clock Divider Register */ #define CPM_LPCDR_PIXDIV_BIT 0 -#define CPM_LPCDR_PIXDIV_MASK (0x1ff << CPM_LPCDR_PIXDIV_BIT) +#define CPM_LPCDR_PIXDIV_MASK (0x7ff << CPM_LPCDR_PIXDIV_BIT) /* MSC Clock Divider Register */ #define CPM_MSCCDR_MSCDIV_BIT 0 @@ -3054,248 +3016,8 @@ /*************************************************************************** * CPM ***************************************************************************/ -#define __cpm_get_pllm() \ - ((REG_CPM_CPPCR & CPM_CPPCR_PLLM_MASK) >> CPM_CPPCR_PLLM_BIT) -#define __cpm_get_plln() \ - ((REG_CPM_CPPCR & CPM_CPPCR_PLLN_MASK) >> CPM_CPPCR_PLLN_BIT) -#define __cpm_get_pllod() \ - ((REG_CPM_CPPCR & CPM_CPPCR_PLLOD_MASK) >> CPM_CPPCR_PLLOD_BIT) - -#define __cpm_get_cdiv() \ - ((REG_CPM_CPCCR & CPM_CPCCR_CDIV_MASK) >> CPM_CPCCR_CDIV_BIT) -#define __cpm_get_hdiv() \ - ((REG_CPM_CPCCR & CPM_CPCCR_HDIV_MASK) >> CPM_CPCCR_HDIV_BIT) -#define __cpm_get_pdiv() \ - ((REG_CPM_CPCCR & CPM_CPCCR_PDIV_MASK) >> CPM_CPCCR_PDIV_BIT) -#define __cpm_get_mdiv() \ - ((REG_CPM_CPCCR & CPM_CPCCR_MDIV_MASK) >> CPM_CPCCR_MDIV_BIT) -#define __cpm_get_ldiv() \ - ((REG_CPM_CPCCR & CPM_CPCCR_LDIV_MASK) >> CPM_CPCCR_LDIV_BIT) -#define __cpm_get_udiv() \ - ((REG_CPM_CPCCR & CPM_CPCCR_UDIV_MASK) >> CPM_CPCCR_UDIV_BIT) -#define __cpm_get_i2sdiv() \ - ((REG_CPM_I2SCDR & CPM_I2SCDR_I2SDIV_MASK) >> CPM_I2SCDR_I2SDIV_BIT) -#define __cpm_get_pixdiv() \ - ((REG_CPM_LPCDR & CPM_LPCDR_PIXDIV_MASK) >> CPM_LPCDR_PIXDIV_BIT) -#define __cpm_get_mscdiv() \ - ((REG_CPM_MSCCDR & CPM_MSCCDR_MSCDIV_MASK) >> CPM_MSCCDR_MSCDIV_BIT) - -#define __cpm_set_cdiv(v) \ - (REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_CDIV_MASK) | ((v) << (CPM_CPCCR_CDIV_BIT))) -#define __cpm_set_hdiv(v) \ - (REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_HDIV_MASK) | ((v) << (CPM_CPCCR_HDIV_BIT))) -#define __cpm_set_pdiv(v) \ - (REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_PDIV_MASK) | ((v) << (CPM_CPCCR_PDIV_BIT))) -#define __cpm_set_mdiv(v) \ - (REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_MDIV_MASK) | ((v) << (CPM_CPCCR_MDIV_BIT))) -#define __cpm_set_ldiv(v) \ - (REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_LDIV_MASK) | ((v) << (CPM_CPCCR_LDIV_BIT))) -#define __cpm_set_udiv(v) \ - (REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_UDIV_MASK) | ((v) << (CPM_CPCCR_UDIV_BIT))) -#define __cpm_set_i2sdiv(v) \ - (REG_CPM_I2SCDR = (REG_CPM_I2SCDR & ~CPM_I2SCDR_I2SDIV_MASK) | ((v) << (CPM_I2SCDR_I2SDIV_BIT))) -#define __cpm_set_pixdiv(v) \ - (REG_CPM_LPCDR = (REG_CPM_LPCDR & ~CPM_LPCDR_PIXDIV_MASK) | ((v) << (CPM_LPCDR_PIXDIV_BIT))) -#define __cpm_set_mscdiv(v) \ - (REG_CPM_MSCCDR = (REG_CPM_MSCCDR & ~CPM_MSCCDR_MSCDIV_MASK) | ((v) << (CPM_MSCCDR_MSCDIV_BIT))) - -#define __cpm_select_i2sclk_exclk() (REG_CPM_CPCCR &= ~CPM_CPCCR_I2CS) -#define __cpm_select_i2sclk_pll() (REG_CPM_CPCCR |= CPM_CPCCR_I2CS) -#define __cpm_enable_cko() (REG_CPM_CPCCR |= CPM_CPCCR_CLKOEN) -#define __cpm_select_usbclk_exclk() (REG_CPM_CPCCR &= ~CPM_CPCCR_UCS) -#define __cpm_select_usbclk_pll() (REG_CPM_CPCCR |= CPM_CPCCR_UCS) -#define __cpm_enable_pll_change() (REG_CPM_CPCCR |= CPM_CPCCR_CE) -#define __cpm_pllout_direct() (REG_CPM_CPCCR |= CPM_CPCCR_PCS) -#define __cpm_pllout_div2() (REG_CPM_CPCCR &= ~CPM_CPCCR_PCS) - -#define __cpm_pll_is_on() (REG_CPM_CPPCR & CPM_CPPCR_PLLS) -#define __cpm_pll_bypass() (REG_CPM_CPPCR |= CPM_CPPCR_PLLBP) -#define __cpm_pll_enable() (REG_CPM_CPPCR |= CPM_CPPCR_PLLEN) - -#define __cpm_get_cclk_doze_duty() \ - ((REG_CPM_LCR & CPM_LCR_DOZE_DUTY_MASK) >> CPM_LCR_DOZE_DUTY_BIT) -#define __cpm_set_cclk_doze_duty(v) \ - (REG_CPM_LCR = (REG_CPM_LCR & ~CPM_LCR_DOZE_DUTY_MASK) | ((v) << (CPM_LCR_DOZE_DUTY_BIT))) - -#define __cpm_doze_mode() (REG_CPM_LCR |= CPM_LCR_DOZE_ON) -#define __cpm_idle_mode() \ - (REG_CPM_LCR = (REG_CPM_LCR & ~CPM_LCR_LPM_MASK) | CPM_LCR_LPM_IDLE) -#define __cpm_sleep_mode() \ - (REG_CPM_LCR = (REG_CPM_LCR & ~CPM_LCR_LPM_MASK) | CPM_LCR_LPM_SLEEP) - -#define __cpm_stop_all() (REG_CPM_CLKGR = 0x7fff) -#define __cpm_stop_uart1() (REG_CPM_CLKGR |= CPM_CLKGR_UART1) -#define __cpm_stop_uhc() (REG_CPM_CLKGR |= CPM_CLKGR_UHC) -#define __cpm_stop_ipu() (REG_CPM_CLKGR |= CPM_CLKGR_IPU) -#define __cpm_stop_dmac() (REG_CPM_CLKGR |= CPM_CLKGR_DMAC) -#define __cpm_stop_udc() (REG_CPM_CLKGR |= CPM_CLKGR_UDC) -#define __cpm_stop_lcd() (REG_CPM_CLKGR |= CPM_CLKGR_LCD) -#define __cpm_stop_cim() (REG_CPM_CLKGR |= CPM_CLKGR_CIM) -#define __cpm_stop_sadc() (REG_CPM_CLKGR |= CPM_CLKGR_SADC) -#define __cpm_stop_msc() (REG_CPM_CLKGR |= CPM_CLKGR_MSC) -#define __cpm_stop_aic1() (REG_CPM_CLKGR |= CPM_CLKGR_AIC1) -#define __cpm_stop_aic2() (REG_CPM_CLKGR |= CPM_CLKGR_AIC2) -#define __cpm_stop_ssi() (REG_CPM_CLKGR |= CPM_CLKGR_SSI) -#define __cpm_stop_i2c() (REG_CPM_CLKGR |= CPM_CLKGR_I2C) -#define __cpm_stop_rtc() (REG_CPM_CLKGR |= CPM_CLKGR_RTC) -#define __cpm_stop_tcu() (REG_CPM_CLKGR |= CPM_CLKGR_TCU) -#define __cpm_stop_uart0() (REG_CPM_CLKGR |= CPM_CLKGR_UART0) - -#define __cpm_start_all() (REG_CPM_CLKGR = 0x0) -#define __cpm_start_uart1() (REG_CPM_CLKGR &= ~CPM_CLKGR_UART1) -#define __cpm_start_uhc() (REG_CPM_CLKGR &= ~CPM_CLKGR_UHC) -#define __cpm_start_ipu() (REG_CPM_CLKGR &= ~CPM_CLKGR_IPU) -#define __cpm_start_dmac() (REG_CPM_CLKGR &= ~CPM_CLKGR_DMAC) -#define __cpm_start_udc() (REG_CPM_CLKGR &= ~CPM_CLKGR_UDC) -#define __cpm_start_lcd() (REG_CPM_CLKGR &= ~CPM_CLKGR_LCD) -#define __cpm_start_cim() (REG_CPM_CLKGR &= ~CPM_CLKGR_CIM) -#define __cpm_start_sadc() (REG_CPM_CLKGR &= ~CPM_CLKGR_SADC) -#define __cpm_start_msc() (REG_CPM_CLKGR &= ~CPM_CLKGR_MSC) -#define __cpm_start_aic1() (REG_CPM_CLKGR &= ~CPM_CLKGR_AIC1) -#define __cpm_start_aic2() (REG_CPM_CLKGR &= ~CPM_CLKGR_AIC2) -#define __cpm_start_ssi() (REG_CPM_CLKGR &= ~CPM_CLKGR_SSI) -#define __cpm_start_i2c() (REG_CPM_CLKGR &= ~CPM_CLKGR_I2C) -#define __cpm_start_rtc() (REG_CPM_CLKGR &= ~CPM_CLKGR_RTC) -#define __cpm_start_tcu() (REG_CPM_CLKGR &= ~CPM_CLKGR_TCU) -#define __cpm_start_uart0() (REG_CPM_CLKGR &= ~CPM_CLKGR_UART0) - -#define __cpm_get_o1st() \ - ((REG_CPM_SCR & CPM_SCR_O1ST_MASK) >> CPM_SCR_O1ST_BIT) -#define __cpm_set_o1st(v) \ - (REG_CPM_SCR = (REG_CPM_SCR & ~CPM_SCR_O1ST_MASK) | ((v) << (CPM_SCR_O1ST_BIT))) -#define __cpm_suspend_udcphy() (REG_CPM_SCR &= ~CPM_SCR_UDCPHY_ENABLE) -#define __cpm_suspend_usbphy() (REG_CPM_SCR |= CPM_SCR_USBPHY_DISABLE) -#define __cpm_enable_osc_in_sleep() (REG_CPM_SCR |= CPM_SCR_OSC_ENABLE) - -#define JZ_EXTAL CONFIG_SYS_EXTAL -#define JZ_EXTAL2 32768 /* RTC clock */ - -/* PLL output frequency */ -static __inline__ unsigned int __cpm_get_pllout(void) -{ - unsigned long m, n, no, pllout; - unsigned long cppcr = REG_CPM_CPPCR; - unsigned long od[4] = {1, 2, 2, 4}; - if ((cppcr & CPM_CPPCR_PLLEN) && !(cppcr & CPM_CPPCR_PLLBP)) { - m = __cpm_get_pllm() + 2; - n = __cpm_get_plln() + 2; - no = od[__cpm_get_pllod()]; - pllout = ((JZ_EXTAL) / (n * no)) * m; - } else - pllout = JZ_EXTAL; - return pllout; -} - -/* PLL output frequency for MSC/I2S/LCD/USB */ -static __inline__ unsigned int __cpm_get_pllout2(void) -{ - if (REG_CPM_CPCCR & CPM_CPCCR_PCS) - return __cpm_get_pllout(); - else - return __cpm_get_pllout()/2; -} - -/* CPU core clock */ -static __inline__ unsigned int __cpm_get_cclk(void) -{ - int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; - - return __cpm_get_pllout() / div[__cpm_get_cdiv()]; -} - -/* AHB system bus clock */ -static __inline__ unsigned int __cpm_get_hclk(void) -{ - int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; - - return __cpm_get_pllout() / div[__cpm_get_hdiv()]; -} - -/* Memory bus clock */ -static __inline__ unsigned int __cpm_get_mclk(void) -{ - int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; - - return __cpm_get_pllout() / div[__cpm_get_mdiv()]; -} - -/* APB peripheral bus clock */ -static __inline__ unsigned int __cpm_get_pclk(void) -{ - int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; - - return __cpm_get_pllout() / div[__cpm_get_pdiv()]; -} - -/* LCDC module clock */ -static __inline__ unsigned int __cpm_get_lcdclk(void) -{ - return __cpm_get_pllout2() / (__cpm_get_ldiv() + 1); -} - -/* LCD pixel clock */ -static __inline__ unsigned int __cpm_get_pixclk(void) -{ - return __cpm_get_pllout2() / (__cpm_get_pixdiv() + 1); -} - -/* I2S clock */ -static __inline__ unsigned int __cpm_get_i2sclk(void) -{ - if (REG_CPM_CPCCR & CPM_CPCCR_I2CS) { - return __cpm_get_pllout2() / (__cpm_get_i2sdiv() + 1); - } - else { - return JZ_EXTAL; - } -} - -/* USB clock */ -static __inline__ unsigned int __cpm_get_usbclk(void) -{ - if (REG_CPM_CPCCR & CPM_CPCCR_UCS) { - return __cpm_get_pllout2() / (__cpm_get_udiv() + 1); - } - else { - return JZ_EXTAL; - } -} - -/* MSC clock */ -static __inline__ unsigned int __cpm_get_mscclk(void) -{ - return __cpm_get_pllout2() / (__cpm_get_mscdiv() + 1); -} - -/* EXTAL clock for UART,I2C,SSI,TCU,USB-PHY */ -static __inline__ unsigned int __cpm_get_extalclk(void) -{ - return JZ_EXTAL; -} - -/* RTC clock for CPM,INTC,RTC,TCU,WDT */ -static __inline__ unsigned int __cpm_get_rtcclk(void) -{ - return JZ_EXTAL2; -} - -/* - * Output 24MHz for SD and 16MHz for MMC. - */ -static inline void __cpm_select_msc_clk(int sd) -{ - unsigned int pllout2 = __cpm_get_pllout2(); - unsigned int div = 0; - - if (sd) { - div = pllout2 / 24000000; - } - else { - div = pllout2 / 16000000; - } - - REG_CPM_MSCCDR = div - 1; -} + +/* Register operations using absolute positioning have been removed. */ /* * TCU diff -r 6cf4059ed447 -r 217a6336c508 stage1/Makefile --- a/stage1/Makefile Sun Jul 09 19:04:49 2017 +0200 +++ b/stage1/Makefile Tue Jul 11 00:03:30 2017 +0200 @@ -1,6 +1,6 @@ # Makefile - Build the NanoNote payload # -# Copyright (C) 2015 Paul Boddie +# Copyright (C) 2015, 2017 Paul Boddie # Copyright (C) Xiangfu Liu # # This program is free software: you can redistribute it and/or modify @@ -41,8 +41,8 @@ # Ordering of objects is important and cannot be left to replacement rules. -SRC = head1.S stage1.c board.c -OBJ = head1.o stage1.o board.o +SRC = head1.S stage1.c board.c cpm.c +OBJ = head1.o stage1.o board.o cpm.o .PHONY: all clean distclean diff -r 6cf4059ed447 -r 217a6336c508 stage1/board.c --- a/stage1/board.c Sun Jul 09 19:04:49 2017 +0200 +++ b/stage1/board.c Tue Jul 11 00:03:30 2017 +0200 @@ -30,6 +30,7 @@ #include "memory.h" #include "sdram.h" +#include "cpm.h" #include "usb_boot_defines.h" /* These arguments are initialised by usbboot and are defined in... @@ -111,7 +112,7 @@ pllout2 = (cfcr & CPM_CPCCR_PCS) ? CONFIG_SYS_CPU_SPEED : (CONFIG_SYS_CPU_SPEED / 2); /* Divisor == UHCCDR + 1 */ - REG_CPM_UHCCDR = pllout2 / 48000000 - 1; + jz4740_cpm_ctrl_set((void *) CPM_BASE, CPM_UHCCDR, pllout2 / 48000000 - 1); #endif nf = CONFIG_SYS_CPU_SPEED * 2 / CONFIG_SYS_EXTAL; @@ -122,15 +123,14 @@ /* Update PLL and wait. */ - REG_CPM_CPCCR = cfcr; - REG_CPM_CPPCR = plcr1; - while (!__cpm_pll_is_on()); + jz4740_cpm_ctrl_set((void *) CPM_BASE, CPM_CPCCR, cfcr); + jz4740_cpm_ctrl_set((void *) CPM_BASE, CPM_CPPCR, plcr1); + while (!jz4740_cpm_have_pll((void *) CPM_BASE)); } void sdram_init() { register unsigned int dmcr0, dmcr, sdmode, tmp, cpu_clk, mem_clk, ns; - unsigned int pllout = __cpm_get_pllout(); unsigned int cas_latency_sdmr[2] = { EMC_SDMR_CAS_2, @@ -142,12 +142,8 @@ 2 << EMC_DMCR_TCL_BIT /* CAS latency is 3 */ }; - /* Divisors for CPCCR values. */ - - int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; - - cpu_clk = pllout / div[__cpm_get_cdiv()]; - mem_clk = pllout / div[__cpm_get_mdiv()]; + cpu_clk = jz4740_cpm_get_cpu_frequency((void *) CPM_BASE); + mem_clk = jz4740_cpm_get_memory_frequency((void *) CPM_BASE); REG_EMC_BCR = 0; /* Disable bus release */ REG_EMC_RTCSR = 0; /* Disable clock for counting */ diff -r 6cf4059ed447 -r 217a6336c508 stage1/board.h --- a/stage1/board.h Sun Jul 09 19:04:49 2017 +0200 +++ b/stage1/board.h Tue Jul 11 00:03:30 2017 +0200 @@ -8,4 +8,17 @@ void pll_init(); void sdram_init(); +/* Select the CPU definitions according to the configuration. */ + +#ifdef CONFIG_CPU_JZ4730 + +#include "jz4730.h" +#include "jz4730_compat.h" + +#else + +#include "jz4740.h" + +#endif + #endif /* __BOARD_H__ */ diff -r 6cf4059ed447 -r 217a6336c508 stage1/cpm.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stage1/cpm.c Tue Jul 11 00:03:30 2017 +0200 @@ -0,0 +1,1 @@ +../stage2/cpm.c \ No newline at end of file diff -r 6cf4059ed447 -r 217a6336c508 stage1/cpm.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stage1/cpm.h Tue Jul 11 00:03:30 2017 +0200 @@ -0,0 +1,1 @@ +../stage2/cpm.h \ No newline at end of file diff -r 6cf4059ed447 -r 217a6336c508 stage2/Makefile --- a/stage2/Makefile Sun Jul 09 19:04:49 2017 +0200 +++ b/stage2/Makefile Tue Jul 11 00:03:30 2017 +0200 @@ -1,6 +1,6 @@ # Makefile - Build the NanoNote payload # -# Copyright (C) 2015, 2016 Paul Boddie +# Copyright (C) 2015, 2016, 2017 Paul Boddie # Copyright (C) Xiangfu Liu # # This program is free software: you can redistribute it and/or modify @@ -60,7 +60,7 @@ # Configure generic objects. -CORE_SRC = stage2.c cpu.c lcd.c jzlcd.c board.c irq.c paging.c tasks.c task_gpio.c +CORE_SRC = stage2.c cpm.c cpu.c lcd.c jzlcd.c board.c irq.c paging.c tasks.c task_gpio.c CORE_OBJ = $(CORE_SRC:.c=.o) # Add tasks. diff -r 6cf4059ed447 -r 217a6336c508 stage2/board-minipc.c --- a/stage2/board-minipc.c Sun Jul 09 19:04:49 2017 +0200 +++ b/stage2/board-minipc.c Tue Jul 11 00:03:30 2017 +0200 @@ -59,11 +59,6 @@ } } -void cpm_init() -{ - __cpm_stop_all(); -} - void rtc_init() { /* NOTE: May only be accessible via I2C. */ @@ -85,7 +80,7 @@ __ost_set_count(TIMER_CHAN, TIMER_FDATA); __ost_enable_channel(TIMER_CHAN); - __cpm_start_ost(); + jz4740_cpm_start_clock((void *) CPM_BASE); lastdec = TIMER_FDATA; timestamp = 0; @@ -125,5 +120,5 @@ int is_started() { - return REG_CPM_MSCR != 0; + return jz4740_cpm_have_clock((void *) CPM_BASE); } diff -r 6cf4059ed447 -r 217a6336c508 stage2/board-nanonote.c --- a/stage2/board-nanonote.c Sun Jul 09 19:04:49 2017 +0200 +++ b/stage2/board-nanonote.c Tue Jul 11 00:03:30 2017 +0200 @@ -22,6 +22,7 @@ #include "board.h" #include "nanonote.h" +#include "cpm.h" /* Later initialisation functions. */ @@ -68,20 +69,6 @@ __gpio_as_pwm4(); } -void cpm_init() -{ - __cpm_stop_ipu(); - __cpm_stop_cim(); - __cpm_stop_i2c(); - __cpm_stop_ssi(); - __cpm_stop_uart1(); - __cpm_stop_sadc(); - __cpm_stop_uhc(); - __cpm_stop_udc(); - __cpm_stop_aic1(); -/* __cpm_stop_aic2();*/ -} - void rtc_init() { while ( !__rtc_write_ready()); @@ -120,7 +107,7 @@ __tcu_start_timer_clock(TIMER_CHAN); __tcu_start_counter(TIMER_CHAN); - __cpm_start_tcu(); + jz4740_cpm_start_clock((void *) CPM_BASE); lastdec = 0; timestamp = 0; @@ -158,5 +145,5 @@ int is_started() { - return REG_CPM_CLKGR != 0; + return jz4740_cpm_have_clock((void *) CPM_BASE); } diff -r 6cf4059ed447 -r 217a6336c508 stage2/cpm.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stage2/cpm.c Tue Jul 11 00:03:30 2017 +0200 @@ -0,0 +1,260 @@ +/* + * Clock and power management. + * + * Copyright (C) Xiangfu Liu + * Copyright (C) 2015, 2016, 2017 Paul Boddie + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "xburst_types.h" +#include "cpm.h" +#include "board.h" + +static uint32_t cpm_ctrl_get(void *cpm_base, uint32_t reg) +{ + return REG32(cpm_base + reg); +} + +static void cpm_ctrl_set(void *cpm_base, uint32_t reg, uint32_t value) +{ + REG32(cpm_base + reg) = value; +} + +static int pll_enabled(void *cpm_base) +{ + return cpm_ctrl_get(cpm_base, CPM_CPPCR) & CPM_CPPCR_PLLEN; +} + +static int pll_bypassed(void *cpm_base) +{ + return cpm_ctrl_get(cpm_base, CPM_CPPCR) & CPM_CPPCR_PLLBP; +} + +// Feedback (9-bit) divider. + +static uint16_t get_multiplier(void *cpm_base) +{ + return ((cpm_ctrl_get(cpm_base, CPM_CPPCR) & CPM_CPPCR_PLLM_MASK) >> CPM_CPPCR_PLLM_BIT) + 2; +} + +// Input (5-bit) divider. + +static uint8_t get_input_divider(void *cpm_base) +{ + return ((cpm_ctrl_get(cpm_base, CPM_CPPCR) & CPM_CPPCR_PLLN_MASK) >> CPM_CPPCR_PLLN_BIT) + 2; +} + +// Output divider. + +static uint8_t get_output_divider(void *cpm_base) +{ + uint8_t od[] = {1, 2, 2, 4}; + return od[(cpm_ctrl_get(cpm_base, CPM_CPPCR) & CPM_CPPCR_PLLOD_MASK) >> CPM_CPPCR_PLLOD_BIT]; +} + +// General clock divider. + +static uint8_t _get_divider(void *cpm_base, uint32_t reg, uint32_t mask, uint8_t shift) +{ + uint8_t cd[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; + uint8_t d = (cpm_ctrl_get(cpm_base, reg) & mask) >> shift; + return (d < 10) ? cd[d] : 1; +} + +// CPU clock divider. + +static uint8_t get_cpu_divider(void *cpm_base) +{ + return _get_divider(cpm_base, CPM_CPCCR, CPM_CPCCR_CDIV_MASK, CPM_CPCCR_CDIV_BIT); +} + +// Memory clock divider. + +static uint8_t get_memory_divider(void *cpm_base) +{ + return _get_divider(cpm_base, CPM_CPCCR, CPM_CPCCR_MDIV_MASK, CPM_CPCCR_MDIV_BIT); +} + +// Clock source divider for MSC, I2S, LCD and USB. + +static uint8_t get_source_divider(void *cpm_base) +{ +#ifdef CONFIG_CPU_JZ4730 + return 1; +#else + return cpm_ctrl_get(cpm_base, CPM_CPCCR) & CPM_CPCCR_PCS ? 1 : 2; +#endif +} + +// LCD device clock divider. + +static void set_lcd_device_divider(void *cpm_base, uint8_t division) +{ + if (division == 0) + division = 1; +#ifdef CONFIG_CPU_JZ4730 + else if (division > 16) + division = 16; +#else + else if (division > 32) + division = 32; +#endif + + cpm_ctrl_set(cpm_base, CPM_CPCCR, + (cpm_ctrl_get(cpm_base, CPM_CPCCR) & ~CPM_CPCCR_LDIV_MASK) | + ((division - 1) << CPM_CPCCR_LDIV_BIT)); +} + +// LCD pixel clock divider. + +static void set_lcd_pixel_divider(void *cpm_base, uint16_t division) +{ +#ifndef CONFIG_CPU_JZ4730 + if (division == 0) + division = 1; + else if (division > 2048) + division = 2048; + + cpm_ctrl_set(cpm_base, CPM_LPCDR, + (cpm_ctrl_get(cpm_base, CPM_LPCDR) & ~CPM_LPCDR_PIXDIV_MASK) | + (division - 1)); +#endif +} + +static uint32_t get_pll_frequency(void *cpm_base) +{ + // Test for PLL enable and not PLL bypass. + + if (pll_enabled(cpm_base) && !pll_bypassed(cpm_base)) + return (JZ_EXTAL * get_multiplier(cpm_base)) / + (get_input_divider(cpm_base) * get_output_divider(cpm_base)); + else + return JZ_EXTAL; +} + +// Clock frequency for MSC, I2S, LCD and USB. + +static uint32_t get_output_frequency(void *cpm_base) +{ + return get_pll_frequency(cpm_base) / get_source_divider(cpm_base); +} + + + +/* Public functions. */ + +// Clock frequency for the CPU. + +uint32_t jz4740_cpm_get_cpu_frequency(void *cpm_base) +{ + return get_pll_frequency(cpm_base) / get_cpu_divider(cpm_base); +} + +// Clock frequency for the memory. + +uint32_t jz4740_cpm_get_memory_frequency(void *cpm_base) +{ + return get_pll_frequency(cpm_base) / get_memory_divider(cpm_base); +} + +// Set the device and pixel frequencies, indicating the latter and +// providing the device:pixel frequency ratio. + +void jz4740_cpm_set_lcd_frequencies(void *cpm_base, uint32_t pclk, uint8_t ratio) +{ + uint32_t out = get_output_frequency(cpm_base), lcd = pclk * ratio; + + set_lcd_pixel_divider(cpm_base, out / pclk); + + // Limit the device frequency to 150MHz. + + if (lcd > 150000000) lcd = 150000000; + + set_lcd_device_divider(cpm_base, out / lcd); +} + +// Update the clock output frequency. + +void jz4740_cpm_update_output_frequency(void *cpm_base) +{ + cpm_ctrl_set(cpm_base, CPM_CPCCR, cpm_ctrl_get(cpm_base, CPM_CPCCR) | CPM_CPCCR_CE); +} + +// General clock functions. + +int jz4740_cpm_have_clock(void *cpm_base) +{ + // NOTE: To check. +#ifdef CONFIG_CPU_JZ4730 + return cpm_ctrl_get(cpm_base, CPM_MSCR) != 0; +#else + return cpm_ctrl_get(cpm_base, CPM_CLKGR) != 0; +#endif +} + +int jz4740_cpm_have_pll(void *cpm_base) +{ + return cpm_ctrl_get(cpm_base, CPM_CPPCR) & CPM_CPPCR_PLLS; +} + +void jz4740_cpm_start_clock(void *cpm_base) +{ +#ifdef CONFIG_CPU_JZ4730 + cpm_start_ost(cpm_base); + cpm_ctrl_set(cpm_base, CPM_MSCR, cpm_ctrl_get(cpm_base, CPM_MSCR) & ~CPM_MSCR_MSTP_OST); +#else + cpm_ctrl_set(cpm_base, CPM_CLKGR, cpm_ctrl_get(cpm_base, CPM_CLKGR) & ~CPM_CLKGR_TCU); +#endif +} + +// Peripheral clock control. + +void jz4740_cpm_start_lcd(void *cpm_base) +{ +#ifndef CONFIG_CPU_JZ4730 + cpm_ctrl_set(cpm_base, CPM_CLKGR, cpm_ctrl_get(cpm_base, CPM_CLKGR) & ~CPM_CLKGR_LCD); +#endif +} + +void jz4740_cpm_stop_lcd(void *cpm_base) +{ +#ifndef CONFIG_CPU_JZ4730 + cpm_ctrl_set(cpm_base, CPM_CLKGR, cpm_ctrl_get(cpm_base, CPM_CLKGR) | CPM_CLKGR_LCD); +#endif +} + +// Register access. + +uint32_t jz4740_cpm_ctrl_get(void *cpm_base, uint32_t reg) +{ + return cpm_ctrl_get(cpm_base, reg); +} + +void jz4740_cpm_ctrl_set(void *cpm_base, uint32_t reg, uint32_t value) +{ + cpm_ctrl_set(cpm_base, reg, value); +} + +/* Top-level initialisation. */ + +void cpm_init() +{ +#ifdef CONFIG_CPU_JZ4730 + cpm_ctrl_set((void *) CPM_BASE, CPM_MSCR, 0xffffffff); +#else + cpm_ctrl_set((void *) CPM_BASE, CPM_CLKGR, 0x7fff); +#endif +} + diff -r 6cf4059ed447 -r 217a6336c508 stage2/cpm.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stage2/cpm.h Tue Jul 11 00:03:30 2017 +0200 @@ -0,0 +1,77 @@ +#ifndef __CPM_H__ +#define __CPM_H__ + +#include + +/* Public functions. */ + +int jz4740_init(); + +int jz4740_cpm_have_pll(void *cpm_base); + +int jz4740_cpm_have_clock(void *cpm_base); +void jz4740_cpm_start_clock(void *cpm_base); + +uint32_t jz4740_cpm_get_cpu_frequency(void *cpm_base); +uint32_t jz4740_cpm_get_memory_frequency(void *cpm_base); + +void jz4740_cpm_set_lcd_frequencies(void *cpm_base, uint32_t pclk, uint8_t ratio); +void jz4740_cpm_update_output_frequency(void *cpm_base); + +void jz4740_cpm_start_lcd(void *cpm_base); +void jz4740_cpm_stop_lcd(void *cpm_base); + +uint32_t jz4740_cpm_ctrl_get(void *cpm_base, uint32_t reg); +void jz4740_cpm_ctrl_set(void *cpm_base, uint32_t reg, uint32_t value); + +/* Register offsets. */ + +#define CPM_CPCCR 0x00 +#define CPM_LCR 0x04 +#define CPM_RSR 0x08 +#define CPM_CPPCR 0x10 + +#ifdef CONFIG_CPU_JZ4730 + +/* Names used by the jz4730. */ + +#define CPM_CFCR CPM_CPCCR +#define CPM_LPCR CPM_LCR +#define CPM_RSTR CPM_RSR +#define CPM_PLCR1 CPM_CPPCR +#define CPM_CFCR2 CPM_I2SCDR /* apparently used by the LCD */ + +/* Registers used by the jz4730. */ + +#define CPM_OCR 0x1c +#define CPM_MSCR 0x20 /* different layout to CLKGR */ +#define CPM_WRER 0x28 +#define CPM_WFER 0x2c +#define CPM_WER 0x30 +#define CPM_WSR 0x34 +#define CPM_GSR0 0x38 +#define CPM_GSR1 0x3c +#define CPM_GSR2 0x40 +#define CPM_SPR 0x44 +#define CPM_GSR3 0x48 + +#else + +/* Registers used by the jz4740. */ + +#define CPM_CLKGR 0x20 +#define CPM_SCR 0x24 +#define CPM_HCR 0x30 +#define CPM_HWFCR 0x34 +#define CPM_HRCR 0x38 +#define CPM_HWCR 0x3c +#define CPM_HWSR 0x40 +#define CPM_HSPR 0x44 +#define CPM_I2SCDR 0x60 +#define CPM_LPCDR 0x64 +#define CPM_MSCCDR 0x68 +#define CPM_UHCCDR 0x6C + +#endif + +#endif /* __CPM_H__ */ diff -r 6cf4059ed447 -r 217a6336c508 stage2/lcd.c --- a/stage2/lcd.c Sun Jul 09 19:04:49 2017 +0200 +++ b/stage2/lcd.c Tue Jul 11 00:03:30 2017 +0200 @@ -24,6 +24,7 @@ #include "jzlcd.h" #include "sdram.h" #include "cpu.h" +#include "cpm.h" #include "board.h" extern vidinfo_t panel_info; @@ -262,76 +263,14 @@ /* LCD initialisation. */ -#ifdef CONFIG_CPU_JZ4730 -void jz4730_set_lcd_frequencies(uint32_t pclk, uint8_t ratio) -{ - uint32_t val; - - val = __cpm_get_pllout() / pclk; - REG_CPM_CFCR2 = val - 1; - val = pclk * ratio; - - if (val > 150000000) { - val = 150000000; - } - - val = __cpm_get_pllout() / val; - val--; - - if (val > 0xF) - val = 0xF; - - __cpm_set_ldiv(val); - REG_CPM_CPCCR = REG_CPM_CPCCR | CPM_CPCCR_CE; /* update divide */ -} -#else -void jz4740_set_lcd_frequencies(uint32_t pclk, uint8_t ratio) -{ - uint32_t val; - int pll_div; - - pll_div = REG_CPM_CPCCR & CPM_CPCCR_PCS; /* clock source,0:pllout/2 1: pllout */ - pll_div = pll_div ? 1 : 2; - val = (__cpm_get_pllout() / pll_div) / pclk; - val--; - - if ( val > 0x1ff ) { - val = 0x1ff; - } - - __cpm_set_pixdiv(val); - - val = pclk * ratio; /* LCDClock > 2.5*Pixclock */ - - if ( val > 150000000 ) { - val = 150000000; - } - - val = (__cpm_get_pllout() / pll_div) / val; - val--; - - if (val > 0x1f) - val = 0x1f; - - __cpm_set_ldiv(val); - REG_CPM_CPCCR = REG_CPM_CPCCR | CPM_CPCCR_CE; /* update divide */ -} -#endif - void lcd_set_timing(vidinfo_t *vid) { uint32_t pclk = jz4740_lcd_get_pixel_clock(vid); - __cpm_stop_lcd(); - -#ifdef CONFIG_CPU_JZ4730 - jz4730_set_lcd_frequencies(pclk, 4); -#else - jz4740_set_lcd_frequencies(pclk, 3); -#endif - - __cpm_start_lcd(); - udelay(1000); + jz4740_cpm_stop_lcd((void *) CPM_BASE); + jz4740_cpm_set_lcd_frequencies((void *) CPM_BASE, pclk, 3); + jz4740_cpm_start_lcd((void *) CPM_BASE); + udelay(1000); } static void lcd_display_pin_init() @@ -374,7 +313,7 @@ fb_vaddr = (void *) (get_memory_size() - jz4740_lcd_get_total_size(vid)); - jz4740_lcd_ctrl_init((void *) LCD_BASE_KSEG1, fb_vaddr, vid); + jz4740_lcd_ctrl_init((void *) LCD_BASE, fb_vaddr, vid); flush_cache_all(); jz4740_lcd_hw_init(vid); lcd_set_timing(vid); diff -r 6cf4059ed447 -r 217a6336c508 stage2/lcd.h --- a/stage2/lcd.h Sun Jul 09 19:04:49 2017 +0200 +++ b/stage2/lcd.h Tue Jul 11 00:03:30 2017 +0200 @@ -3,8 +3,6 @@ #include -#define LCD_BASE_KSEG1 0xB3050000 - /* Initialisation functions. */ void lcd_init(); diff -r 6cf4059ed447 -r 217a6336c508 stage2/nanonote_gpm940b0.h --- a/stage2/nanonote_gpm940b0.h Sun Jul 09 19:04:49 2017 +0200 +++ b/stage2/nanonote_gpm940b0.h Tue Jul 11 00:03:30 2017 +0200 @@ -55,7 +55,6 @@ static inline void __lcd_display_pin_init() { - __cpm_start_tcu(); __gpio_as_output(SPEN); __gpio_as_output(SPCK); __gpio_as_output(SPDA);