int interrupt_init(void) { int ret; /* call cpu specific function from $(CPU)/interrupts.c */ ret = interrupt_init_cpu(&decrementer_count); if (ret) return ret; decrementer_count = get_tbclk() / CFG_HZ; debug("interrupt init: tbclk() = %d MHz, decrementer_count = %d\n", (get_tbclk() / 1000000), decrementer_count); set_dec(decrementer_count); set_msr(get_msr() | MSR_EE); debug("MSR = 0x%08lx, Decrementer reg = 0x%08lx\n", get_msr(), get_dec()); return 0; }
/* * This function is intended for SHORT delays only. * It will overflow at around 10 seconds @ 400MHz, * or 20 seconds @ 200MHz. */ unsigned long usec2ticks(unsigned long usec) { ulong ticks; if (usec < 1000) { ticks = ((usec * (get_tbclk()/1000)) + 500) / 1000; } else { ticks = ((usec / 10) * (get_tbclk() / 100000)); } return (ticks); }
int interrupt_init_cpu(unsigned long *decrementer_count) { volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; volatile ccsr_pic_t *pic = &immr->im_pic; #ifdef CONFIG_POST /* * The POST word is stored in the PIC's TFRR register which gets * cleared when the PIC is reset. Save it off so we can restore it * later. */ ulong post_word = post_word_load(); #endif pic->gcr = MPC86xx_PICGCR_RST; while (pic->gcr & MPC86xx_PICGCR_RST) ; pic->gcr = MPC86xx_PICGCR_MODE; *decrementer_count = get_tbclk() / CONFIG_SYS_HZ; debug("interrupt init: tbclk() = %ld MHz, decrementer_count = %ld\n", (get_tbclk() / 1000000), *decrementer_count); #ifdef CONFIG_INTERRUPTS pic->iivpr1 = 0x810001; /* 50220 enable mcm interrupts */ debug("iivpr1@%p = %x\n", &pic->iivpr1, pic->iivpr1); pic->iivpr2 = 0x810002; /* 50240 enable ddr interrupts */ debug("iivpr2@%p = %x\n", &pic->iivpr2, pic->iivpr2); pic->iivpr3 = 0x810003; /* 50260 enable lbc interrupts */ debug("iivpr3@%p = %x\n", &pic->iivpr3, pic->iivpr3); #if defined(CONFIG_PCI1) || defined(CONFIG_PCIE1) pic->iivpr8 = 0x810008; /* enable pcie1 interrupts */ debug("iivpr8@%p = %x\n", &pic->iivpr8, pic->iivpr8); #endif #if defined(CONFIG_PCI2) || defined(CONFIG_PCIE2) pic->iivpr9 = 0x810009; /* enable pcie2 interrupts */ debug("iivpr9@%p = %x\n", &pic->iivpr9, pic->iivpr9); #endif pic->ctpr = 0; /* 40080 clear current task priority register */ #endif #ifdef CONFIG_POST post_word_store(post_word); #endif return 0; }
static unsigned long long usec_to_tick(unsigned long usec) { uint64_t tick = usec; tick *= get_tbclk(); do_div(tick, 1000000); return tick; }
static inline unsigned long long usec_to_tick(unsigned long long usec) { usec *= get_tbclk(); do_div(usec, 1000000); return usec; }
static inline unsigned long long tick_to_time(unsigned long long tick) { tick *= CONFIG_SYS_HZ; do_div(tick, get_tbclk()); return tick; }
static unsigned long long notrace tick_to_time(uint64_t tick) { unsigned int div = get_tbclk(); tick *= CONFIG_SYS_HZ; do_div(tick, div); return tick; }
/* Returns time in milliseconds */ static uint64_t notrace tick_to_time(uint64_t tick) { ulong div = get_tbclk(); tick *= CONFIG_SYS_HZ; do_div(tick, div); return tick; }
static int pic32_eth_send(struct udevice *dev, void *packet, int length) { struct pic32eth_dev *priv = dev_get_priv(dev); struct pic32_ectl_regs *ectl_p = priv->ectl_regs; struct eth_dma_desc *txd; u64 deadline; txd = &priv->txd_ring[0]; /* set proper flags & length in descriptor header */ txd->hdr = EDH_SOP | EDH_EOP | EDH_EOWN | EDH_BCOUNT(length); /* pass buffer address to hardware */ txd->data_buff = virt_to_phys(packet); debug("%s: %d / .hdr %x, .data_buff %x, .stat %x, .nexted %x\n", __func__, __LINE__, txd->hdr, txd->data_buff, txd->stat2, txd->next_ed); /* cache flush (packet) */ flush_dcache_range((ulong)packet, (ulong)packet + length); /* cache flush (txd) */ flush_dcache_range((ulong)txd, (ulong)txd + sizeof(*txd)); /* pass descriptor table base to h/w */ writel(virt_to_phys(txd), &ectl_p->txst.raw); /* ready to send enabled, hardware can now send the packet(s) */ writel(ETHCON_TXRTS | ETHCON_ON, &ectl_p->con1.set); /* wait until tx has completed and h/w has released ownership * of the tx descriptor or timeout elapsed. */ deadline = get_ticks() + get_tbclk(); for (;;) { /* check timeout */ if (get_ticks() > deadline) return -ETIMEDOUT; if (ctrlc()) return -EINTR; /* tx completed ? */ if (readl(&ectl_p->con1.raw) & ETHCON_TXRTS) { udelay(1); continue; } /* h/w not released ownership yet? */ invalidate_dcache_range((ulong)txd, (ulong)txd + sizeof(*txd)); if (!(txd->hdr & EDH_EOWN)) break; } return 0; }
void interrupt_init_cpu(unsigned *decrementer_count) { immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR; *decrementer_count = get_tbclk() / CONFIG_SYS_HZ; /* disable all interrupts */ out_be32(&immr->im_siu_conf.sc_simask, 0); /* Configure CPM interrupts */ cpm_interrupt_init(); }
int interrupt_init_cpu(unsigned long *decrementer_count) { volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; volatile ccsr_pic_t *pic = &immr->im_pic; pic->gcr = MPC86xx_PICGCR_RST; while (pic->gcr & MPC86xx_PICGCR_RST) ; pic->gcr = MPC86xx_PICGCR_MODE; *decrementer_count = get_tbclk() / CONFIG_SYS_HZ; debug("interrupt init: tbclk() = %d MHz, decrementer_count = %ld\n", (get_tbclk() / 1000000), *decrementer_count); #ifdef CONFIG_INTERRUPTS pic->iivpr1 = 0x810001; /* 50220 enable mcm interrupts */ debug("iivpr1@%x = %x\n", &pic->iivpr1, pic->iivpr1); pic->iivpr2 = 0x810002; /* 50240 enable ddr interrupts */ debug("iivpr2@%x = %x\n", &pic->iivpr2, pic->iivpr2); pic->iivpr3 = 0x810003; /* 50260 enable lbc interrupts */ debug("iivpr3@%x = %x\n", &pic->iivpr3, pic->iivpr3); #if defined(CONFIG_PCI1) || defined(CONFIG_PCIE1) pic->iivpr8 = 0x810008; /* enable pcie1 interrupts */ debug("iivpr8@%x = %x\n", &pic->iivpr8, pic->iivpr8); #endif #if defined(CONFIG_PCI2) || defined(CONFIG_PCIE2) pic->iivpr9 = 0x810009; /* enable pcie2 interrupts */ debug("iivpr9@%x = %x\n", &pic->iivpr9, pic->iivpr9); #endif pic->ctpr = 0; /* 40080 clear current task priority register */ #endif return 0; }
/* * For short delays only. It will overflow after a few seconds. */ void __udelay(unsigned long usec) { unsigned long cycles; unsigned long base; unsigned long now; base = sysreg_read(COUNT); cycles = ((usec * (get_tbclk() / 10000)) + 50) / 100; do { now = sysreg_read(COUNT); } while ((now - base) < cycles); }
/** * set_cpu_clk_info() - Initialize clock framework * Always returns zero. * * This function is called from common code after relocation and sets up the * clock framework. The framework must not be used before this function had been * called. */ int set_cpu_clk_info(void) { gd->cpu_clk = get_tbclk(); /* Support Veloce to show at least 1MHz via bdi */ if (gd->cpu_clk > 1000000) gd->bd->bi_arm_freq = gd->cpu_clk / 1000000; else gd->bd->bi_arm_freq = 1; gd->bd->bi_dsp_freq = 0; return 0; }
unsigned long ticks2usec(unsigned long ticks) { ulong tbclk = get_tbclk(); /* usec = ticks * 1000000 / tbclk * Multiplication would overflow at ~4.2e3 ticks, * so we break it up into * usec = ( ( ticks * 1000) / tbclk ) * 1000; */ ticks *= 1000L; ticks /= tbclk; ticks *= 1000L; return ((ulong)ticks); }
void set_timer(unsigned long t) { unsigned long long ticks = t; unsigned long lo, hi, hi_new; ticks = (ticks * get_tbclk()) / CFG_HZ; hi = ticks >> 32; lo = ticks & 0xffffffffUL; do { timer_overflow = hi; sysreg_write(COUNT, lo); hi_new = timer_overflow; } while (hi_new != hi); }
/* * For short delays only. It will overflow after a few seconds. */ void udelay(unsigned long usec) { unsigned long now, end; now = sysreg_read(COUNT); end = ((usec * (get_tbclk() / 10000)) + 50) / 100; end += now; while (now > end) now = sysreg_read(COUNT); while (now < end) now = sysreg_read(COUNT); }
void ft_cpu_setup(void *blob, bd_t *bd) { do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, "timebase-frequency", get_tbclk(), 1); do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, "bus-frequency", bd->bi_busfreq, 1); do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, "clock-frequency", bd->bi_intfreq, 1); do_fixup_by_compat_u32(blob, "fsl,cpm-brg", "clock-frequency", gd->arch.brg_clk, 1); /* Fixup ethernet MAC addresses */ fdt_fixup_ethernet(blob); fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize); }
static void pic32_mac_init(struct pic32eth_dev *priv, u8 *macaddr) { struct pic32_emac_regs *emac_p = priv->emac_regs; u32 stat = 0, v; u64 expire; v = EMAC_TXPAUSE | EMAC_RXPAUSE | EMAC_RXENABLE; writel(v, &emac_p->cfg1.raw); v = EMAC_EXCESS | EMAC_AUTOPAD | EMAC_PADENABLE | EMAC_CRCENABLE | EMAC_LENGTHCK | EMAC_FULLDUP; writel(v, &emac_p->cfg2.raw); /* recommended back-to-back inter-packet gap for 10 Mbps half duplex */ writel(HALFDUP_GAP_TIME, &emac_p->ipgt.raw); /* recommended non-back-to-back interpacket gap is 0xc12 */ writel(0xc12, &emac_p->ipgr.raw); /* recommended collision window retry limit is 0x370F */ writel(0x370f, &emac_p->clrt.raw); /* set maximum frame length: allow VLAN tagged frame */ writel(0x600, &emac_p->maxf.raw); /* set the mac address */ writel(macaddr[0] | (macaddr[1] << 8), &emac_p->sa2.raw); writel(macaddr[2] | (macaddr[3] << 8), &emac_p->sa1.raw); writel(macaddr[4] | (macaddr[5] << 8), &emac_p->sa0.raw); /* default, enable 10 Mbps operation */ writel(EMAC_RMII_SPD100, &emac_p->supp.clr); /* wait until link status UP or deadline elapsed */ expire = get_ticks() + get_tbclk() * 2; for (; get_ticks() < expire;) { stat = phy_read(priv->phydev, priv->phy_addr, MII_BMSR); if (stat & BMSR_LSTATUS) break; } if (!(stat & BMSR_LSTATUS)) printf("MAC: Link is DOWN!\n"); /* delay to stabilize before any tx/rx */ mdelay(10); }
/* Blinkin' LEDS for Robert. */ void show_activity(int flag) { volatile uint *blatch; if (next_led_update > get_ticks()) return; blatch = (volatile uint *)CONFIG_SYS_LBC_CFGLATCH_BASE; led_bit >>= 1; if (led_bit == 0) led_bit = 0x08; *blatch = (0xc0 | led_bit); eieio(); next_led_update += (get_tbclk() / 4); }
unsigned int zynqmp_get_silicon_version(void) { if (current_el() == 3) return zynqmp_get_silicon_version_secure(); gd->cpu_clk = get_tbclk(); switch (gd->cpu_clk) { case 0 ... 1000000: return ZYNQMP_CSU_VERSION_VELOCE; case 50000000: return ZYNQMP_CSU_VERSION_QEMU; case 4000000: return ZYNQMP_CSU_VERSION_EP108; } return ZYNQMP_CSU_VERSION_SILICON; }
int interrupt_init_cpu (unsigned *decrementer_count) { debug("interrupt_init: GT main cause reg: %08x:%08x\n", GTREGREAD(LOW_INTERRUPT_CAUSE_REGISTER), GTREGREAD(HIGH_INTERRUPT_CAUSE_REGISTER)); debug("interrupt_init: ethernet cause regs: %08x %08x %08x\n", GTREGREAD(ETHERNET0_INTERRUPT_CAUSE_REGISTER), GTREGREAD(ETHERNET1_INTERRUPT_CAUSE_REGISTER), GTREGREAD(ETHERNET2_INTERRUPT_CAUSE_REGISTER)); debug("interrupt_init: ethernet mask regs: %08x %08x %08x\n", GTREGREAD(ETHERNET0_INTERRUPT_MASK_REGISTER), GTREGREAD(ETHERNET1_INTERRUPT_MASK_REGISTER), GTREGREAD(ETHERNET2_INTERRUPT_MASK_REGISTER)); debug("interrupt_init: setting decrementer_count\n"); *decrementer_count = get_tbclk() / CONFIG_SYS_HZ; return (0); }
int watchdog_post_test (int flags) { if (flags & POST_REBOOT) { /* Test passed */ return 0; } else { /* 10-second delay */ int ints = disable_interrupts (); ulong base = gettbl (); ulong clk = get_tbclk (); while ((gettbl () - base) / 10 < clk); if (ints) enable_interrupts (); /* * If we have reached this point, the watchdog timer * does not work */ return -1; } }
int interrupt_init_cpu (ulong * decrementer_count) { *decrementer_count = get_tbclk () / CFG_HZ; return (0); }
unsigned long usec2ticks(unsigned long usec) { ulong ticks = ((usec * (get_tbclk()/1000)) + 500) / 1000; return (ticks); }
int do_fastboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { int ret = 1; char fbparts[4096], *env; int check_timeout = 0; uint64_t timeout_endtime = 0; uint64_t timeout_ticks = 0; long timeout_seconds = -1; int continue_from_disconnect = 0; /* * Place the runtime partitions at the end of the * static paritions. First save the start off so * it can be saved from run to run. */ if (static_pcount >= 0) { /* Reset */ pcount = static_pcount; } else { /* Save */ static_pcount = pcount; } env = getenv("fbparts"); if (env) { unsigned int len; len = strlen(env); if (len && len < 4096) { char *s, *e; memcpy(&fbparts[0], env, len + 1); printf("Fastboot: Adding partitions from environment\n"); s = &fbparts[0]; e = s + len; while (s < e) { if (add_partition_from_environment(s, &s)) { printf("Error:Fastboot: Abort adding partitions\n"); /* reset back to static */ pcount = static_pcount; break; } /* Skip a bunch of delimiters */ while (s < e) { if ((' ' == *s) || ('\t' == *s) || ('\n' == *s) || ('\r' == *s) || (',' == *s)) { s++; } else { break; } } } } } /* Time out */ if (2 == argc) { long try_seconds; char *try_seconds_end; /* Check for timeout */ try_seconds = simple_strtol(argv[1], &try_seconds_end, 10); if ((try_seconds_end != argv[1]) && (try_seconds >= 0)) { check_timeout = 1; timeout_seconds = try_seconds; printf("Fastboot inactivity timeout %ld seconds\n", timeout_seconds); } } if (1 == check_timeout) { timeout_ticks = (uint64_t) (timeout_seconds * get_tbclk()); } do { continue_from_disconnect = 0; /* Initialize the board specific support */ if (0 == fastboot_init(&interface)) { int poll_status; /* If we got this far, we are a success */ ret = 0; printf("fastboot initialized\n"); timeout_endtime = get_ticks(); timeout_endtime += timeout_ticks; while (1) { uint64_t current_time = 0; poll_status = fastboot_poll(); if (1 == check_timeout) current_time = get_ticks(); if (FASTBOOT_ERROR == poll_status) { /* Error */ break; } else if (FASTBOOT_DISCONNECT == poll_status) { /* beak, cleanup and re-init */ printf("Fastboot disconnect detected\n"); continue_from_disconnect = 1; break; } else if ((1 == check_timeout) && (FASTBOOT_INACTIVE == poll_status)) { /* No activity */ if (current_time >= timeout_endtime) { printf("Fastboot inactivity detected\n"); break; } } else { /* Something happened */ if (1 == check_timeout) { /* Update the timeout endtime */ timeout_endtime = current_time; timeout_endtime += timeout_ticks; } } /* Check if the user wanted to terminate with ^C */ if ((FASTBOOT_INACTIVE == poll_status) && (ctrlc())) { printf("Fastboot ended by user\n"); break; } /* * Check if the fastboot client wanted to * continue booting */ if (continue_booting) { printf("Fastboot ended by client\n"); break; } /* Check if there is something to upload */ tx_handler(); } } /* Reset the board specific support */ fastboot_shutdown(); /* restart the loop if a disconnect was detected */ } while (continue_from_disconnect); return ret; }