static void bfin_timer_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { switch (mode) { case CLOCK_EVT_MODE_PERIODIC: { set_gptimer_config(TIMER0_id, \ TIMER_OUT_DIS | TIMER_IRQ_ENA | \ TIMER_PERIOD_CNT | TIMER_MODE_PWM); set_gptimer_period(TIMER0_id, get_sclk() / HZ); set_gptimer_pwidth(TIMER0_id, get_sclk() / HZ - 1); enable_gptimers(TIMER0bit); break; } case CLOCK_EVT_MODE_ONESHOT: disable_gptimers(TIMER0bit); set_gptimer_config(TIMER0_id, \ TIMER_OUT_DIS | TIMER_IRQ_ENA | TIMER_MODE_PWM); set_gptimer_period(TIMER0_id, 0); break; case CLOCK_EVT_MODE_UNUSED: case CLOCK_EVT_MODE_SHUTDOWN: disable_gptimers(TIMER0bit); break; case CLOCK_EVT_MODE_RESUME: break; } }
static int bfin_wdt_set_timeout(unsigned long t) { u32 cnt; unsigned long flags; stampit(); cnt = t * get_sclk(); if (cnt < get_sclk()) { printk(KERN_WARNING PFX "timeout value is too large\n"); return -EINVAL; } spin_lock_irqsave(&bfin_wdt_spinlock, flags); { int run = bfin_wdt_running(); bfin_wdt_stop(); bfin_write_WDOG_CNT(cnt); if (run) bfin_wdt_start(); } spin_unlock_irqrestore(&bfin_wdt_spinlock, flags); timeout = t; return 0; }
static void config_timers(void) { unsigned long timer_period = 0; pr_debug("%s\n", __func__); /* stop timers */ #ifdef CONFIG_BFIN561_BLUETECHNIX_CM bfin_write_TMRS8_DISABLE((1 << TIMER_DCLK) | (1 << TIMER_VSYNC) | (1 << TIMER_BACKLIGHT)); bfin_write_TMRS4_DISABLE((1 << (TIMER_HSYNC - 8)) | (1 << (TIMER_DTMG - 8))); #else bfin_write_TIMER_DISABLE((1 << TIMER_VSYNC) | (1 << TIMER_HSYNC) | (1 << TIMER_DTMG) | (1 << TIMER_DCLK) | (1 << TIMER_BACKLIGHT)); #endif SSYNC(); /* dclk clock output */ BFIN_WRITE(TIMER_DCLK, CONFIG) (PERIOD_CNT | PULSE_HI | PWM_OUT); timer_period = get_sclk() / (CONFIG_FB_HITACHI_TX09_REFRESHRATE * 89271); BFIN_WRITE(TIMER_DCLK, PERIOD) (timer_period); BFIN_WRITE(TIMER_DCLK, WIDTH) (timer_period / 2); SSYNC(); /* brightness timer */ BFIN_WRITE(TIMER_BACKLIGHT, CONFIG) (PERIOD_CNT | PULSE_HI | PWM_OUT); timer_period = get_sclk() / 100000; BFIN_WRITE(TIMER_BACKLIGHT, PERIOD) (timer_period); BFIN_WRITE(TIMER_BACKLIGHT, WIDTH) (timer_period - 1); /* 100% duty cycle */ SSYNC(); /* hsync timer */ BFIN_WRITE(TIMER_HSYNC, CONFIG) (CLK_SEL | TIN_SEL | PERIOD_CNT | PWM_OUT); /* clocked by PPI_clk */ BFIN_WRITE(TIMER_HSYNC, PERIOD) (273); /* 240 + 33 blanking */ BFIN_WRITE(TIMER_HSYNC, WIDTH) (5); SSYNC(); /* dtmg timer */ BFIN_WRITE(TIMER_DTMG, CONFIG) (CLK_SEL | TIN_SEL | PERIOD_CNT | PWM_OUT); /* clocked by PPI_clk */ BFIN_WRITE(TIMER_DTMG, PERIOD) (273); BFIN_WRITE(TIMER_DTMG, WIDTH) (33); SSYNC(); /* vsync timer */ BFIN_WRITE(TIMER_VSYNC, CONFIG) (CLK_SEL | TIN_SEL | PERIOD_CNT | PWM_OUT); /* clocked by PPI_clk */ BFIN_WRITE(TIMER_VSYNC, PERIOD) (89271); BFIN_WRITE(TIMER_VSYNC, WIDTH) (1911); SSYNC(); t_conf_done = 1; }
/** * bfin_otp_init_timing - setup OTP timing parameters * * Required before doing any write operation. Algorithms from HRM. */ static u32 bfin_otp_init_timing(void) { u32 tp1, tp2, tp3, timing; tp1 = get_sclk() / 1000000; tp2 = (2 * get_sclk() / 10000000) << 8; tp3 = (0x1401) << 15; timing = tp1 | tp2 | tp3; if (bfrom_OtpCommand(OTP_INIT, timing)) return 0; return timing; }
static void sdh_set_clk(unsigned long clk) { unsigned long sys_clk; unsigned long clk_div; u16 clk_ctl = 0; clk_ctl = bfin_read_SDH_CLK_CTL(); if (clk) { /* setting SD_CLK */ sys_clk = get_sclk(); bfin_write_SDH_CLK_CTL(clk_ctl & ~CLK_E); SSYNC(); if (sys_clk % (2 * clk) == 0) clk_div = sys_clk / (2 * clk) - 1; else clk_div = sys_clk / (2 * clk); if (clk_div > 0xff) clk_div = 0xff; clk_ctl |= (clk_div & 0xff); clk_ctl |= CLK_E; bfin_write_SDH_CLK_CTL(clk_ctl); } else bfin_write_SDH_CLK_CTL(clk_ctl & ~CLK_E); SSYNC(); }
static ssize_t iio_bfin_tmr_frequency_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct iio_trigger *trig = dev_get_drvdata(dev); struct bfin_tmr_state *st = trig->private_data; long val; int ret; ret = strict_strtoul(buf, 10, &val); if (ret) goto error_ret; if (val > 100000) { ret = -EINVAL; goto error_ret; } disable_gptimers(st->t->bit); if (!val) goto error_ret; val = get_sclk() / val; if (val <= 4) { ret = -EINVAL; goto error_ret; } set_gptimer_period(st->t->id, val); set_gptimer_pwidth(st->t->id, 1); enable_gptimers(st->t->bit); error_ret: return ret ? ret : count; }
static int bfin_wdt_set_timeout(unsigned long t) { u32 cnt, max_t, sclk; unsigned long flags; sclk = get_sclk(); max_t = -1 / sclk; cnt = t * sclk; stamp("maxtimeout=%us newtimeout=%lus (cnt=%#x)", max_t, t, cnt); if (t > max_t) { printk(KERN_WARNING PFX "timeout value is too large\n"); return -EINVAL; } spin_lock_irqsave(&bfin_wdt_spinlock, flags); { int run = bfin_wdt_running(); bfin_wdt_stop(); bfin_write_WDOG_CNT(cnt); if (run) bfin_wdt_start(); } spin_unlock_irqrestore(&bfin_wdt_spinlock, flags); timeout = t; return 0; }
static int mii_probe(struct net_device *dev, int phy_mode) { struct bfin_mac_local *lp = netdev_priv(dev); struct phy_device *phydev; unsigned short sysctl; u32 sclk, mdc_div; /* Enable PHY output early */ if (!(bfin_read_VR_CTL() & CLKBUFOE)) bfin_write_VR_CTL(bfin_read_VR_CTL() | CLKBUFOE); sclk = get_sclk(); mdc_div = ((sclk / MDC_CLK) / 2) - 1; sysctl = bfin_read_EMAC_SYSCTL(); sysctl = (sysctl & ~MDCDIV) | SET_MDCDIV(mdc_div); bfin_write_EMAC_SYSCTL(sysctl); phydev = phy_find_first(lp->mii_bus); if (!phydev) { netdev_err(dev, "no phy device found\n"); return -ENODEV; } if (phy_mode != PHY_INTERFACE_MODE_RMII && phy_mode != PHY_INTERFACE_MODE_MII) { netdev_err(dev, "invalid phy interface mode\n"); return -EINVAL; } phydev = phy_connect(dev, phydev_name(phydev), &bfin_mac_adjust_link, phy_mode); if (IS_ERR(phydev)) { netdev_err(dev, "could not attach PHY\n"); return PTR_ERR(phydev); } /* mask with MAC supported features */ phydev->supported &= (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_Autoneg | SUPPORTED_Pause | SUPPORTED_Asym_Pause | SUPPORTED_MII | SUPPORTED_TP); phydev->advertising = phydev->supported; lp->old_link = 0; lp->old_speed = 0; lp->old_duplex = -1; lp->phydev = phydev; phy_attached_print(phydev, "mdc_clk=%dHz(mdc_div=%d)@sclk=%dMHz)\n", MDC_CLK, mdc_div, sclk / 1000000); return 0; }
int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) { unsigned long period, duty; unsigned long long val; if (duty_ns < 0 || duty_ns > period_ns) return -EINVAL; val = (unsigned long long)get_sclk() * period_ns; do_div(val, NSEC_PER_SEC); period = val; val = (unsigned long long)period * duty_ns; do_div(val, period_ns); duty = period - val; if (duty >= period) duty = period - 1; set_gptimer_config(pwm->id, TIMER_MODE_PWM | TIMER_PERIOD_CNT); set_gptimer_pwidth(pwm->id, duty); set_gptimer_period(pwm->id, period); return 0; }
static void set_backlight(int val) { unsigned long timer_period; pr_debug("%s to %d\n", __func__, val); if (val < 0) val = 0; if (val > MAX_BRIGHTNESS) val = MAX_BRIGHTNESS; current_brightness = val; #ifdef CONFIG_BFIN561_BLUETECHNIX_CM bfin_write_TMRS8_DISABLE(1 << TIMER_BACKLIGHT); #else bfin_write_TIMER_DISABLE(1 << TIMER_BACKLIGHT); #endif SSYNC(); timer_period = get_sclk() / 100000; BFIN_WRITE(TIMER_BACKLIGHT, WIDTH) ((timer_period * val) / 100); #ifdef CONFIG_BFIN561_BLUETECHNIX_CM bfin_write_TMRS8_ENABLE(1 << TIMER_BACKLIGHT); #else bfin_write_TIMER_ENABLE(1 << TIMER_BACKLIGHT); #endif SSYNC(); }
int musb_platform_init(void) { /* board specific initialization */ board_musb_init(); bfin_anomaly_init(); /* Configure PLL oscillator register */ bfin_write_USB_PLLOSC_CTRL(0x3080 | ((480 / CONFIG_USB_BLACKFIN_CLKIN) << 1)); SSYNC(); bfin_write_USB_SRP_CLKDIV((get_sclk()/1000) / 32 - 1); SSYNC(); bfin_write_USB_EP_NI0_RXMAXP(64); SSYNC(); bfin_write_USB_EP_NI0_TXMAXP(64); SSYNC(); /* Route INTRUSB/INTR_RX/INTR_TX to USB_INT0*/ bfin_write_USB_GLOBINTR(0x7); SSYNC(); bfin_write_USB_GLOBAL_CTL(GLOBAL_ENA | EP1_TX_ENA | EP2_TX_ENA | EP3_TX_ENA | EP4_TX_ENA | EP5_TX_ENA | EP6_TX_ENA | EP7_TX_ENA | EP1_RX_ENA | EP2_RX_ENA | EP3_RX_ENA | EP4_RX_ENA | EP5_RX_ENA | EP6_RX_ENA | EP7_RX_ENA); SSYNC(); return 0; }
static void bfin_mac_hwtstamp_init(struct net_device *netdev) { struct bfin_mac_local *lp = netdev_priv(netdev); u64 append; append = PTP_CLK * (1ULL << 32); do_div(append, get_sclk()); bfin_write_EMAC_PTP_ADDEND((u32)append); memset(&lp->cycles, 0, sizeof(lp->cycles)); lp->cycles.read = bfin_read_clock; lp->cycles.mask = CLOCKSOURCE_MASK(64); lp->cycles.mult = 1000000000 / PTP_CLK; lp->cycles.shift = 0; memset(&lp->compare, 0, sizeof(lp->compare)); lp->compare.source = &lp->clock; lp->compare.target = ktime_get_real; lp->compare.num_samples = 10; lp->stamp_cfg.rx_filter = HWTSTAMP_FILTER_NONE; lp->stamp_cfg.tx_type = HWTSTAMP_TX_OFF; }
static void __devinit bfin_sir_init_ports(struct bfin_sir_port *sp, struct platform_device *pdev) { int i; struct resource *res; for (i = 0; i < pdev->num_resources; i++) { res = &pdev->resource[i]; switch (res->flags) { case IORESOURCE_MEM: sp->membase = (void __iomem *)res->start; break; case IORESOURCE_IRQ: sp->irq = res->start; break; case IORESOURCE_DMA: sp->rx_dma_channel = res->start; sp->tx_dma_channel = res->end; break; default: break; } } sp->clk = get_sclk(); #ifdef CONFIG_SIR_BFIN_DMA sp->tx_done = 1; init_timer(&(sp->rx_dma_timer)); #endif }
int bfin_mmc_init(bd_t *bis) { struct mmc *mmc = NULL; mmc = malloc(sizeof(struct mmc)); if (!mmc) return -ENOMEM; sprintf(mmc->name, "Blackfin SDH"); mmc->send_cmd = bfin_sdh_request; mmc->set_ios = bfin_sdh_set_ios; mmc->init = bfin_sdh_init; mmc->getcd = NULL; mmc->host_caps = MMC_MODE_4BIT; mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; mmc->f_max = get_sclk(); mmc->f_min = mmc->f_max >> 9; mmc->b_max = 1; mmc_register(mmc); return 0; }
static inline u16 get_eppi_clkdiv(u32 target_ppi_clk) { u32 sclk = get_sclk(); /* EPPI_CLK = (SCLK) / (2 * (EPPI_CLKDIV[15:0] + 1)) */ return (((sclk / target_ppi_clk) / 2) - 1); }
void show_regs(struct pt_regs *fp) { char buf[150]; struct irqaction *action; unsigned int i; unsigned long flags = 0; unsigned int cpu = raw_smp_processor_id(); unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic(); pr_notice("\n"); if (CPUID != bfin_cpuid()) pr_notice("Compiled for cpu family 0x%04x (Rev %d), " "but running on:0x%04x (Rev %d)\n", CPUID, bfin_compiled_revid(), bfin_cpuid(), bfin_revid()); pr_notice("ADSP-%s-0.%d", CPU, bfin_compiled_revid()); if (bfin_compiled_revid() != bfin_revid()) pr_cont("(Detected 0.%d)", bfin_revid()); pr_cont(" %lu(MHz CCLK) %lu(MHz SCLK) (%s)\n", get_cclk()/1000000, get_sclk()/1000000, #ifdef CONFIG_MPU "mpu on" #else "mpu off" #endif ); if(board_rom_type()) pr_notice("%s", linux_banner_stockui); else pr_notice("%s", linux_banner); pr_notice("\nSEQUENCER STATUS:\t\t%s\n", print_tainted()); pr_notice(" SEQSTAT: %08lx IPEND: %04lx IMASK: %04lx SYSCFG: %04lx\n", (long)fp->seqstat, fp->ipend, cpu_pda[raw_smp_processor_id()].ex_imask, fp->syscfg); if (fp->ipend & EVT_IRPTEN) pr_notice(" Global Interrupts Disabled (IPEND[4])\n"); if (!(cpu_pda[raw_smp_processor_id()].ex_imask & (EVT_IVG13 | EVT_IVG12 | EVT_IVG11 | EVT_IVG10 | EVT_IVG9 | EVT_IVG8 | EVT_IVG7 | EVT_IVTMR))) pr_notice(" Peripheral interrupts masked off\n"); if (!(cpu_pda[raw_smp_processor_id()].ex_imask & (EVT_IVG15 | EVT_IVG14))) pr_notice(" Kernel interrupts masked off\n"); if ((fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) { pr_notice(" HWERRCAUSE: 0x%lx\n", (fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14); #ifdef EBIU_ERRMST if (bfin_read_EBIU_ERRMST() & CORE_ERROR) { pr_notice(" EBIU Error Reason : 0x%04x\n", bfin_read_EBIU_ERRMST()); pr_notice(" EBIU Error Address : 0x%08x\n", bfin_read_EBIU_ERRADD()); } #endif }
static int __init bfin_cs_gptimer0_init(void) { setup_gptimer0(); if (clocksource_register_hz(&bfin_cs_gptimer0, get_sclk())) panic("failed to register clocksource"); return 0; }
static ssize_t iio_bfin_tmr_frequency_show(struct device *dev, struct device_attribute *attr, char *buf) { struct iio_trigger *trig = dev_get_drvdata(dev); struct bfin_tmr_state *st = trig->private_data; return sprintf(buf, "%lu\n", get_sclk() / get_gptimer_period(st->t->id)); }
/* Caculate the SPI_BAUD register value based on input HZ */ static u16 hz_to_spi_baud(u32 speed_hz) { u_long sclk = get_sclk(); u16 spi_baud = (sclk / (2 * speed_hz)); if ((sclk % (2 * speed_hz)) > 0) spi_baud++; return spi_baud; }
int __init __timerbench_init (void) { int ret = 0; ret = register_chrdev (TB_MAJOR, TB_DEVNAME, &tb_fops); tb_cclk = get_cclk (); tb_sclk = get_sclk (); return ret; }
static int __init bfin_cs_gptimer0_init(void) { setup_gptimer0(); bfin_cs_gptimer0.mult = \ clocksource_hz2mult(get_sclk(), bfin_cs_gptimer0.shift); if (clocksource_register(&bfin_cs_gptimer0)) panic("failed to register clocksource"); return 0; }
int bfin_mmc_init(bd_t *bis) { struct mmc *mmc; bfin_mmc_cfg.f_max = get_sclk(); bfin_mmc_cfg.f_min = bfin_mmc_cfg.f_max >> 9; mmc = mmc_create(&bfin_mmc_cfg, NULL); if (mmc == NULL) return -1; return 0; }
/* Caculate the SPI_BAUD register value based on input HZ */ static u16 hz_to_spi_baud(u32 speed_hz) { u_long sclk = get_sclk(); u16 spi_baud = (sclk / (2 * speed_hz)); if ((sclk % (2 * speed_hz)) > 0) spi_baud++; if (spi_baud < MIN_SPI_BAUD_VAL) spi_baud = MIN_SPI_BAUD_VAL; return spi_baud; }
static void __init bfin_gptmr0_clockevent_init(struct clock_event_device *evt) { unsigned long clock_tick; clock_tick = get_sclk(); evt->mult = div_sc(clock_tick, NSEC_PER_SEC, evt->shift); evt->max_delta_ns = clockevent_delta2ns(-1, evt); evt->min_delta_ns = clockevent_delta2ns(100, evt); evt->cpumask = cpumask_of(0); clockevents_register_device(evt); }
struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, unsigned int max_hz, unsigned int mode) { struct bfin_spi_slave *bss; u32 mmr_base; u32 baud; if (!spi_cs_is_valid(bus, cs)) return NULL; switch (bus) { #ifdef SPI_CTL # define SPI0_CTL SPI_CTL #endif case 0: mmr_base = SPI0_CTL; break; #ifdef SPI1_CTL case 1: mmr_base = SPI1_CTL; break; #endif #ifdef SPI2_CTL case 2: mmr_base = SPI2_CTL; break; #endif default: return NULL; } baud = get_sclk() / (2 * max_hz); if (baud < 2) baud = 2; else if (baud > (u16)-1) baud = -1; bss = malloc(sizeof(*bss)); if (!bss) return NULL; bss->slave.bus = bus; bss->slave.cs = cs; bss->mmr_base = (void *)mmr_base; bss->ctl = SPE | MSTR | TDBR_CORE; if (mode & SPI_CPHA) bss->ctl |= CPHA; if (mode & SPI_CPOL) bss->ctl |= CPOL; if (mode & SPI_LSB_FIRST) bss->ctl |= LSBF; bss->baud = baud; bss->flg = mode & SPI_CS_HIGH ? 1 : 0; debug("%s: bus:%i cs:%i mmr:%x ctl:%x baud:%i flg:%i\n", __func__, bus, cs, mmr_base, bss->ctl, baud, bss->flg); return &bss->slave; }
static void set_otp_timing(bool write) { static uint32_t timing; if (!timing) { uint32_t tp1, tp2, tp3; /* OTP_TP1 = 1000 / sclk_period (in nanoseconds) * OTP_TP1 = 1000 / (1 / get_sclk() * 10^9) * OTP_TP1 = (1000 * get_sclk()) / 10^9 * OTP_TP1 = get_sclk() / 10^6 */ tp1 = get_sclk() / 1000000; /* OTP_TP2 = 400 / (2 * sclk_period) * OTP_TP2 = 400 / (2 * 1 / get_sclk() * 10^9) * OTP_TP2 = (400 * get_sclk()) / (2 * 10^9) * OTP_TP2 = (2 * get_sclk()) / 10^7 */ tp2 = (2 * get_sclk() / 10000000) << 8; /* OTP_TP3 = magic constant */ tp3 = (0x1401) << 15; timing = tp1 | tp2 | tp3; } bfrom_OtpCommand(OTP_INIT, write ? timing : timing & ~(-1 << 15)); }
void spi_set_speed(struct spi_slave *slave, uint hz) { struct bfin_spi_slave *bss = to_bfin_spi_slave(slave); ulong sclk; u32 baud; sclk = get_sclk(); /* baud should be rounded up */ baud = DIV_ROUND_UP(sclk, 2 * hz); if (baud < 2) baud = 2; else if (baud > (u16)-1) baud = -1; bss->baud = baud; }
/* Caculate the SPI_BAUD register value based on input HZ */ static u16 bfin_sport_hz_to_spi_baud(u32 speed_hz) { u_long clk, sclk = get_sclk(); int div = (sclk / (2 * speed_hz)) - 1; if (div < 0) div = 0; clk = sclk / (2 * (div + 1)); if (clk > speed_hz) div++; return div; }
void __init setup_system_timer0(void) { /* Power down the core timer, just to play safe. */ bfin_write_TCNTL(0); disable_gptimers(TIMER0bit); set_gptimer_status(0, TIMER_STATUS_TRUN0); while (get_gptimer_status(0) & TIMER_STATUS_TRUN0) udelay(10); set_gptimer_config(0, 0x59); /* IRQ enable, periodic, PWM_OUT, SCLKed, OUT PAD disabled */ set_gptimer_period(TIMER0_id, get_sclk() / HZ); set_gptimer_pwidth(TIMER0_id, 1); SSYNC(); enable_gptimers(TIMER0bit); }
static ssize_t iio_bfin_tmr_frequency_show(struct device *dev, struct device_attribute *attr, char *buf) { struct iio_trigger *trig = to_iio_trigger(dev); struct bfin_tmr_state *st = trig->private_data; unsigned int period = get_gptimer_period(st->t->id); unsigned long val; if (period == 0) val = 0; else val = get_sclk() / get_gptimer_period(st->t->id); return sprintf(buf, "%lu\n", val); }