From dd865bcd1ef03b32df1bd65508e991d0ae9e5f63 Mon Sep 17 00:00:00 2001 From: Amaury Pouly Date: Sat, 3 Dec 2011 15:34:40 +0000 Subject: imx233: add control for more clocks, add debug clock debug screen git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31121 a1c6a512-1295-4272-9138-f99709370657 --- firmware/target/arm/imx233/clkctrl-imx233.c | 245 +++++++++++++++++++++++++++- firmware/target/arm/imx233/clkctrl-imx233.h | 81 ++++++++- firmware/target/arm/imx233/debug-imx233.c | 122 +++++++++++++- 3 files changed, 434 insertions(+), 14 deletions(-) (limited to 'firmware/target') diff --git a/firmware/target/arm/imx233/clkctrl-imx233.c b/firmware/target/arm/imx233/clkctrl-imx233.c index 31fccd3e3b..fa94f23a0f 100644 --- a/firmware/target/arm/imx233/clkctrl-imx233.c +++ b/firmware/target/arm/imx233/clkctrl-imx233.c @@ -23,7 +23,7 @@ #define __CLK_CLKGATE (1 << 31) #define __CLK_BUSY (1 << 29) -void imx233_enable_xtal_clock(enum imx233_xtal_clkt_t xtal_clk, bool enable) +void imx233_enable_xtal_clock(enum imx233_xtal_clk_t xtal_clk, bool enable) { if(enable) __REG_CLR(HW_CLKCTRL_XTAL) = xtal_clk; @@ -31,6 +31,11 @@ void imx233_enable_xtal_clock(enum imx233_xtal_clkt_t xtal_clk, bool enable) __REG_SET(HW_CLKCTRL_XTAL) = xtal_clk; } +bool imx233_is_xtal_clock_enable(enum imx233_xtal_clk_t clk) +{ + return HW_CLKCTRL_XTAL & clk; +} + void imx233_enable_clock(enum imx233_clock_t clk, bool enable) { volatile uint32_t *REG; @@ -55,6 +60,20 @@ void imx233_enable_clock(enum imx233_clock_t clk, bool enable) } } +bool imx233_is_clock_enable(enum imx233_clock_t clk) +{ + volatile uint32_t *REG; + switch(clk) + { + case CLK_PLL: return HW_CLKCTRL_PLLCTRL0 & HW_CLKCTRL_PLLCTRL0__POWER; + case CLK_PIX: REG = &HW_CLKCTRL_PIX; break; + case CLK_SSP: REG = &HW_CLKCTRL_SSP; break; + default: return true; + } + + return !((*REG) & __CLK_CLKGATE); +} + void imx233_set_clock_divisor(enum imx233_clock_t clk, int div) { switch(clk) @@ -74,24 +93,57 @@ void imx233_set_clock_divisor(enum imx233_clock_t clk, int div) __REG_SET(HW_CLKCTRL_CPU) = div; while(HW_CLKCTRL_CPU & HW_CLKCTRL_CPU__BUSY_REF_CPU); break; - case CLK_AHB: - __REG_CLR(HW_CLKCTRL_HBUS) = HW_CLKCTRL_HBUS__DIV_BM; + case CLK_EMI: + __REG_CLR(HW_CLKCTRL_EMI) = HW_CLKCTRL_EMI__DIV_EMI_BM; + __REG_SET(HW_CLKCTRL_EMI) = div; + while(HW_CLKCTRL_EMI & HW_CLKCTRL_EMI__BUSY_REF_EMI); + break; + case CLK_HBUS: + __REG_CLR(HW_CLKCTRL_HBUS) = HW_CLKCTRL_HBUS__DIV_BM | HW_CLKCTRL_HBUS__DIV_FRAC_EN; __REG_SET(HW_CLKCTRL_HBUS) = div; while(HW_CLKCTRL_HBUS & __CLK_BUSY); break; + case CLK_XBUS: + __REG_CLR(HW_CLKCTRL_XBUS) = HW_CLKCTRL_XBUS__DIV_BM; + __REG_SET(HW_CLKCTRL_XBUS) = div; + while(HW_CLKCTRL_XBUS & __CLK_BUSY); + break; default: return; } } +int imx233_get_clock_divisor(enum imx233_clock_t clk) +{ + switch(clk) + { + case CLK_PIX: return __XTRACT(HW_CLKCTRL_PIX, DIV); + case CLK_SSP: return __XTRACT(HW_CLKCTRL_SSP, DIV); + case CLK_CPU: return __XTRACT(HW_CLKCTRL_CPU, DIV_CPU); + case CLK_EMI: return __XTRACT(HW_CLKCTRL_EMI, DIV_EMI); + case CLK_HBUS: + if(HW_CLKCTRL_HBUS & HW_CLKCTRL_HBUS__DIV_FRAC_EN) + return 0; + else + return __XTRACT(HW_CLKCTRL_HBUS, DIV); + case CLK_XBUS: return __XTRACT(HW_CLKCTRL_XBUS, DIV); + default: return 0; + } +} + void imx233_set_fractional_divisor(enum imx233_clock_t clk, int fracdiv) { /* NOTE: HW_CLKCTRL_FRAC only support byte access ! */ volatile uint8_t *REG; switch(clk) { + case CLK_HBUS: + __REG_CLR(HW_CLKCTRL_HBUS) = HW_CLKCTRL_HBUS__DIV_BM; + __REG_SET(HW_CLKCTRL_HBUS) = fracdiv | HW_CLKCTRL_HBUS__DIV_FRAC_EN; + return; case CLK_PIX: REG = &HW_CLKCTRL_FRAC_PIX; break; case CLK_IO: REG = &HW_CLKCTRL_FRAC_IO; break; case CLK_CPU: REG = &HW_CLKCTRL_FRAC_CPU; break; + case CLK_EMI: REG = &HW_CLKCTRL_FRAC_EMI; break; default: return; } @@ -101,6 +153,30 @@ void imx233_set_fractional_divisor(enum imx233_clock_t clk, int fracdiv) *REG = HW_CLKCTRL_FRAC_XX__CLKGATEXX;; } +int imx233_get_fractional_divisor(enum imx233_clock_t clk) +{ + /* NOTE: HW_CLKCTRL_FRAC only support byte access ! */ + volatile uint8_t *REG; + switch(clk) + { + case CLK_HBUS: + if(HW_CLKCTRL_HBUS & HW_CLKCTRL_HBUS__DIV_FRAC_EN) + return __XTRACT(HW_CLKCTRL_HBUS, DIV); + else + return 0; + case CLK_PIX: REG = &HW_CLKCTRL_FRAC_PIX; break; + case CLK_IO: REG = &HW_CLKCTRL_FRAC_IO; break; + case CLK_CPU: REG = &HW_CLKCTRL_FRAC_CPU; break; + case CLK_EMI: REG = &HW_CLKCTRL_FRAC_EMI; break; + default: return 0; + } + + if((*REG) & HW_CLKCTRL_FRAC_XX__CLKGATEXX) + return 0; + else + return *REG & ~HW_CLKCTRL_FRAC_XX__XX_STABLE; +} + void imx233_set_bypass_pll(enum imx233_clock_t clk, bool bypass) { uint32_t msk; @@ -109,6 +185,7 @@ void imx233_set_bypass_pll(enum imx233_clock_t clk, bool bypass) case CLK_PIX: msk = HW_CLKCTRL_CLKSEQ__BYPASS_PIX; break; case CLK_SSP: msk = HW_CLKCTRL_CLKSEQ__BYPASS_SSP; break; case CLK_CPU: msk = HW_CLKCTRL_CLKSEQ__BYPASS_CPU; break; + case CLK_EMI: msk = HW_CLKCTRL_CLKSEQ__BYPASS_EMI; break; default: return; } @@ -118,6 +195,21 @@ void imx233_set_bypass_pll(enum imx233_clock_t clk, bool bypass) __REG_CLR(HW_CLKCTRL_CLKSEQ) = msk; } +bool imx233_get_bypass_pll(enum imx233_clock_t clk) +{ + uint32_t msk; + switch(clk) + { + case CLK_PIX: msk = HW_CLKCTRL_CLKSEQ__BYPASS_PIX; break; + case CLK_SSP: msk = HW_CLKCTRL_CLKSEQ__BYPASS_SSP; break; + case CLK_CPU: msk = HW_CLKCTRL_CLKSEQ__BYPASS_CPU; break; + case CLK_EMI: msk = HW_CLKCTRL_CLKSEQ__BYPASS_EMI; break; + default: return false; + } + + return HW_CLKCTRL_CLKSEQ & msk; +} + void imx233_enable_usb_pll(bool enable) { if(enable) @@ -126,3 +218,150 @@ void imx233_enable_usb_pll(bool enable) __REG_CLR(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS; } +bool imx233_is_usb_pll_enable(void) +{ + return HW_CLKCTRL_PLLCTRL0 & HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS; +} + +void imx233_set_auto_slow_divisor(enum imx233_as_div_t div) +{ + __REG_CLR(HW_CLKCTRL_HBUS) = HW_CLKCTRL_HBUS__SLOW_DIV_BM; + __REG_SET(HW_CLKCTRL_HBUS) = div; +} + +enum imx233_as_div_t imx233_get_auto_slow_divisor(void) +{ + return __XTRACT(HW_CLKCTRL_HBUS, SLOW_DIV); +} + +void imx233_enable_auto_slow(bool enable) +{ + if(enable) + __REG_CLR(HW_CLKCTRL_HBUS) = HW_CLKCTRL_HBUS__AUTO_SLOW_MODE; + else + __REG_SET(HW_CLKCTRL_HBUS) = HW_CLKCTRL_HBUS__AUTO_SLOW_MODE; +} + +bool imx233_is_auto_slow_enable(void) +{ + return HW_CLKCTRL_HBUS & HW_CLKCTRL_HBUS__AUTO_SLOW_MODE; +} + +void imx233_enable_auto_slow_monitor(enum imx233_as_monitor_t monitor, bool enable) +{ + if(enable) + __REG_SET(HW_CLKCTRL_HBUS) = monitor; + else + __REG_CLR(HW_CLKCTRL_HBUS) = monitor; +} + +bool imx233_is_auto_slow_monitor_enable(enum imx233_as_monitor_t monitor) +{ + return HW_CLKCTRL_HBUS & monitor; +} + +unsigned imx233_get_clock_freq(enum imx233_clock_t clk) +{ + switch(clk) + { + case CLK_PLL: /* PLL: 480MHz when enable */ + return imx233_is_clock_enable(CLK_PLL) ? 480000 : 0; + case CLK_XTAL: /* crytsal: 24MHz */ + return 24000; + case CLK_CPU: + { + unsigned ref; + /* In bypass mode: clk_p derived from clk_xtal via int/binfrac divider + * otherwise, clk_p derived from clk_cpu via int div and clk_cpu + * derived from clk_pll fracdiv */ + if(imx233_get_bypass_pll(CLK_CPU)) + { + ref = imx233_get_clock_freq(CLK_XTAL); + /* Integer divide mode vs fractional divide mode */ + if(HW_CLKCTRL_CPU & HW_CLKCTRL_CPU__DIV_XTAL_FRAC_EN) + + return (ref * __XTRACT(HW_CLKCTRL_CPU, DIV_XTAL)) / 32; + else + return ref / imx233_get_clock_divisor(CLK_CPU); + } + else + { + ref = imx233_get_clock_freq(CLK_PLL); + /* fractional divider enable ? */ + if(imx233_get_fractional_divisor(CLK_CPU) != 0) + ref = (ref * 18) / imx233_get_fractional_divisor(CLK_CPU); + return ref / imx233_get_clock_divisor(CLK_CPU); + } + } + case CLK_HBUS: + { + /* Derived from clk_p via integer/fractional div */ + unsigned ref = imx233_get_clock_freq(CLK_CPU); + if(imx233_get_fractional_divisor(CLK_HBUS) != 0) + ref = (ref * imx233_get_fractional_divisor(CLK_HBUS)) / 32; + if(imx233_get_clock_divisor(CLK_HBUS) != 0) + ref /= imx233_get_clock_divisor(CLK_HBUS); + return ref; + } + case CLK_IO: + { + /* Derived from clk_pll via fracdiv */ + unsigned ref = imx233_get_clock_freq(CLK_PLL); + if(imx233_get_fractional_divisor(CLK_IO) != 0) + ref = (ref * 18) / imx233_get_fractional_divisor(CLK_IO); + return ref; + } + case CLK_PIX: + { + unsigned ref; + /* Derived from clk_pll or clk_xtal */ + if(!imx233_is_clock_enable(CLK_PIX)) + ref = 0; + else if(imx233_get_bypass_pll(CLK_PIX)) + ref = imx233_get_clock_freq(CLK_XTAL); + else + { + ref = imx233_get_clock_freq(CLK_PLL); + if(imx233_get_fractional_divisor(CLK_PIX) != 0) + ref = (ref * 18) / imx233_get_fractional_divisor(CLK_PIX); + } + return ref / imx233_get_clock_divisor(CLK_PIX); + } + case CLK_SSP: + { + unsigned ref; + /* Derived from clk_pll or clk_xtal */ + if(!imx233_is_clock_enable(CLK_SSP)) + ref = 0; + else if(imx233_get_bypass_pll(CLK_SSP)) + ref = imx233_get_clock_freq(CLK_XTAL); + else + ref = imx233_get_clock_freq(CLK_IO); + return ref / imx233_get_clock_divisor(CLK_SSP); + } + case CLK_EMI: + { + unsigned ref; + /* Derived from clk_pll or clk_xtal */ + if(imx233_get_bypass_pll(CLK_EMI)) + { + ref = imx233_get_clock_freq(CLK_XTAL); + if(HW_CLKCTRL_EMI & HW_CLKCTRL_EMI__CLKGATE) + return 0; + else + return ref / __XTRACT(HW_CLKCTRL_EMI, DIV_XTAL); + } + else + { + ref = imx233_get_clock_freq(CLK_PLL); + if(imx233_get_fractional_divisor(CLK_EMI) != 0) + ref = (ref * 18) / imx233_get_fractional_divisor(CLK_EMI); + return ref / imx233_get_clock_divisor(CLK_EMI); + } + } + case CLK_XBUS: + return imx233_get_clock_freq(CLK_XTAL) / imx233_get_clock_divisor(CLK_XBUS); + default: + return 0; + } +} diff --git a/firmware/target/arm/imx233/clkctrl-imx233.h b/firmware/target/arm/imx233/clkctrl-imx233.h index e59f954071..fc835c813a 100644 --- a/firmware/target/arm/imx233/clkctrl-imx233.h +++ b/firmware/target/arm/imx233/clkctrl-imx233.h @@ -28,6 +28,7 @@ #define HW_CLKCTRL_BASE 0x80040000 #define HW_CLKCTRL_PLLCTRL0 (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x0)) +#define HW_CLKCTRL_PLLCTRL0__POWER (1 << 16) #define HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS (1 << 18) #define HW_CLKCTRL_PLLCTRL0__DIV_SEL_BP 20 #define HW_CLKCTRL_PLLCTRL0__DIV_SEL_BM (3 << 20) @@ -37,11 +38,19 @@ #define HW_CLKCTRL_CPU (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x20)) #define HW_CLKCTRL_CPU__DIV_CPU_BP 0 #define HW_CLKCTRL_CPU__DIV_CPU_BM 0x3f +#define HW_CLKCTRL_CPU__INTERRUPT_WAIT (1 << 12) +#define HW_CLKCTRL_CPU__DIV_XTAL_BP 16 +#define HW_CLKCTRL_CPU__DIV_XTAL_BM (0x3ff << 16) +#define HW_CLKCTRL_CPU__DIV_XTAL_FRAC_EN (1 << 26) #define HW_CLKCTRL_CPU__BUSY_REF_CPU (1 << 28) #define HW_CLKCTRL_HBUS (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x30)) -#define HW_CLKCTRL_HBUS__DIV_BP 0 -#define HW_CLKCTRL_HBUS__DIV_BM 0x1f +#define HW_CLKCTRL_HBUS__DIV_BP 0 +#define HW_CLKCTRL_HBUS__DIV_BM 0x1f +#define HW_CLKCTRL_HBUS__DIV_FRAC_EN (1 << 5) +#define HW_CLKCTRL_HBUS__SLOW_DIV_BP 16 +#define HW_CLKCTRL_HBUS__SLOW_DIV_BM (0x7 << 16) +#define HW_CLKCTRL_HBUS__AUTO_SLOW_MODE (1 << 20) #define HW_CLKCTRL_XBUS (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x40)) #define HW_CLKCTRL_XBUS__DIV_BP 0 @@ -54,14 +63,26 @@ #define HW_CLKCTRL_XTAL__FILT_CLK24M_GATE (1 << 30) #define HW_CLKCTRL_PIX (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x60)) +#define HW_CLKCTRL_PIX__DIV_BP 0 #define HW_CLKCTRL_PIX__DIV_BM 0xfff #define HW_CLKCTRL_SSP (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x70)) +#define HW_CLKCTRL_SSP__DIV_BP 0 #define HW_CLKCTRL_SSP__DIV_BM 0x1ff +#define HW_CLKCTRL_EMI (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xa0)) +#define HW_CLKCTRL_EMI__DIV_EMI_BP 0 +#define HW_CLKCTRL_EMI__DIV_EMI_BM 0x3f +#define HW_CLKCTRL_EMI__DIV_XTAL_BP 8 +#define HW_CLKCTRL_EMI__DIV_XTAL_BM (0xf << 8) +#define HW_CLKCTRL_EMI__BUSY_REF_EMI (1 << 28) +#define HW_CLKCTRL_EMI__SYNC_MODE_EN (1 << 30) +#define HW_CLKCTRL_EMI__CLKGATE (1 << 31) + #define HW_CLKCTRL_CLKSEQ (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x110)) #define HW_CLKCTRL_CLKSEQ__BYPASS_PIX (1 << 1) #define HW_CLKCTRL_CLKSEQ__BYPASS_SSP (1 << 5) +#define HW_CLKCTRL_CLKSEQ__BYPASS_EMI (1 << 6) #define HW_CLKCTRL_CLKSEQ__BYPASS_CPU (1 << 7) #define HW_CLKCTRL_FRAC (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xf0)) @@ -79,28 +100,70 @@ enum imx233_clock_t { - CLK_PIX, /* div, frac */ - CLK_SSP, /* div, frac */ - CLK_IO, /* div */ - CLK_CPU, /* div, frac */ - CLK_AHB /* div */ + CLK_PIX, /* freq, div, frac, bypass, enable */ + CLK_SSP, /* freq, div, bypass, enable */ + CLK_IO, /* freq, frac */ + CLK_CPU, /* freq, div, frac, bypass */ + CLK_HBUS, /* freq, div, frac */ + CLK_PLL, /* freq */ + CLK_XTAL, /* freq */ + CLK_EMI, /* freq */ + CLK_XBUS, /* freq, div */ }; -enum imx233_xtal_clkt_t +enum imx233_xtal_clk_t { XTAL_FILT = 1 << 30, XTAL_DRI = 1 << 28, XTAL_TIMROT = 1 << 26, }; +/* Auto-Slow monitoring */ +enum imx233_as_monitor_t +{ + AS_CPU_INSTR = 1 << 21, /* Monitor CPU instruction access to AHB */ + AS_CPU_DATA = 1 << 22, /* Monitor CPU data access to AHB */ + AS_TRAFFIC = 1 << 23, /* Monitor AHB master activity */ + AS_TRAFFIC_JAM = 1 << 24, /* Monitor AHB masters (>=3) activity */ + AS_APBXDMA = 1 << 25, /* Monitor APBX DMA activity */ + AS_APBHDMA = 1 << 26, /* Monitor APBH DMA activity */ + AS_PXP = 1 << 27, /* Monitor PXP activity */ + AS_DCP = 1 << 28, /* Monitor DCP activity */ +}; + +enum imx233_as_div_t +{ + AS_DIV_1 = 0, + AS_DIV_2 = 1, + AS_DIV_4 = 2, + AS_DIV_8 = 3, + AS_DIV_16 = 4, + AS_DIV_32 = 5 +}; + /* can use a mask of clocks */ -void imx233_enable_xtal_clock(enum imx233_xtal_clkt_t xtal_clk, bool enable); +void imx233_enable_xtal_clock(enum imx233_xtal_clk_t xtal_clk, bool enable); +bool imx233_is_xtal_clock_enable(enum imx233_xtal_clk_t clk); /* only use it for non-fractional clocks (ie not for IO) */ void imx233_enable_clock(enum imx233_clock_t clk, bool enable); +bool imx233_is_clock_enable(enum imx233_clock_t cl); void imx233_set_clock_divisor(enum imx233_clock_t clk, int div); +int imx233_get_clock_divisor(enum imx233_clock_t clk); /* call with fracdiv=0 to disable it */ void imx233_set_fractional_divisor(enum imx233_clock_t clk, int fracdiv); +/* 0 means fractional dividor disable */ +int imx233_get_fractional_divisor(enum imx233_clock_t clk); void imx233_set_bypass_pll(enum imx233_clock_t clk, bool bypass); +bool imx233_get_bypass_pll(enum imx233_clock_t clk); void imx233_enable_usb_pll(bool enable); +bool imx233_is_usb_pll_enable(void); +unsigned imx233_get_clock_freq(enum imx233_clock_t clk); + +void imx233_set_auto_slow_divisor(enum imx233_as_div_t div); +enum imx233_as_div_t imx233_get_auto_slow_divisor(void); +void imx233_enable_auto_slow(bool enable); +bool imx233_is_auto_slow_enable(void); +void imx233_enable_auto_slow_monitor(enum imx233_as_monitor_t monitor, bool enable); +bool imx233_is_auto_slow_monitor_enable(enum imx233_as_monitor_t monitor); #endif /* CLKCTRL_IMX233_H */ diff --git a/firmware/target/arm/imx233/debug-imx233.c b/firmware/target/arm/imx233/debug-imx233.c index 7eacbf7523..e6b07aef58 100644 --- a/firmware/target/arm/imx233/debug-imx233.c +++ b/firmware/target/arm/imx233/debug-imx233.c @@ -28,7 +28,9 @@ #include "adc.h" #include "adc-imx233.h" #include "power-imx233.h" +#include "clkctrl-imx233.h" #include "powermgmt.h" +#include "string.h" static struct { @@ -88,7 +90,7 @@ bool dbg_hw_info_power(void) while(1) { - int button = get_action(CONTEXT_STD, HZ / 25); + int button = get_action(CONTEXT_STD, HZ / 10); switch(button) { case ACTION_STD_NEXT: @@ -151,9 +153,125 @@ bool dbg_hw_info_adc(void) } } +static struct +{ + enum imx233_clock_t clk; + const char *name; + bool has_enable; + bool has_bypass; + bool has_idiv; + bool has_fdiv; + bool has_freq; +} dbg_clk[] = +{ + { CLK_PLL, "pll", true, false, false, false, true}, + { CLK_XTAL, "xtal", false, false, false, false, true}, + { CLK_PIX, "pix", true, true, true, true, true }, + { CLK_SSP, "ssp", true, true, true, false, true }, + { CLK_IO, "io", false, false, false, true, true }, + { CLK_CPU, "cpu", false, true, true, true, true }, + { CLK_HBUS, "hbus", false, false, true, true, true }, + { CLK_EMI, "emi", false, true, true, true, true }, + { CLK_XBUS, "xbus", false, false, true, false, true } +}; + +static struct +{ + enum imx233_as_monitor_t monitor; + const char *name; +} dbg_as_monitor[] = +{ + { AS_CPU_INSTR, "cpu inst" }, + { AS_CPU_DATA, "cpu data" }, + { AS_TRAFFIC, "traffic" }, + { AS_TRAFFIC_JAM, "traffic jam" }, + { AS_APBXDMA, "apbx" }, + { AS_APBHDMA, "apbh" }, + { AS_PXP, "pxp" }, + { AS_DCP, "dcp" } +}; + +bool dbg_hw_info_clkctrl(void) +{ + lcd_setfont(FONT_SYSFIXED); + imx233_enable_auto_slow_monitor(AS_CPU_INSTR, true); + imx233_enable_auto_slow_monitor(AS_CPU_DATA, true); + imx233_enable_auto_slow_monitor(AS_TRAFFIC, true); + imx233_enable_auto_slow_monitor(AS_TRAFFIC_JAM, true); + imx233_enable_auto_slow_monitor(AS_APBXDMA, true); + imx233_enable_auto_slow_monitor(AS_APBHDMA, true); + + while(1) + { + int button = get_action(CONTEXT_STD, HZ / 10); + switch(button) + { + case ACTION_STD_NEXT: + case ACTION_STD_PREV: + case ACTION_STD_OK: + case ACTION_STD_MENU: + lcd_setfont(FONT_UI); + return true; + case ACTION_STD_CANCEL: + lcd_setfont(FONT_UI); + return false; + } + + lcd_clear_display(); + + /* 012345678901234567890123456789 */ + lcd_putsf(0, 0, "name en by idiv fdiv frequency"); + for(unsigned i = 0; i < ARRAYLEN(dbg_clk); i++) + { + #define c dbg_clk[i] + lcd_putsf(0, i + 1, "%4s", c.name); + if(c.has_enable) + lcd_putsf(5, i + 1, "%2d", imx233_is_clock_enable(c.clk)); + if(c.has_bypass) + lcd_putsf(8, i + 1, "%2d", imx233_get_bypass_pll(c.clk)); + if(c.has_idiv && imx233_get_clock_divisor(c.clk) != 0) + lcd_putsf(10, i + 1, "%4d", imx233_get_clock_divisor(c.clk)); + if(c.has_fdiv && imx233_get_fractional_divisor(c.clk) != 0) + lcd_putsf(16, i + 1, "%4d", imx233_get_fractional_divisor(c.clk)); + if(c.has_freq) + lcd_putsf(21, i + 1, "%9d", imx233_get_clock_freq(c.clk)); + #undef c + } + int line = ARRAYLEN(dbg_clk) + 1; + lcd_putsf(0, line, "auto slow: %d", imx233_is_auto_slow_enable()); + line++; + lcd_putsf(0, line, "as monitor: "); + int x_off = 12; + bool first = true; + unsigned line_w = lcd_getwidth() / font_get_width(font_get(lcd_getfont()), ' '); + for(unsigned i = 0; i < ARRAYLEN(dbg_as_monitor); i++) + { + if(!imx233_is_auto_slow_monitor_enable(dbg_as_monitor[i].monitor)) + continue; + if(!first) + { + lcd_putsf(x_off, line, ", "); + x_off += 2; + } + first = false; + if((x_off + strlen(dbg_as_monitor[i].name)) > line_w) + { + x_off = 1; + line++; + } + lcd_putsf(x_off, line, "%s", dbg_as_monitor[i].name); + x_off += strlen(dbg_as_monitor[i].name); + } + line++; + + lcd_update(); + yield(); + } +} + bool dbg_hw_info(void) { - return dbg_hw_info_dma() && dbg_hw_info_adc() && dbg_hw_info_power() && + return dbg_hw_info_clkctrl() && dbg_hw_info_dma() && dbg_hw_info_adc() && dbg_hw_info_power() && dbg_hw_target_info(); } -- cgit v1.2.3