Re: [PATCH] I2C: Fix twl4030 timeouts on omap3430
On Tue, Apr 01, 2008 at 03:43:56PM +0300, ext Tony Lindgren wrote: * Tony Lindgren [EMAIL PROTECTED] [080331 17:30]: * Tony Lindgren [EMAIL PROTECTED] [080331 13:43]: * Tony Lindgren [EMAIL PROTECTED] [080328 10:41]: Hi all, This helps with the annoying I2C timeouts. Does anybody have an idea why the twl4030 chip does not like doing multiple transfers in a row? To me the only difference seems to be that clocks are idled between writing the twl4030 register and reading the register value. I'll push this today with a REVISIT comment added. Looks like this kills twl4030 interrupts, so I've reverted it. After looking into this problem a bit more, looks like twl4030 reads to anything in POWER ID (modules 0x10 and higher) will hang twl4030 eventually and I2C controller gets stuck in mode where STP never clears. Repeated reads to USB ID, AUD ID or AUX ID will not hang twl4030. I remember seeing something similar when doing the powerbutton code. Klaus Pedersen found out that leaving CFG_BOOT to its reset value solved the problem. Unfortunately this breaks MADC and USB afaics, so it's not a real solution. CFG_BOOT is programmed in power_companion_init(). Cheers, Peter. -- goa is a state of mind -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] I2C: Fix twl4030 timeouts on omap3430
* Tony Lindgren [EMAIL PROTECTED] [080401 16:39]: * Peter 'p2' De Schrijver [EMAIL PROTECTED] [080401 16:01]: On Tue, Apr 01, 2008 at 03:43:56PM +0300, ext Tony Lindgren wrote: * Tony Lindgren [EMAIL PROTECTED] [080331 17:30]: * Tony Lindgren [EMAIL PROTECTED] [080331 13:43]: * Tony Lindgren [EMAIL PROTECTED] [080328 10:41]: Hi all, This helps with the annoying I2C timeouts. Does anybody have an idea why the twl4030 chip does not like doing multiple transfers in a row? To me the only difference seems to be that clocks are idled between writing the twl4030 register and reading the register value. I'll push this today with a REVISIT comment added. Looks like this kills twl4030 interrupts, so I've reverted it. After looking into this problem a bit more, looks like twl4030 reads to anything in POWER ID (modules 0x10 and higher) will hang twl4030 eventually and I2C controller gets stuck in mode where STP never clears. Repeated reads to USB ID, AUD ID or AUX ID will not hang twl4030. I remember seeing something similar when doing the powerbutton code. Klaus Pedersen found out that leaving CFG_BOOT to its reset value solved the problem. Unfortunately this breaks MADC and USB afaics, so it's not a real solution. CFG_BOOT is programmed in power_companion_init(). Great, this helped a lot! Looks like power_companion_init() tries to get osc_ck without checking for clkg_get() return value, and osc_ck does not exist in clock34xx.h. So R_CFG_BOOT gets set to default 26MHz value :) Will post a patch when available. Thanks again, here's a patch, I've pushed it also. Tony From: Tony Lindgren [EMAIL PROTECTED] Date: Tue, 1 Apr 2008 16:58:02 +0300 Subject: [PATCH] I2C: Fix twl4030 clock init Without this patch twl4030 clock can get programmed to incorrect rate which can eventually hang twl4030 reads. Also minor formatting fixes. Signed-off-by: Tony Lindgren [EMAIL PROTECTED] --- a/drivers/i2c/chips/twl4030-core.c +++ b/drivers/i2c/chips/twl4030-core.c @@ -672,11 +672,20 @@ static int power_companion_init(void) u32 rate, ctrl = HFCLK_FREQ_26_MHZ; int e = 0; - osc = clk_get(NULL,osc_ck); + if (cpu_is_omap2430()) + osc = clk_get(NULL, osc_ck); + else + osc = clk_get(NULL, osc_sys_ck); + if (IS_ERR(osc)) { + printk(KERN_ERR Skipping twl3040 internal clock init and +using bootloader value (unknown osc rate)\n); + return 0; + } + rate = clk_get_rate(osc); clk_put(osc); - switch(rate) { + switch (rate) { case 1920 : ctrl = HFCLK_FREQ_19p2_MHZ; break; case 2600 : ctrl = HFCLK_FREQ_26_MHZ; break; case 3840 : ctrl = HFCLK_FREQ_38p4_MHZ; break; @@ -684,7 +693,7 @@ static int power_companion_init(void) ctrl |= HIGH_PERF_SQ; e |= unprotect_pm_master(); - /* effect-MADC+USB ck en */ + /* effect-MADC+USB ck en */ e |= twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, ctrl, R_CFG_BOOT); e |= protect_pm_master();
Re: [PATCH] I2C: Fix twl4030 timeouts on omap3430
* Peter 'p2' De Schrijver [EMAIL PROTECTED] [080401 16:01]: On Tue, Apr 01, 2008 at 03:43:56PM +0300, ext Tony Lindgren wrote: * Tony Lindgren [EMAIL PROTECTED] [080331 17:30]: * Tony Lindgren [EMAIL PROTECTED] [080331 13:43]: * Tony Lindgren [EMAIL PROTECTED] [080328 10:41]: Hi all, This helps with the annoying I2C timeouts. Does anybody have an idea why the twl4030 chip does not like doing multiple transfers in a row? To me the only difference seems to be that clocks are idled between writing the twl4030 register and reading the register value. I'll push this today with a REVISIT comment added. Looks like this kills twl4030 interrupts, so I've reverted it. After looking into this problem a bit more, looks like twl4030 reads to anything in POWER ID (modules 0x10 and higher) will hang twl4030 eventually and I2C controller gets stuck in mode where STP never clears. Repeated reads to USB ID, AUD ID or AUX ID will not hang twl4030. I remember seeing something similar when doing the powerbutton code. Klaus Pedersen found out that leaving CFG_BOOT to its reset value solved the problem. Unfortunately this breaks MADC and USB afaics, so it's not a real solution. CFG_BOOT is programmed in power_companion_init(). Great, this helped a lot! Looks like power_companion_init() tries to get osc_ck without checking for clkg_get() return value, and osc_ck does not exist in clock34xx.h. So R_CFG_BOOT gets set to default 26MHz value :) Will post a patch when available. Tony -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] I2C: Fix twl4030 timeouts on omap3430
Hi all, This helps with the annoying I2C timeouts. Does anybody have an idea why the twl4030 chip does not like doing multiple transfers in a row? To me the only difference seems to be that clocks are idled between writing the twl4030 register and reading the register value. Regards, Tony From 25c4c8f449819cb6f40b59ed1a9b25ebcc7cd72e Mon Sep 17 00:00:00 2001 From: Tony Lindgren [EMAIL PROTECTED] Date: Thu, 27 Mar 2008 19:05:30 +0200 Subject: [PATCH] I2C: Fix twl4030 timeouts on omap3430 For some reason doing a twl4030 write-read cycle can hang the I2C bus on omap3430. And doing the write and read separately in twl4030_i2c_read() seems to fix the problem... Not intended for applying, just a temporary workaround. diff --git a/drivers/i2c/chips/twl4030-core.c b/drivers/i2c/chips/twl4030-core.c index ded86e7..62868b0 100644 --- a/drivers/i2c/chips/twl4030-core.c +++ b/drivers/i2c/chips/twl4030-core.c @@ -327,6 +327,7 @@ int twl4030_i2c_read(u8 mod_no, u8 * value, u8 reg, u8 num_bytes) return -EPERM; } mutex_lock(twl-xfer_lock); + /* [MSG1] fill the register address data */ msg = twl-xfer_msg[0]; msg-addr = twl-address; @@ -334,18 +335,25 @@ int twl4030_i2c_read(u8 mod_no, u8 * value, u8 reg, u8 num_bytes) msg-flags = 0; /* Read the register value */ val = twl4030_map[mod_no].base + reg; msg-buf = val; + ret = i2c_transfer(twl-client.adapter, twl-xfer_msg, 1); + if (ret 0) + goto out; + /* [MSG2] fill the data rx buffer */ msg = twl-xfer_msg[1]; msg-addr = twl-address; msg-flags = I2C_M_RD; /* Read the register value */ msg-len = num_bytes; /* only n bytes */ msg-buf = value; - ret = i2c_transfer(twl-client.adapter, twl-xfer_msg, 2); + ret = i2c_transfer(twl-client.adapter, twl-xfer_msg, 1); + +out: mutex_unlock(twl-xfer_lock); /* i2cTransfer returns num messages.translate it pls.. */ if (ret = 0) ret = 0; + return ret; }
[PATCH] I2C: Fix twl4030 timeouts on omap3430
For some reason doing a twl4030 write-read cycle can hang the I2C bus on omap3430. And doing the write and read separately in twl4030_i2c_read() seems to fix the problem... Not intended for applying, just a temporary workaround. diff --git a/drivers/i2c/chips/twl4030-core.c b/drivers/i2c/chips/twl4030-core.c index ded86e7..62868b0 100644 --- a/drivers/i2c/chips/twl4030-core.c +++ b/drivers/i2c/chips/twl4030-core.c @@ -327,6 +327,7 @@ int twl4030_i2c_read(u8 mod_no, u8 * value, u8 reg, u8 num_bytes) return -EPERM; } mutex_lock(twl-xfer_lock); + /* [MSG1] fill the register address data */ msg = twl-xfer_msg[0]; msg-addr = twl-address; @@ -334,18 +335,25 @@ int twl4030_i2c_read(u8 mod_no, u8 * value, u8 reg, u8 num_bytes) msg-flags = 0; /* Read the register value */ val = twl4030_map[mod_no].base + reg; msg-buf = val; + ret = i2c_transfer(twl-client.adapter, twl-xfer_msg, 1); + if (ret 0) + goto out; + /* [MSG2] fill the data rx buffer */ msg = twl-xfer_msg[1]; msg-addr = twl-address; msg-flags = I2C_M_RD; /* Read the register value */ msg-len = num_bytes; /* only n bytes */ msg-buf = value; - ret = i2c_transfer(twl-client.adapter, twl-xfer_msg, 2); + ret = i2c_transfer(twl-client.adapter, twl-xfer_msg, 1); + +out: mutex_unlock(twl-xfer_lock); /* i2cTransfer returns num messages.translate it pls.. */ if (ret = 0) ret = 0; + return ret; } -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] I2C: Fix twl4030 timeouts on omap3430
ARM: OMAP: Use posted mode for dmtimer This patch adds the use of write posting for the timer. Previously, every write could lock the requestor for almost 3x32KHz cycles. This patch only synchronizes before writes and reads instead of after them and it does it on per register basis. Doing it this way there is some chance to hide some of the sync latency. It also removes some needless reads when non-posted mode is there. With out this fix the read/writes take almost 2% CPU load @500MHz just waiting on tick timer registers. Also define new 34xx only registers. Signed-off-by: Richard Woodruff [EMAIL PROTECTED] Signed-off-by: Tony Lindgren [EMAIL PROTECTED] --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -38,34 +38,113 @@ #include asm/arch/irqs.h /* register offsets */ -#define OMAP_TIMER_ID_REG 0x00 -#define OMAP_TIMER_OCP_CFG_REG 0x10 -#define OMAP_TIMER_SYS_STAT_REG0x14 -#define OMAP_TIMER_STAT_REG0x18 -#define OMAP_TIMER_INT_EN_REG 0x1c -#define OMAP_TIMER_WAKEUP_EN_REG 0x20 -#define OMAP_TIMER_CTRL_REG0x24 -#define OMAP_TIMER_COUNTER_REG 0x28 -#define OMAP_TIMER_LOAD_REG0x2c -#define OMAP_TIMER_TRIGGER_REG 0x30 -#define OMAP_TIMER_WRITE_PEND_REG 0x34 -#define OMAP_TIMER_MATCH_REG 0x38 -#define OMAP_TIMER_CAPTURE_REG 0x3c -#define OMAP_TIMER_IF_CTRL_REG 0x40 - -/* timer control reg bits */ -#define OMAP_TIMER_CTRL_GPOCFG (1 14) -#define OMAP_TIMER_CTRL_CAPTMODE (1 13) -#define OMAP_TIMER_CTRL_PT (1 12) -#define OMAP_TIMER_CTRL_TCM_LOWTOHIGH (0x1 8) -#define OMAP_TIMER_CTRL_TCM_HIGHTOLOW (0x2 8) -#define OMAP_TIMER_CTRL_TCM_BOTHEDGES (0x3 8) -#define OMAP_TIMER_CTRL_SCPWM (1 7) -#define OMAP_TIMER_CTRL_CE (1 6)/* compare enable */ -#define OMAP_TIMER_CTRL_PRE(1 5)/* prescaler enable */ -#define OMAP_TIMER_CTRL_PTV_SHIFT 2 /* how much to shift the prescaler value */ -#define OMAP_TIMER_CTRL_AR (1 1)/* auto-reload enable */ -#define OMAP_TIMER_CTRL_ST (1 0)/* start timer */ +#define _OMAP_TIMER_ID_OFFSET 0x00 +#define _OMAP_TIMER_OCP_CFG_OFFSET 0x10 +#define _OMAP_TIMER_SYS_STAT_OFFSET0x14 +#define _OMAP_TIMER_STAT_OFFSET0x18 +#define _OMAP_TIMER_INT_EN_OFFSET 0x1c +#define _OMAP_TIMER_WAKEUP_EN_OFFSET 0x20 +#define _OMAP_TIMER_CTRL_OFFSET0x24 +#defineOMAP_TIMER_CTRL_GPOCFG (1 14) +#defineOMAP_TIMER_CTRL_CAPTMODE(1 13) +#defineOMAP_TIMER_CTRL_PT (1 12) +#defineOMAP_TIMER_CTRL_TCM_LOWTOHIGH (0x1 8) +#defineOMAP_TIMER_CTRL_TCM_HIGHTOLOW (0x2 8) +#defineOMAP_TIMER_CTRL_TCM_BOTHEDGES (0x3 8) +#defineOMAP_TIMER_CTRL_SCPWM (1 7) +#defineOMAP_TIMER_CTRL_CE (1 6) /* compare enable */ +#defineOMAP_TIMER_CTRL_PRE (1 5) /* prescaler enable */ +#defineOMAP_TIMER_CTRL_PTV_SHIFT 2 /* prescaler value shift */ +#defineOMAP_TIMER_CTRL_POSTED (1 2) +#defineOMAP_TIMER_CTRL_AR (1 1) /* auto-reload enable */ +#defineOMAP_TIMER_CTRL_ST (1 0) /* start timer */ +#define _OMAP_TIMER_COUNTER_OFFSET 0x28 +#define _OMAP_TIMER_LOAD_OFFSET0x2c +#define _OMAP_TIMER_TRIGGER_OFFSET 0x30 +#define _OMAP_TIMER_WRITE_PEND_OFFSET 0x34 +#defineWP_NONE 0 /* no write pending bit */ +#defineWP_TCLR (1 0) +#defineWP_TCRR (1 1) +#defineWP_TLDR (1 2) +#defineWP_TTGR (1 3) +#defineWP_TMAR (1 4) +#defineWP_TPIR (1 5) +#defineWP_TNIR (1 6) +#defineWP_TCVR (1 7) +#defineWP_TOCR (1 8) +#defineWP_TOWR (1 9) +#define _OMAP_TIMER_MATCH_OFFSET 0x38 +#define _OMAP_TIMER_CAPTURE_OFFSET 0x3c +#define _OMAP_TIMER_IF_CTRL_OFFSET 0x40 +#define _OMAP_TIMER_CAPTURE2_OFFSET0x44/* TCAR2, 34xx only */ +#define _OMAP_TIMER_TICK_POS_OFFSET0x48/* TPIR, 34xx only */ +#define _OMAP_TIMER_TICK_NEG_OFFSET0x4c/* TNIR, 34xx only */ +#define _OMAP_TIMER_TICK_COUNT_OFFSET 0x50/* TCVR, 34xx only */ +#define _OMAP_TIMER_TICK_INT_MASK_SET_OFFSET 0x54/* TOCR, 34xx only */ +#define _OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET 0x58/* TOWR, 34xx only */ + +/* register offsets with the write pending bit encoded */ +#define
Re: [PATCH] I2C: Fix twl4030 timeouts on omap3430
* Tony Lindgren [EMAIL PROTECTED] [080328 13:47]: For some reason doing a twl4030 write-read cycle can hang the I2C bus on omap3430. And doing the write and read separately in twl4030_i2c_read() seems to fix the problem... Not intended for applying, just a temporary workaround. Uh, please ignore this one, git-send-email weirdness where it sends all files ending in .patch.. The series should only contain two patches. Tony diff --git a/drivers/i2c/chips/twl4030-core.c b/drivers/i2c/chips/twl4030-core.c index ded86e7..62868b0 100644 --- a/drivers/i2c/chips/twl4030-core.c +++ b/drivers/i2c/chips/twl4030-core.c @@ -327,6 +327,7 @@ int twl4030_i2c_read(u8 mod_no, u8 * value, u8 reg, u8 num_bytes) return -EPERM; } mutex_lock(twl-xfer_lock); + /* [MSG1] fill the register address data */ msg = twl-xfer_msg[0]; msg-addr = twl-address; @@ -334,18 +335,25 @@ int twl4030_i2c_read(u8 mod_no, u8 * value, u8 reg, u8 num_bytes) msg-flags = 0; /* Read the register value */ val = twl4030_map[mod_no].base + reg; msg-buf = val; + ret = i2c_transfer(twl-client.adapter, twl-xfer_msg, 1); + if (ret 0) + goto out; + /* [MSG2] fill the data rx buffer */ msg = twl-xfer_msg[1]; msg-addr = twl-address; msg-flags = I2C_M_RD; /* Read the register value */ msg-len = num_bytes; /* only n bytes */ msg-buf = value; - ret = i2c_transfer(twl-client.adapter, twl-xfer_msg, 2); + ret = i2c_transfer(twl-client.adapter, twl-xfer_msg, 1); + +out: mutex_unlock(twl-xfer_lock); /* i2cTransfer returns num messages.translate it pls.. */ if (ret = 0) ret = 0; + return ret; } -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] I2C: Fix twl4030 timeouts on omap3430
* Tony Lindgren [EMAIL PROTECTED] [080328 13:47]: ARM: OMAP: Use posted mode for dmtimer This patch adds the use of write posting for the timer. Previously, every write could lock the requestor for almost 3x32KHz cycles. This patch only synchronizes before writes and reads instead of after them and it does it on per register basis. Doing it this way there is some chance to hide some of the sync latency. It also removes some needless reads when non-posted mode is there. With out this fix the read/writes take almost 2% CPU load @500MHz just waiting on tick timer registers. Also define new 34xx only registers. Please ignore this patch too. Tony Signed-off-by: Richard Woodruff [EMAIL PROTECTED] Signed-off-by: Tony Lindgren [EMAIL PROTECTED] --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -38,34 +38,113 @@ #include asm/arch/irqs.h /* register offsets */ -#define OMAP_TIMER_ID_REG0x00 -#define OMAP_TIMER_OCP_CFG_REG 0x10 -#define OMAP_TIMER_SYS_STAT_REG 0x14 -#define OMAP_TIMER_STAT_REG 0x18 -#define OMAP_TIMER_INT_EN_REG0x1c -#define OMAP_TIMER_WAKEUP_EN_REG 0x20 -#define OMAP_TIMER_CTRL_REG 0x24 -#define OMAP_TIMER_COUNTER_REG 0x28 -#define OMAP_TIMER_LOAD_REG 0x2c -#define OMAP_TIMER_TRIGGER_REG 0x30 -#define OMAP_TIMER_WRITE_PEND_REG0x34 -#define OMAP_TIMER_MATCH_REG 0x38 -#define OMAP_TIMER_CAPTURE_REG 0x3c -#define OMAP_TIMER_IF_CTRL_REG 0x40 - -/* timer control reg bits */ -#define OMAP_TIMER_CTRL_GPOCFG (1 14) -#define OMAP_TIMER_CTRL_CAPTMODE (1 13) -#define OMAP_TIMER_CTRL_PT (1 12) -#define OMAP_TIMER_CTRL_TCM_LOWTOHIGH(0x1 8) -#define OMAP_TIMER_CTRL_TCM_HIGHTOLOW(0x2 8) -#define OMAP_TIMER_CTRL_TCM_BOTHEDGES(0x3 8) -#define OMAP_TIMER_CTRL_SCPWM(1 7) -#define OMAP_TIMER_CTRL_CE (1 6)/* compare enable */ -#define OMAP_TIMER_CTRL_PRE (1 5)/* prescaler enable */ -#define OMAP_TIMER_CTRL_PTV_SHIFT2 /* how much to shift the prescaler value */ -#define OMAP_TIMER_CTRL_AR (1 1)/* auto-reload enable */ -#define OMAP_TIMER_CTRL_ST (1 0)/* start timer */ +#define _OMAP_TIMER_ID_OFFSET0x00 +#define _OMAP_TIMER_OCP_CFG_OFFSET 0x10 +#define _OMAP_TIMER_SYS_STAT_OFFSET 0x14 +#define _OMAP_TIMER_STAT_OFFSET 0x18 +#define _OMAP_TIMER_INT_EN_OFFSET0x1c +#define _OMAP_TIMER_WAKEUP_EN_OFFSET 0x20 +#define _OMAP_TIMER_CTRL_OFFSET 0x24 +#define OMAP_TIMER_CTRL_GPOCFG (1 14) +#define OMAP_TIMER_CTRL_CAPTMODE(1 13) +#define OMAP_TIMER_CTRL_PT (1 12) +#define OMAP_TIMER_CTRL_TCM_LOWTOHIGH (0x1 8) +#define OMAP_TIMER_CTRL_TCM_HIGHTOLOW (0x2 8) +#define OMAP_TIMER_CTRL_TCM_BOTHEDGES (0x3 8) +#define OMAP_TIMER_CTRL_SCPWM (1 7) +#define OMAP_TIMER_CTRL_CE (1 6) /* compare enable */ +#define OMAP_TIMER_CTRL_PRE (1 5) /* prescaler enable */ +#define OMAP_TIMER_CTRL_PTV_SHIFT 2 /* prescaler value shift */ +#define OMAP_TIMER_CTRL_POSTED (1 2) +#define OMAP_TIMER_CTRL_AR (1 1) /* auto-reload enable */ +#define OMAP_TIMER_CTRL_ST (1 0) /* start timer */ +#define _OMAP_TIMER_COUNTER_OFFSET 0x28 +#define _OMAP_TIMER_LOAD_OFFSET 0x2c +#define _OMAP_TIMER_TRIGGER_OFFSET 0x30 +#define _OMAP_TIMER_WRITE_PEND_OFFSET0x34 +#define WP_NONE 0 /* no write pending bit */ +#define WP_TCLR (1 0) +#define WP_TCRR (1 1) +#define WP_TLDR (1 2) +#define WP_TTGR (1 3) +#define WP_TMAR (1 4) +#define WP_TPIR (1 5) +#define WP_TNIR (1 6) +#define WP_TCVR (1 7) +#define WP_TOCR (1 8) +#define WP_TOWR (1 9) +#define _OMAP_TIMER_MATCH_OFFSET 0x38 +#define _OMAP_TIMER_CAPTURE_OFFSET 0x3c +#define _OMAP_TIMER_IF_CTRL_OFFSET 0x40 +#define _OMAP_TIMER_CAPTURE2_OFFSET 0x44/* TCAR2, 34xx only */ +#define _OMAP_TIMER_TICK_POS_OFFSET 0x48/* TPIR, 34xx only */ +#define _OMAP_TIMER_TICK_NEG_OFFSET 0x4c/* TNIR, 34xx only */ +#define _OMAP_TIMER_TICK_COUNT_OFFSET0x50/* TCVR, 34xx only */ +#define _OMAP_TIMER_TICK_INT_MASK_SET_OFFSET 0x54/* TOCR,