diff options
author | Katsunaga Kinoshita <katsu@katsu-ubuntu.(none)> | 2012-06-15 17:27:13 +0900 |
---|---|---|
committer | Justin Waters <justin.waters@timesys.com> | 2012-07-03 17:15:15 -0400 |
commit | 44a2c68ff012eabdc6131a51b0942e981fe96d55 (patch) | |
tree | 25891e4206f829d48f5ac6970c6447ff37550011 | |
parent | 369d4be392f5a86a2a2130d72b60bab8e9c27cb9 (diff) |
fix: Ether driver
-rw-r--r-- | arch/arm/mach-mvf/board-twr_vf600.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-mvf/clock.c | 83 | ||||
-rw-r--r-- | arch/arm/mach-mvf/mvf_fec.c | 9 | ||||
-rwxr-xr-x | arch/arm/plat-mxc/include/mach/iomux-vmvf.h | 11 | ||||
-rw-r--r-- | arch/arm/plat-mxc/mvf_time.c | 35 | ||||
-rwxr-xr-x | drivers/net/fec.c | 28 | ||||
-rw-r--r-- | drivers/tty/serial/serial_mvf.c | 2 | ||||
-rw-r--r-- | include/linux/micrel_phy.h | 2 | ||||
-rw-r--r-- | init/main.c | 6 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 1 |
10 files changed, 126 insertions, 55 deletions
diff --git a/arch/arm/mach-mvf/board-twr_vf600.h b/arch/arm/mach-mvf/board-twr_vf600.h index 0ce5dc797246..74f934d4cd66 100644 --- a/arch/arm/mach-mvf/board-twr_vf600.h +++ b/arch/arm/mach-mvf/board-twr_vf600.h @@ -131,7 +131,7 @@ static iomux_vmvf_cfg_t twr_vf6xx_pads[] = { VF6XX_PAD_PAD_105__TCON0_TCON1, VF6XX_PAD_PAD_106__TCON0_TCON2, VF6XX_PAD_PAD_107__TCON0_DATA_OUT1, - VF6XX_PAD_PAD_108__RGPIOC_GPIO108, +// KATSU VF6XX_PAD_PAD_108__RGPIOC_GPIO108, VF6XX_PAD_PAD_109__TCON0_TCON3, VF6XX_PAD_PAD_110__TCON0_DATA_OUT18, VF6XX_PAD_PAD_111__TCON0_DATA_OUT19, @@ -269,7 +269,7 @@ static iomux_vmvf_cfg_t twr_vf6xx_pads[] = { VF6XX_PAD_PAD_105__TCON0_TCON1, VF6XX_PAD_PAD_106__TCON0_TCON2, VF6XX_PAD_PAD_107__TCON0_DATA_OUT1, - VF6XX_PAD_PAD_108__RGPIOC_GPIO108, +// KATSU VF6XX_PAD_PAD_108__RGPIOC_GPIO108, VF6XX_PAD_PAD_109__TCON0_TCON3, VF6XX_PAD_PAD_110__TCON0_DATA_OUT18, VF6XX_PAD_PAD_111__TCON0_DATA_OUT19, diff --git a/arch/arm/mach-mvf/clock.c b/arch/arm/mach-mvf/clock.c index 35bebc83326a..cf5e4a2cc88a 100644 --- a/arch/arm/mach-mvf/clock.c +++ b/arch/arm/mach-mvf/clock.c @@ -110,8 +110,7 @@ static int cpu_op_nr; static unsigned long internal_high_reference, internal_low_reference; static unsigned long external_high_reference, external_low_reference; static unsigned long anaclk_1_reference, audio_ext_clk_reference; -static unsigned long enet_ext_clk_reference, enet_ts_clk_reference; -static unsigned long usb_clk_reference; +static unsigned long enet_ts_clk_reference, usb_clk_reference; /* For MX 6DL/S, Video PLL may be used by synchronous display devices, * such as HDMI or LVDS, and also by the EPDC. If EPDC is in use, @@ -336,13 +335,7 @@ static int _clk_audio_ext_set_rate(struct clk *clk, unsigned long rate) static unsigned long _clk_enet_ext_get_rate(struct clk *clk) { - return enet_ext_clk_reference; -} - -static int _clk_enet_ext_set_rate(struct clk *clk, unsigned long rate) -{ - enet_ext_clk_reference = rate; - return 0; + return 50000000; } static unsigned long _clk_enet_ts_get_rate(struct clk *clk) @@ -400,7 +393,6 @@ static struct clk audio_ext = { static struct clk enet_ext = { __INIT_CLK_DEBUG(enet_ext) .get_rate = _clk_enet_ext_get_rate, - .set_rate = _clk_enet_ext_set_rate, }; static struct clk enet_ts = { @@ -1292,7 +1284,6 @@ static int _clk_enet_enable(struct clk *clk) reg |= ANADIG_PLL_ENABLE; __raw_writel(reg, PLL5_ENET_BASE_ADDR); - _clk_enable(clk); return 0; } @@ -1300,8 +1291,6 @@ static void _clk_enet_disable(struct clk *clk) { unsigned int reg; - _clk_disable(clk); - /* Enable ENET ref clock */ reg = __raw_readl(PLL5_ENET_BASE_ADDR); reg |= ANADIG_PLL_BYPASS; @@ -1366,8 +1355,6 @@ static struct clk enet_clk = { __INIT_CLK_DEBUG(enet_clk) .id = 0, .parent = &pll5_enet_main_clk, - .enable_reg = MXC_CCM_CCGR1, - .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET, .enable = _clk_enet_enable, .disable = _clk_enet_disable, #if 0 //we do not support enet freq @@ -2309,10 +2296,11 @@ static int _clk_enet_rmii_set_parent(struct clk *clk, struct clk *parent) static struct clk enet_rmii_clk = { __INIT_CLK_DEBUG(enet_rmii_clk) - .parent = &enet_ext, + .parent = &enet_clk, + //.parent = &enet_div2_clk, .enable = _clk_enet_rmii_enable, .disable = _clk_enet_rmii_disable, -#if 0 //we do not support to change enet freq +#if 1 //FIXME 0 //we do not support to change enet freq .set_parent = _clk_enet_rmii_set_parent, #endif }; @@ -2374,6 +2362,30 @@ static struct clk enet_ts_clk = { #endif }; +static struct clk fec0_clk = { + __INIT_CLK_DEBUG(fec0_rmii_clk) + .parent = &enet_rmii_clk, + .enable = _clk_enable, + .disable = _clk_disable, + .enable_reg = MXC_CCM_CCGR9, + .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET, +#ifdef CONFIG_FEC_1588 + .secondary = &enet_ts_clk, +#endif +}; + +static struct clk fec1_clk = { + __INIT_CLK_DEBUG(fec1_rmii_clk) + .parent = &enet_rmii_clk, + .enable = _clk_enable, + .disable = _clk_disable, + .enable_reg = MXC_CCM_CCGR9, + .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET, +#ifdef CONFIG_FEC_1588 + .secondary = &enet_ts_clk, +#endif +}; + static int _clk_sdhc0_enable(struct clk *clk) { u32 reg; @@ -3775,14 +3787,12 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK(NULL, "ftm3_clk", ftm3_clk), _REGISTER_CLOCK(NULL, "nfc_clk_root", nfc_clk_root), _REGISTER_CLOCK(NULL, "nfc_clk", nfc_clk[0]), -#if 1 - _REGISTER_CLOCK(NULL, "fec_clk", enet_clk), //FIXME -#else - _REGISTER_CLOCK("fec.0", NULL, enet_clk), //FIXME -#endif + _REGISTER_CLOCK(NULL, "enet_clk", enet_clk), _REGISTER_CLOCK(NULL, "enet_div2_clk", enet_div2_clk), _REGISTER_CLOCK(NULL, "enet_rmii_clk", enet_rmii_clk), _REGISTER_CLOCK(NULL, "enet_ts_clk", enet_ts_clk), + _REGISTER_CLOCK(NULL, "fec_clk", fec0_clk), + _REGISTER_CLOCK(NULL, "fec1_clk", fec1_clk), _REGISTER_CLOCK(NULL, "sdhc0_clk", sdhc0_clk), _REGISTER_CLOCK(NULL, "sdhc1_clk", sdhc1_clk), _REGISTER_CLOCK(NULL, "dcu0_clk_root", dcu0_clk_root), @@ -4018,6 +4028,27 @@ int __init mvf_clocks_init(unsigned long sirc, unsigned long firc, clk_enable(&ips_bus_clk); clk_enable(&ddrc_clk); +#if 1 //DEBUG + if (1) { + struct clk *old_parent = clk_get_parent(&enet_rmii_clk); +#if 0 + if (old_parent != &enet_clk) { + clk_set_parent(&enet_rmii_clk, &enet_clk); + printk("*** rmii_clk:%ldHz -> %ldHz\n", + clk_get_rate(old_parent), clk_get_rate(&fec0_clk)); +#else + if (old_parent != &enet_ext) { + clk_set_parent(&enet_rmii_clk, &enet_ext); + printk("*** rmii_clk:%ldHz -> %ldHz\n", + clk_get_rate(old_parent), clk_get_rate(&fec0_clk)); +#endif + } else { + printk("*** rmii_clk:%ldHz\n", clk_get_rate(&enet_rmii_clk)); + } + printk("*** fec0_clk:%ldHz\n", clk_get_rate(&fec0_clk)); + } +#endif + /* Disable un-necessary PFDs & PLLs */ if (pll2_pfd1.usecount == 0) pll2_pfd1.disable(&pll2_pfd1); @@ -4028,14 +4059,6 @@ int __init mvf_clocks_init(unsigned long sirc, unsigned long firc, if (pll2_pfd4.usecount == 0) pll2_pfd4.disable(&pll2_pfd4); -#if !defined(CONFIG_FEC_1588) - pll3_pfd1.disable(&pll3_pfd1); - pll3_pfd2.disable(&pll3_pfd2); - pll3_pfd3.disable(&pll3_pfd3); - pll3_pfd4.disable(&pll3_pfd4); - - pll3_480_usb1_main_clk.disable(&pll3_480_usb1_main_clk); -#endif pll4_audio_main_clk.disable(&pll4_audio_main_clk); pll6_video_main_clk.disable(&pll6_video_main_clk); pll_480_usb2_main_clk.disable(&pll_480_usb2_main_clk); diff --git a/arch/arm/mach-mvf/mvf_fec.c b/arch/arm/mach-mvf/mvf_fec.c index 009dbc168a96..ef42c9d69628 100644 --- a/arch/arm/mach-mvf/mvf_fec.c +++ b/arch/arm/mach-mvf/mvf_fec.c @@ -32,7 +32,7 @@ static int fec_get_mac_addr(unsigned char *mac) { unsigned int value; - +#if 0 #if 1 value = 0x01; #endif @@ -44,6 +44,13 @@ static int fec_get_mac_addr(unsigned char *mac) //value = readl(MVF_IO_ADDRESS(MVF_OTP_CTRL_BASE_ADDR) + HW_OCOTP_MACn(1)); mac[1] = value & 0xff; mac[0] = (value >> 8) & 0xff; +#endif + mac[5]=0x00; + mac[4]=0x21; + mac[3]=0x97; + mac[2]=0x09; + mac[1]=0xc6; + mac[0]=0xae; return 0; } diff --git a/arch/arm/plat-mxc/include/mach/iomux-vmvf.h b/arch/arm/plat-mxc/include/mach/iomux-vmvf.h index 7bf3bbf6250e..beb7b85c735a 100755 --- a/arch/arm/plat-mxc/include/mach/iomux-vmvf.h +++ b/arch/arm/plat-mxc/include/mach/iomux-vmvf.h @@ -117,13 +117,24 @@ typedef u64 iomux_vmvf_cfg_t; #define MUX_CTL_PAD_DSE_25ohm (6 << 6) #define MUX_CTL_PAD_DSE_20ohm (7 << 6) /* 34 Ohm if pad is DDR */ +#if 0 #define MUX_CTL_PAD_PUS_100K_DOWN (0 << 4 | MUX_CTL_PAD_PUE) #define MUX_CTL_PAD_PUS_47K_UP (1 << 4 | MUX_CTL_PAD_PUE) #define MUX_CTL_PAD_PUS_100K_UP (2 << 4 | MUX_CTL_PAD_PUE) #define MUX_CTL_PAD_PUS_22K_UP (3 << 4 | MUX_CTL_PAD_PUE) +#else +#define MUX_CTL_PAD_PUS_100K_DOWN (0 << 4) +#define MUX_CTL_PAD_PUS_47K_UP (1 << 4) +#define MUX_CTL_PAD_PUS_100K_UP (2 << 4) +#define MUX_CTL_PAD_PUS_22K_UP (3 << 4) +#endif #define MUX_CTL_PAD_PKE (1 << 3) +#if 0 #define MUX_CTL_PAD_PUE (1 << 2 | MUX_CTL_PAD_PKE) +#else +#define MUX_CTL_PAD_PUE (1 << 2) +#endif #define MUX_CTL_PAD_OBE (1 << 1) #define MUX_CTL_PAD_IBE (1 << 0) diff --git a/arch/arm/plat-mxc/mvf_time.c b/arch/arm/plat-mxc/mvf_time.c index 597f96cd6f02..039e45e8864c 100644 --- a/arch/arm/plat-mxc/mvf_time.c +++ b/arch/arm/plat-mxc/mvf_time.c @@ -124,6 +124,8 @@ static void mvf_set_mode(enum clock_event_mode mode, * The timer interrupt generation is disabled at least * for enough time to call mvf_set_next_event() */ + /* DEBUG */ printk("DBG: %s[%d]: Start Mode = %x, jiffies = %ld\n",__func__,__LINE__, mode,jiffies); + local_irq_save(flags); /* Disable interrupt in GPT module */ @@ -166,6 +168,7 @@ static void mvf_set_mode(enum clock_event_mode mode, /* Left event sources disabled, no more interrupts appear */ break; } + /* DEBUG */ printk("DBG: %s[%d]: Start jiffies = %ld\n",__func__,__LINE__, jiffies); } /* @@ -181,16 +184,18 @@ static irqreturn_t mvf_timer_interrupt(int irq, void *dev_id) __raw_writel(tstat, timer_base + PIT_TFLG(TIMER_CH)); gpt_irq_acknowledge(); evt->event_handler(evt); + jiffies++; return IRQ_HANDLED; } + // /* DEBUG */ printk("DBG: %s[%d]: NONE Exit\n",__func__,__LINE__); return IRQ_NONE; } static int mvf_set_next_event(unsigned long evt, struct clock_event_device *unused) { - unsigned long tcmp,tmp; - +#if 1 + unsigned long tcmp; tcmp = evt; /* STOP Time */ __raw_writel(__raw_readl(timer_base + PIT_TCTRL(TIMER_CH)) @@ -201,12 +206,26 @@ static int mvf_set_next_event(unsigned long evt, __raw_writel(__raw_readl(timer_base + PIT_TCTRL(TIMER_CH)) | (PIT_TCTRL_TEN), timer_base + PIT_TCTRL(TIMER_CH)); -#if 0 - while(1) { - tmp = __raw_readl(timer_base + PIT_CVAL(TIMER_CH)); - printk("val = %08lx\n",tmp); - } +#else + unsigned long tcmp,cval; + unsigned long oval,nval; + tcmp = evt; + cval = __raw_readl(timer_base + PIT_CVAL(TIMER_CH)); + oval = __raw_readl(timer_base + PIT_LDVAL(TIMER_CH)); + /* STOP Time */ + __raw_writel(__raw_readl(timer_base + PIT_TCTRL(TIMER_CH)) + & ~(PIT_TCTRL_TEN), + timer_base + PIT_TCTRL(TIMER_CH)); + __raw_writel(tcmp, timer_base + PIT_LDVAL(TIMER_CH)); + /* Start Timer */ + __raw_writel(__raw_readl(timer_base + PIT_TCTRL(TIMER_CH)) + | (PIT_TCTRL_TEN), + timer_base + PIT_TCTRL(TIMER_CH)); + __raw_writel(tcmp+cval, timer_base + PIT_LDVAL(TIMER_CH)); + nval = __raw_readl(timer_base + PIT_LDVAL(TIMER_CH)); + tcmp = __raw_readl(timer_base + PIT_CVAL(TIMER_CH)); + // printk("DEBUG: KATSU: evt=%lud, oldval = %lud, nval = %lud,cval = %lud,tcmp = %lud\n",evt,oval,nval,cval,tcmp); #endif return 0; @@ -250,8 +269,6 @@ static int __init mvf_clockevent_init(struct clk *timer_clk) void __init mvf_timer_init(struct clk *timer_clk, void __iomem *base, int irq) { - uint32_t tctrl_val; - u32 reg; #if 1 /* Clock is fix to 50MHz */ clk_enable(timer_clk); diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 750fca841890..26f579dd803e 100755 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -71,7 +71,7 @@ #define FEC_QUIRK_SWAP_FRAME (1 << 1) static struct platform_device_id fec_devtype[] = { -#ifdef CONFIG_SOC_IMX6Q +#if defined(CONFIG_SOC_IMX6Q) || defined(CONFIG_SOC_VF6XX) { .name = DRIVER_NAME, .driver_data = FEC_QUIRK_ENET_MAC, @@ -149,7 +149,7 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address"); #define FEC_ENET_HOLD_TIME ((uint)0x100) /* 2 internal clock cycle*/ #if defined(CONFIG_FEC_1588) && (defined(CONFIG_ARCH_MX28) || \ - defined(CONFIG_ARCH_MX6)) + defined(CONFIG_ARCH_MX6)) || defined(CONFIG_SOC_VF6XX) #define FEC_DEFAULT_IMASK (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII | \ FEC_ENET_TS_AVAIL | FEC_ENET_TS_TIMER) #else @@ -280,7 +280,6 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) /* Link is down or autonegotiation is in progress. */ return NETDEV_TX_BUSY; } - spin_lock_irqsave(&fep->hw_lock, flags); /* Fill in a Tx ring entry */ bdp = fep->cur_tx; @@ -370,7 +369,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) fep->cur_tx = bdp; spin_unlock_irqrestore(&fep->hw_lock, flags); - + return NETDEV_TX_OK; } @@ -617,6 +616,7 @@ fec_enet_interrupt(int irq, void *dev_id) do { int_events = readl(fep->hwp + FEC_IEVENT); writel(int_events, fep->hwp + FEC_IEVENT); +/* KATASU */ //if( int_events && (int_events !=0x800000)) printk("DBG: %s[%x]:Irq\n",__func__,int_events); if (int_events & FEC_ENET_RXF) { ret = IRQ_HANDLED; @@ -902,11 +902,15 @@ static int fec_enet_mii_init(struct platform_device *pdev) /* * Set MII speed to 2.5 MHz (= clk_get_rate() / 2 * phy_speed) */ +#if defined(CONFIG_SOC_VF6XX) + fep->phy_speed = 0x09<<1; +#else fep->phy_speed = DIV_ROUND_UP(clk_get_rate(fep->clk), (FEC_ENET_MII_CLK << 2)) << 1; +#endif /* set hold time to 2 internal clock cycle */ - if (cpu_is_mx6()) + if (cpu_is_mx6() || cpu_is_vf6xx()) fep->phy_speed |= FEC_ENET_HOLD_TIME; writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); @@ -1427,7 +1431,7 @@ fec_restart(struct net_device *dev, int duplex) fep->ptimer_present = 0; reg = 0x0; } else -#if defined(CONFIG_SOC_IMX28) || defined(CONFIG_ARCH_MX6) || defined(CONFIG_ARCH_VF600) +#if defined(CONFIG_SOC_IMX28) || defined(CONFIG_ARCH_MX6) || defined(CONFIG_SOC_VF6XX) reg = 0x00000010; #else reg = 0x0; @@ -1457,7 +1461,7 @@ fec_restart(struct net_device *dev, int duplex) /* ENET enable */ val = reg | (0x1 << 1); -#ifndef CONFIG_ARCH_VF600 +#ifndef CONFIG_SOC_VF6XX /* if phy work at 1G mode, set ENET RGMII speed to 1G */ if (fep->phy_dev && (fep->phy_dev->supported & (SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full)) && @@ -1465,7 +1469,7 @@ fec_restart(struct net_device *dev, int duplex) fep->phy_dev->speed == SPEED_1000) val |= (0x1 << 5); #endif - if (cpu_is_mx6()) { + if (cpu_is_mx6()||cpu_is_vf6xx()) { /* enable endian swap */ val |= (0x1 << 8); /* enable ENET store and forward mode */ @@ -1496,7 +1500,7 @@ fec_stop(struct net_device *dev) writel(1, fep->hwp + FEC_ECNTRL); udelay(10); - if (cpu_is_mx6()) + if (cpu_is_mx6()||cpu_is_vf6xx()) /* FIXME: we have to enable enet to keep mii interrupt works. */ writel(2, fep->hwp + FEC_ECNTRL); @@ -1537,7 +1541,6 @@ fec_probe(struct platform_device *pdev) fep->hwp = ioremap(r->start, resource_size(r)); fep->pdev = pdev; - if (!fep->hwp) { ret = -ENOMEM; goto failed_ioremap; @@ -1546,9 +1549,12 @@ fec_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ndev); pdata = pdev->dev.platform_data; +#if defined(CONFIG_SOC_VF6XX) + fep->phy_interface=PHY_INTERFACE_MODE_RMII; +#else if (pdata) fep->phy_interface = pdata->phy; - +#endif /* This device has up to three irqs on some platforms */ for (i = 0; i < 3; i++) { irq = platform_get_irq(pdev, i); diff --git a/drivers/tty/serial/serial_mvf.c b/drivers/tty/serial/serial_mvf.c index ebf7819e8bf1..ffcabc9fb51c 100644 --- a/drivers/tty/serial/serial_mvf.c +++ b/drivers/tty/serial/serial_mvf.c @@ -50,7 +50,7 @@ #define SERIAL_MVF_MAJOR 207 #define MINOR_START 16 #define DRIVER_NAME "MVF-uart" -#define DEV_NAME "ttymvf" +#define DEV_NAME "ttyvmvf" #define UART_NR 6 diff --git a/include/linux/micrel_phy.h b/include/linux/micrel_phy.h index b073c57534b3..b62e9b614030 100644 --- a/include/linux/micrel_phy.h +++ b/include/linux/micrel_phy.h @@ -6,7 +6,7 @@ #define PHY_ID_KSZ9021 0x00221611 #define PHY_ID_KS8737 0x00221720 #define PHY_ID_KS8041 0x00221510 -#define PHY_ID_KSZ8041 0x00221512 +#define PHY_ID_KSZ8041 0x00221513 #define PHY_ID_KS8051 0x00221550 /* both for ks8001 Rev. A/B, and for ks8721 Rev 3. */ #define PHY_ID_KS8001 0x0022161A diff --git a/init/main.c b/init/main.c index d7211faed2ad..4ef68c64c66f 100644 --- a/init/main.c +++ b/init/main.c @@ -371,6 +371,12 @@ static noinline void __init_refok rest_init(void) schedule(); preempt_disable(); +#if 0 + while(1) { + /* DEBUG Katsu */ printk("DBG: %s[%d]:****** %ld ***********\n",__func__,__LINE__, jiffies ); + mdelay(1000); + } +#endif /* Call into cpu_idle with preempt disabled */ cpu_idle(); } diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index d5097c44b407..d44ae10642e8 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -52,6 +52,7 @@ static void tick_do_update_jiffies64(ktime_t now) * Do a quick check without holding xtime_lock: */ delta = ktime_sub(now, last_jiffies_update); + // /* DEBUG */ printk("delta.vt64 = %lld, tick_period.vt64 = %lld\n",delta.tv64 ,tick_period.tv64); if (delta.tv64 < tick_period.tv64) return; |