static u32 libfdt_property_len(const char *prop, u32 address_cells, u32 size_cells, u32 len) { u32 lsz, type, reg_cells, reg_count; /* Special way of handling 'reg' property */ if (strcmp(prop, "reg") == 0) { reg_cells = len / sizeof(fdt_cell_t); reg_count = udiv32(reg_cells, address_cells + size_cells); if (umod32(reg_cells, address_cells + size_cells)) { reg_count++; } reg_cells = sizeof(physical_addr_t) / sizeof(fdt_cell_t); reg_cells += sizeof(physical_size_t) / sizeof(fdt_cell_t); reg_count = reg_count * (reg_cells * sizeof(fdt_cell_t)); return reg_count; } type = vmm_devtree_estimate_attrtype(prop); /* Special way of handling non-literal property */ if (!vmm_devtree_isliteral(type)) { return len; } /* Special way of handling literal property */ lsz = vmm_devtree_literal_size(type); if (umod32(len, lsz)) { return udiv32(len, lsz) * lsz + lsz; } return len; }
void samsung_lowlevel_init(virtual_addr_t base, u32 baudrate, u32 input_clock) { unsigned int divider; unsigned int temp; unsigned int remainder; /* First, disable everything */ vmm_out_le16((void *)(base + S3C2410_UCON), 0); /* * Set baud rate * * UBRDIV = (UART_CLK / (16 * BAUD_RATE)) - 1 * DIVSLOT = MOD(UART_CLK / BAUD_RATE, 16) */ temp = udiv32(input_clock, baudrate); divider = udiv32(temp, 16) - 1; remainder = umod32(temp, 16); vmm_out_le16((void *)(base + S3C2410_UBRDIV), (u16) divider); vmm_out_8((void *)(base + S3C2443_DIVSLOT), (u8) remainder); /* Set the UART to be 8 bits, 1 stop bit, no parity */ vmm_out_le32((void *)(base + S3C2410_ULCON), S3C2410_LCON_CS8 | S3C2410_LCON_PNONE); /* enable FIFO, set RX and TX trigger */ vmm_out_le32((void *)(base + S3C2410_UFCON), S3C2410_UFCON_DEFAULT); /* enable the UART */ vmm_out_le32((void *)(base + S3C2410_UCON), S3C2410_UCON_DEFAULT); }
static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { struct mmci_host *host = mmc_priv(mmc); u32 sdi_clkcr; sdi_clkcr = vmm_readl(&host->base->clock); /* Ramp up the clock rate */ if (ios->clock) { u32 clkdiv = 0; u32 tmp_clock; if (ios->clock >= mmc->f_max) { clkdiv = 0; ios->clock = mmc->f_max; } else { clkdiv = udiv32(host->clock_in, ios->clock) - 2; } tmp_clock = udiv32(host->clock_in, (clkdiv + 2)); while (tmp_clock > ios->clock) { clkdiv++; tmp_clock = udiv32(host->clock_in, (clkdiv + 2)); } if (clkdiv > SDI_CLKCR_CLKDIV_MASK) clkdiv = SDI_CLKCR_CLKDIV_MASK; tmp_clock = udiv32(host->clock_in, (clkdiv + 2)); ios->clock = tmp_clock; sdi_clkcr &= ~(SDI_CLKCR_CLKDIV_MASK); sdi_clkcr |= clkdiv; } /* Set the bus width */ if (ios->bus_width) { u32 buswidth = 0; switch (ios->bus_width) { case 1: buswidth |= SDI_CLKCR_WIDBUS_1; break; case 4: buswidth |= SDI_CLKCR_WIDBUS_4; break; case 8: buswidth |= SDI_CLKCR_WIDBUS_8; break; default: vmm_printf("%s: Invalid bus width: %d\n", __func__, ios->bus_width); break; } sdi_clkcr &= ~(SDI_CLKCR_WIDBUS_MASK); sdi_clkcr |= buswidth; } vmm_writel(sdi_clkcr, &host->base->clock); vmm_udelay(CLK_CHANGE_DELAY); }
static u32 epool_slab_buf_count(u32 pool_sz, u32 slab) { u32 slab_size, buf_size, weight, total_weight; switch (slab) { case 0: weight = 1; break; case 1: weight = 1; break; case 2: weight = 4; break; case 3: weight = 2; break; default: return 0; }; total_weight = 8; buf_size = epool_slab_buf_size(slab); if (!buf_size) { return 0; } slab_size = udiv32(pool_sz, total_weight) * weight; if (!slab_size) { return 0; } return udiv32(slab_size, buf_size); }
static int sdhci_set_clock(struct mmc_host *mmc, u32 clock) { struct sdhci_host *host = (struct sdhci_host *)mmc->priv; u32 div, clk, timeout; sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); if (clock == 0) { return VMM_OK; } if ((host->sdhci_version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300) { /* Version 3.00 divisors must be a multiple of 2. */ if (mmc->f_max <= clock) div = 1; else { for (div = 2; div < SDHCI_MAX_DIV_SPEC_300; div += 2) { if (udiv32(mmc->f_max, div) <= clock) { break; } } } } else { /* Version 2.00 divisors must be a power of 2. */ for (div = 1; div < SDHCI_MAX_DIV_SPEC_200; div *= 2) { if (udiv32(mmc->f_max, div) <= clock) { break; } } } div >>= 1; if (host->ops.set_clock) { host->ops.set_clock(host, div); } clk = (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) << SDHCI_DIVIDER_HI_SHIFT; clk |= SDHCI_CLOCK_INT_EN; sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); /* Wait max 20 ms */ timeout = 20; while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL)) & SDHCI_CLOCK_INT_STABLE)) { if (timeout == 0) { vmm_printf("%s: Internal clock never stabilised.\n", __func__); return VMM_EFAIL; } timeout--; vmm_udelay(1000); } clk |= SDHCI_CLOCK_CARD_EN; sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); return VMM_OK; }
void imx_lowlevel_init(virtual_addr_t base, u32 baudrate, u32 input_clock) { unsigned int temp = vmm_readl((void *)(base + UCR1)); unsigned int divider; /* First, disable everything */ temp &= ~UCR1_UARTEN; vmm_writel(temp, (void *)base + UCR1); /* disable all UCR2 related interrupts */ temp = vmm_readl((void *)(base + UCR2)); temp &= ~(UCR2_ATEN | UCR2_ESCI | UCR2_RTSEN); /* Set to 8N1 */ temp = (temp & ~(UCR2_PREN | UCR2_STPB)) | UCR2_WS; /* Ignore RTS */ temp |= UCR2_IRTS; vmm_writel(temp, (void *)(base + UCR2)); /* disable all UCR3 related interrupts */ temp = vmm_readl((void *)(base + UCR3)); vmm_writel(temp & ~(UCR3_RXDSEN | UCR3_DTREN | UCR3_FRAERREN | UCR3_TIMEOUTEN | UCR3_AIRINTEN | UCR3_AWAKEN | UCR3_DTRDEN), (void *)(base + UCR3)); /* disable all UCR4 related interrupts */ temp = vmm_readl((void *)(base + UCR4)); vmm_writel(temp & ~(UCR4_DREN | UCR4_TCEN | UCR4_ENIRI | UCR4_WKEN | UCR4_BKEN | UCR4_OREN), (void *)(base + UCR4)); /* trigger interrupt when there is 1 by in the RXFIFO */ temp = vmm_readl((void *)(base + UFCR)); vmm_writel((temp & 0xFFC0) | 1, (void *)(base + UFCR)); /* Divide input clock by 2 */ temp = vmm_readl((void *)(base + UFCR)) & ~UFCR_RFDIV; vmm_writel(temp | UFCR_RFDIV_REG(2), (void *)(base + UFCR)); input_clock /= 2; divider = udiv32(baudrate, 100) - 1; vmm_writel(divider, (void *)(base + UBIR)); /* UBMR = Ref Freq / (16 * baudrate) * (UBIR + 1) - 1 */ /* As UBIR = baudrate / 100 - 1, UBMR = Ref Freq / (16 * 100) - 1 */ temp = udiv32(input_clock, 16 * 100) - 1; vmm_writel(temp, (void *)(base + UBMR)); /* enable the UART */ temp = UCR1_UARTEN; vmm_writel(temp, (void *)(base + UCR1)); /* Enable FIFOs */ temp = vmm_readl((void *)(base + UCR2)); vmm_writel(temp | UCR2_SRST | UCR2_RXEN | UCR2_TXEN, (void *)(base + UCR2)); }
struct icst_vco icst_hz_to_vco(const struct icst_params *p, unsigned long freq) { struct icst_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max }; unsigned long f; unsigned int i = 0, rd, best = (unsigned int)-1; /* * First, find the PLL output divisor such * that the PLL output is within spec. */ do { f = freq * p->s2div[p->idx2s[i]]; if (f > p->vco_min && f <= p->vco_max) break; i++; } while (i < 8); if (i == 8) return vco; vco.s = p->idx2s[i]; /* * Now find the closest divisor combination * which gives a PLL output of 'f'. */ for (rd = p->rd_min; rd <= p->rd_max; rd++) { unsigned long fref_div, f_pll; unsigned int vd; int f_diff; fref_div = udiv32((2 * p->ref), rd); vd = udiv32((f + fref_div / 2), fref_div); if (vd < p->vd_min || vd > p->vd_max) continue; f_pll = fref_div * vd; f_diff = f_pll - f; if (f_diff < 0) f_diff = -f_diff; if ((unsigned)f_diff < best) { vco.v = vd - 8; vco.r = rd - 2; if (f_diff == 0) break; best = f_diff; } } return vco; }
static int cmd_host_cpu_stats(struct vmm_chardev *cdev) { int rc; char str[16]; u32 c, p, khz, util; unsigned long hwid; vmm_cprintf(cdev, "----------------------------------------" "----------------------------------------\n"); vmm_cprintf(cdev, " %4s %14s %15s %13s %12s %16s\n", "CPU#", "HWID", "Speed (MHz)", "Util. (%)", "IRQs (%)", "Active VCPUs"); vmm_cprintf(cdev, "----------------------------------------" "----------------------------------------\n"); for_each_online_cpu(c) { vmm_cprintf(cdev, " %4d", c); rc = vmm_smp_map_hwid(c, &hwid); if (rc) return rc; vmm_snprintf(str, sizeof(str), "0x%lx", hwid); vmm_cprintf(cdev, " %14s", str); khz = vmm_delay_estimate_cpu_khz(c); vmm_cprintf(cdev, " %11d.%03d", udiv32(khz, 1000), umod32(khz, 1000)); util = udiv64(vmm_scheduler_idle_time(c) * 1000, vmm_scheduler_get_sample_period(c)); util = (util > 1000) ? 1000 : util; util = 1000 - util; vmm_cprintf(cdev, " %11d.%01d", udiv32(util, 10), umod32(util, 10)); util = udiv64(vmm_scheduler_irq_time(c) * 1000, vmm_scheduler_get_sample_period(c)); util = (util > 1000) ? 1000 : util; vmm_cprintf(cdev, " %10d.%01d", udiv32(util, 10), umod32(util, 10)); util = 1; for (p = VMM_VCPU_MIN_PRIORITY; p <= VMM_VCPU_MAX_PRIORITY; p++) { util += vmm_scheduler_ready_count(c, p); } vmm_cprintf(cdev, " %15d ", util); vmm_cprintf(cdev, "\n"); } vmm_cprintf(cdev, "----------------------------------------" "----------------------------------------\n"); return VMM_OK; }
static void vmm_fb_cvt_print_name(struct vmm_fb_cvt_data *cvt) { u32 pixcount, pixcount_mod; int cnt = 255, offset = 0, read = 0; char *buf = vmm_zalloc(256); if (!buf) return; pixcount = (cvt->xres * udiv32(cvt->yres, cvt->interlace))/1000000; pixcount_mod = (cvt->xres * udiv32(cvt->yres, cvt->interlace)) % 1000000; pixcount_mod /= 1000; read = vmm_snprintf(buf+offset, cnt, "fbcvt: %dx%d@%d: CVT Name - ", cvt->xres, cvt->yres, cvt->refresh); offset += read; cnt -= read; if (cvt->status) vmm_snprintf(buf+offset, cnt, "Not a CVT standard - %d.%03d Mega " "Pixel Image\n", pixcount, pixcount_mod); else { if (pixcount) { read = vmm_snprintf(buf+offset, cnt, "%d", pixcount); cnt -= read; offset += read; } read = vmm_snprintf(buf+offset, cnt, ".%03dM", pixcount_mod); cnt -= read; offset += read; if (cvt->aspect_ratio == 0) read = vmm_snprintf(buf+offset, cnt, "3"); else if (cvt->aspect_ratio == 3) read = vmm_snprintf(buf+offset, cnt, "4"); else if (cvt->aspect_ratio == 1 || cvt->aspect_ratio == 4) read = vmm_snprintf(buf+offset, cnt, "9"); else if (cvt->aspect_ratio == 2) read = vmm_snprintf(buf+offset, cnt, "A"); else read = 0; cnt -= read; offset += read; if (cvt->flags & FB_CVT_FLAG_REDUCED_BLANK) { read = vmm_snprintf(buf+offset, cnt, "-R"); cnt -= read; offset += read; } } vmm_printf("%s\n", buf); vmm_free(buf); }
/* * fast_imageblit - optimized monochrome color expansion * * Only if: bits_per_pixel == 8, 16, or 32 * image->width is divisible by pixel/dword (ppw); * fix->line_legth is divisible by 4; * beginning and end of a scanline is dword aligned */ static inline void fast_imageblit(const struct vmm_fb_image *image, struct vmm_fb_info *p, u8 *dst1, u32 fgcolor, u32 bgcolor) { u32 fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel; u32 ppw = udiv32(32, bpp), spitch = (image->width + 7)/8; u32 bit_mask, end_mask, eorx, shift; const char *s = image->data, *src; u32 *dst; const u32 *tab = NULL; int i, j, k; switch (bpp) { case 8: tab = vmm_fb_be_math(p) ? cfb_tab8_be : cfb_tab8_le; break; case 16: tab = vmm_fb_be_math(p) ? cfb_tab16_be : cfb_tab16_le; break; case 32: default: tab = cfb_tab32; break; } for (i = ppw-1; i--; ) { fgx <<= bpp; bgx <<= bpp; fgx |= fgcolor; bgx |= bgcolor; } bit_mask = (1 << ppw) - 1; eorx = fgx ^ bgx; k = udiv32(image->width, ppw); for (i = image->height; i--; ) { dst = (u32 *) dst1, shift = 8; src = s; for (j = k; j--; ) { shift -= ppw; end_mask = tab[(*src >> shift) & bit_mask]; FB_WRITEL((end_mask & eorx)^bgx, dst++); if (!shift) { shift = 8; src++; } } dst1 += p->fix.line_length; s += spitch; } }
/* returns hperiod * 1000 */ static u32 vmm_fb_cvt_hperiod(struct vmm_fb_cvt_data *cvt) { u32 num = udiv32(1000000000, cvt->f_refresh); u32 den; if (cvt->flags & FB_CVT_FLAG_REDUCED_BLANK) { num -= FB_CVT_RB_MIN_VBLANK * 1000; den = 2 * (udiv32(cvt->yres, cvt->interlace) + 2 * cvt->v_margin); } else { num -= FB_CVT_MIN_VSYNC_BP * 1000; den = 2 * (udiv32(cvt->yres, cvt->interlace) + cvt->v_margin * 2 + FB_CVT_MIN_VPORCH + cvt->interlace/2); } return 2 * udiv32(num, den); }
void uart_lowlevel_init(virtual_addr_t base, u32 reg_align, u32 baudrate, u32 input_clock) { u16 bdiv; bdiv = udiv32(input_clock, (16 * baudrate)); /* set DLAB bit */ vmm_out_8((u8 *)REG_UART_LCR(base,reg_align), 0x80); /* set baudrate divisor */ vmm_out_8((u8 *)REG_UART_DLL(base,reg_align), bdiv & 0xFF); /* set baudrate divisor */ vmm_out_8((u8 *)REG_UART_DLM(base,reg_align), (bdiv >> 8) & 0xFF); /* clear DLAB; set 8 bits, no parity */ vmm_out_8((u8 *)REG_UART_LCR(base,reg_align), 0x03); /* disable FIFO */ vmm_out_8((u8 *)REG_UART_FCR(base,reg_align), 0x01); /* no modem control DTR RTS */ vmm_out_8((u8 *)REG_UART_MCR(base,reg_align), 0x00); /* clear line status */ vmm_in_8((u8 *)REG_UART_LSR(base,reg_align)); /* read receive buffer */ vmm_in_8((u8 *)REG_UART_RBR(base,reg_align)); /* set scratchpad */ vmm_out_8((u8 *)REG_UART_SCR(base,reg_align), 0x00); /* set interrupt enable reg */ vmm_out_8((u8 *)REG_UART_IER(base,reg_align), 0x0F); }
void omap_uart_lowlevel_init(virtual_addr_t base, u32 reg_align, u32 baudrate, u32 input_clock) { u16 bdiv; bdiv = udiv32(input_clock, (16 * baudrate)); /* clear interrupt enable reg */ omap_serial_out(UART_IER, 0); /* set mode select to disabled before dll/dlh */ omap_serial_out(UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE); omap_serial_out(UART_LCR, UART_LCR_CONF_MODE_A); omap_serial_out(UART_DLL, 0); omap_serial_out(UART_DLM, 0); omap_serial_out(UART_LCR, 0); /* no modem control DTR RTS */ omap_serial_out(UART_MCR, 0); /* enable FIFO */ omap_serial_out(UART_FCR, UART_FCR_R_TRIG_00 | UART_FCR_T_TRIG_00 | \ UART_FCR_CLEAR_XMIT | UART_FCR_CLEAR_RCVR | UART_FCR_ENABLE_FIFO); /* set baudrate divisor */ omap_serial_out(UART_LCR, UART_LCR_CONF_MODE_B); omap_serial_out(UART_DLL, bdiv & 0xFF); omap_serial_out(UART_DLM, (bdiv >> 8) & 0xFF); omap_serial_out(UART_LCR, UART_LCR_WLEN8); /* set mode select to 16x mode */ omap_serial_out(UART_OMAP_MDR1, UART_OMAP_MDR1_16X_MODE); }
static int cmd_host_cpu_info(struct vmm_chardev *cdev) { int rc; u32 c, khz; unsigned long hwid; char name[25]; vmm_cprintf(cdev, "%-25s: %s\n", "CPU Type", CONFIG_CPU); vmm_cprintf(cdev, "%-25s: %d\n", "CPU Present Count", vmm_num_present_cpus()); vmm_cprintf(cdev, "%-25s: %d\n", "CPU Possible Count", vmm_num_possible_cpus()); vmm_cprintf(cdev, "%-25s: %u\n", "CPU Online Count", vmm_num_online_cpus()); vmm_cprintf(cdev, "\n"); for_each_online_cpu(c) { rc = vmm_smp_map_hwid(c, &hwid); if (rc) return rc; vmm_sprintf(name, "CPU%d Hardware ID", c); vmm_cprintf(cdev, "%-25s: 0x%lx\n", name, hwid); vmm_sprintf(name, "CPU%d Estimated Speed", c); khz = vmm_delay_estimate_cpu_khz(c); vmm_cprintf(cdev, "%-25s: %d.%03d MHz\n", name, udiv32(khz, 1000), umod32(khz, 1000)); } vmm_cprintf(cdev, "\n"); arch_cpu_print_info(cdev); return VMM_OK; }
static int imx_pwm_config_v1(struct pwm_chip *chip, struct pwm_device *pwm, int duty_ns, int period_ns) { struct imx_chip *imx = to_imx_chip(chip); /* * The PWM subsystem allows for exact frequencies. However, * I cannot connect a scope on my device to the PWM line and * thus cannot provide the program the PWM controller * exactly. Instead, I'm relying on the fact that the * Bootloader (u-boot or WinCE+haret) has programmed the PWM * function group already. So I'll just modify the PWM sample * register to follow the ratio of duty_ns vs. period_ns * accordingly. * * This is good enough for programming the brightness of * the LCD backlight. * * The real implementation would divide PERCLK[0] first by * both the prescaler (/1 .. /128) and then by CLKSEL * (/2 .. /16). */ u32 max = readl(imx->mmio_base + MX1_PWMP); u32 p = udiv32(max * duty_ns, period_ns); writel(max - p, imx->mmio_base + MX1_PWMS); return 0; }
void uart_8250_lowlevel_init(struct uart_8250_port *port) { u16 bdiv; bdiv = udiv32(port->input_clock, (16 * port->baudrate)); /* set DLAB bit */ uart_8250_out(port, UART_LCR_OFFSET, 0x80); /* set baudrate divisor */ uart_8250_out(port, UART_DLL_OFFSET, bdiv & 0xFF); /* set baudrate divisor */ uart_8250_out(port, UART_DLM_OFFSET, (bdiv >> 8) & 0xFF); /* clear DLAB; set 8 bits, no parity */ uart_8250_out(port, UART_LCR_OFFSET, 0x03); /* enable FIFO */ uart_8250_out(port, UART_FCR_OFFSET, 0x01); /* no modem control DTR RTS */ uart_8250_out(port, UART_MCR_OFFSET, 0x00); /* clear line status */ uart_8250_in(port, UART_LSR_OFFSET); /* read receive buffer */ uart_8250_in(port, UART_RBR_OFFSET); /* set scratchpad */ uart_8250_out(port, UART_SCR_OFFSET, 0x00); /* set interrupt enable reg */ port->ier = 0x00; uart_8250_out(port, UART_IER_OFFSET, 0x00); }
static u32 vmm_fb_cvt_vtotal(struct vmm_fb_cvt_data *cvt) { u32 vtotal = udiv32(cvt->yres, cvt->interlace); vtotal += 2 * cvt->v_margin + cvt->interlace/2 + vmm_fb_cvt_vbi_lines(cvt); vtotal |= cvt->interlace/2; return vtotal; }
static void cmd_host_cpu_stats(struct vmm_chardev *cdev) { u32 c, p, khz, util; vmm_cprintf(cdev, "----------------------------------------" "-------------------------\n"); vmm_cprintf(cdev, " %4s %15s %13s %12s %16s\n", "CPU#", "Speed (MHz)", "Util. (%)", "IRQs (%)", "Active VCPUs"); vmm_cprintf(cdev, "----------------------------------------" "-------------------------\n"); for_each_online_cpu(c) { vmm_cprintf(cdev, " %4d", c); khz = vmm_delay_estimate_cpu_khz(c); vmm_cprintf(cdev, " %11d.%03d", udiv32(khz, 1000), umod32(khz, 1000)); util = udiv64(vmm_scheduler_idle_time(c) * 1000, vmm_scheduler_get_sample_period(c)); util = (util > 1000) ? 1000 : util; util = 1000 - util; vmm_cprintf(cdev, " %11d.%01d", udiv32(util, 10), umod32(util, 10)); util = udiv64(vmm_scheduler_irq_time(c) * 1000, vmm_scheduler_get_sample_period(c)); util = (util > 1000) ? 1000 : util; vmm_cprintf(cdev, " %10d.%01d", udiv32(util, 10), umod32(util, 10)); util = 1; for (p = VMM_VCPU_MIN_PRIORITY; p <= VMM_VCPU_MAX_PRIORITY; p++) { util += vmm_scheduler_ready_count(c, p); } vmm_cprintf(cdev, " %15d ", util); vmm_cprintf(cdev, "\n"); } vmm_cprintf(cdev, "----------------------------------------" "-------------------------\n"); }
void imx_lowlevel_init(virtual_addr_t base, u32 baudrate, u32 input_clock) { unsigned int temp = vmm_readl((void *)(base + UCR1)); #if 0 unsigned int divider; unsigned int remainder; #endif /* First, disable everything */ temp &= ~UCR1_UARTEN; vmm_writel(temp, (void *)base + UCR1); #if 0 /* * Set baud rate * * UBRDIV = (UART_CLK / (16 * BAUD_RATE)) - 1 * DIVSLOT = MOD(UART_CLK / BAUD_RATE, 16) */ temp = udiv32(input_clock, baudrate); divider = udiv32(temp, 16) - 1; remainder = umod32(temp, 16); vmm_out_le16((void *)(base + S3C2410_UBRDIV), (u16) divider); vmm_out_8((void *)(base + S3C2443_DIVSLOT), (u8) remainder); /* Set the UART to be 8 bits, 1 stop bit, no parity */ vmm_out_le32((void *)(base + S3C2410_ULCON), S3C2410_LCON_CS8 | S3C2410_LCON_PNONE); /* enable FIFO, set RX and TX trigger */ vmm_out_le32((void *)(base + S3C2410_UFCON), S3C2410_UFCON_DEFAULT); #else /* enable the UART */ temp |= UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN; vmm_writel(temp, (void *)(base + UCR1)); #endif }
/** * Convert vmm_fb_var_screeninfo to vmm_fb_videomode * @mode: pointer to struct fb_videomode * @var: pointer to struct fb_var_screeninfo */ void vmm_fb_var_to_videomode(struct vmm_fb_videomode *mode, const struct vmm_fb_var_screeninfo *var) { u32 pixclock, hfreq, htotal, vtotal; mode->name = NULL; mode->xres = var->xres; mode->yres = var->yres; mode->pixclock = var->pixclock; mode->hsync_len = var->hsync_len; mode->vsync_len = var->vsync_len; mode->left_margin = var->left_margin; mode->right_margin = var->right_margin; mode->upper_margin = var->upper_margin; mode->lower_margin = var->lower_margin; mode->sync = var->sync; mode->vmode = var->vmode & FB_VMODE_MASK; mode->flag = FB_MODE_IS_FROM_VAR; mode->refresh = 0; if (!var->pixclock) return; pixclock = PICOS2KHZ(var->pixclock) * 1000; htotal = var->xres + var->right_margin + var->hsync_len + var->left_margin; vtotal = var->yres + var->lower_margin + var->vsync_len + var->upper_margin; if (var->vmode & FB_VMODE_INTERLACED) vtotal /= 2; if (var->vmode & FB_VMODE_DOUBLE) vtotal *= 2; hfreq = udiv32(pixclock, htotal); mode->refresh = udiv32(hfreq, vtotal); }
static u32 vmm_fb_cvt_vbi_lines(struct vmm_fb_cvt_data *cvt) { u32 vbi_lines, min_vbi_lines, act_vbi_lines; if (cvt->flags & FB_CVT_FLAG_REDUCED_BLANK) { vbi_lines = udiv32((1000 * FB_CVT_RB_MIN_VBLANK), cvt->hperiod) + 1; min_vbi_lines = FB_CVT_RB_V_FPORCH + cvt->vsync + FB_CVT_MIN_BPORCH; } else { vbi_lines = udiv32((FB_CVT_MIN_VSYNC_BP * 1000), cvt->hperiod) + 1 + FB_CVT_MIN_VPORCH; min_vbi_lines = cvt->vsync + FB_CVT_MIN_BPORCH + FB_CVT_MIN_VPORCH; } if (vbi_lines < min_vbi_lines) act_vbi_lines = min_vbi_lines; else act_vbi_lines = vbi_lines; return act_vbi_lines; }
static u32 vmm_fb_cvt_pixclock(struct vmm_fb_cvt_data *cvt) { u32 pixclock; if (cvt->flags & FB_CVT_FLAG_REDUCED_BLANK) pixclock = (cvt->f_refresh * cvt->vtotal * cvt->htotal)/1000; else pixclock = udiv32((cvt->htotal * 1000000), cvt->hperiod); pixclock /= 250; pixclock *= 250; pixclock *= 1000; return pixclock; }
static u32 __fatfs_control_write_fat_cache(struct fatfs_control *ctrl, u8 *buf, u32 pos) { int rc, index, cache_buf_index; u32 ret, sect_num, sect_off; if ((ctrl->sectors_per_fat * ctrl->bytes_per_sector) <= pos) { return 0; } sect_num = udiv32(pos, ctrl->bytes_per_sector); sect_off = pos - (sect_num * ctrl->bytes_per_sector); rc = __fatfs_control_load_fat_cache(ctrl, sect_num); if (rc) { return 0; } index = __fatfs_control_find_fat_cache(ctrl, sect_num); if (index < 0) { return 0; } cache_buf_index = (index * ctrl->bytes_per_sector) + sect_off; switch (ctrl->type) { case FAT_TYPE_12: case FAT_TYPE_16: ret = 2; ctrl->fat_cache_buf[cache_buf_index + 0] = buf[0]; ctrl->fat_cache_buf[cache_buf_index + 1] = buf[1]; break; case FAT_TYPE_32: ret = 4; ctrl->fat_cache_buf[cache_buf_index + 0] = buf[0]; ctrl->fat_cache_buf[cache_buf_index + 1] = buf[1]; ctrl->fat_cache_buf[cache_buf_index + 2] = buf[2]; ctrl->fat_cache_buf[cache_buf_index + 3] = buf[3]; break; default: ret = 0; break; }; ctrl->fat_cache_dirty[index] = TRUE; return ret; }
/* Must be called with sp805->lock held */ static int _sp805_counter_reload(struct sp805_state *sp805) { int rc = VMM_OK; u64 reload = (sp805->load + 1) * 1000; if (!_sp805_enabled(sp805)) { sp805_debug(sp805, "Disabled, event not started.\n"); return VMM_OK; } sp805->timestamp = vmm_timer_timestamp(); vmm_timer_event_stop(&sp805->event); rc = vmm_timer_event_start(&sp805->event, reload); sp805_debug(sp805, "Counter started: IRQ in %d ms (%d)\n", udiv32(sp805->load + 1, 1000), rc); return rc; }
static void cmd_host_cpu_info(struct vmm_chardev *cdev) { u32 c, khz; char name[25]; vmm_cprintf(cdev, "%-25s: %s\n", "CPU Type", CONFIG_CPU); vmm_cprintf(cdev, "%-25s: %d\n", "CPU Present Count", vmm_num_present_cpus()); vmm_cprintf(cdev, "%-25s: %d\n", "CPU Possible Count", vmm_num_possible_cpus()); vmm_cprintf(cdev, "%-25s: %u\n", "CPU Online Count", vmm_num_online_cpus()); for_each_online_cpu(c) { khz = vmm_delay_estimate_cpu_khz(c); vmm_sprintf(name, "CPU%d Speed", c); vmm_cprintf(cdev, "%-25s: %d.%d MHz (Estimated)\n", name, udiv32(khz, 1000), umod32(khz, 1000)); } arch_cpu_print_info(cdev); }
static int imx_pwm_config_v2(struct pwm_chip *chip, struct pwm_device *pwm, int duty_ns, int period_ns) { struct imx_chip *imx = to_imx_chip(chip); unsigned long long c; unsigned long period_cycles, duty_cycles, prescale; u32 cr; c = clk_get_rate(imx->clk_per); c = c * period_ns; c = udiv64(c, 1000000000); period_cycles = c; prescale = period_cycles / 0x10000 + 1; period_cycles = udiv32(period_cycles, prescale); c = (unsigned long long)period_cycles * duty_ns; c = udiv64(c, period_ns); duty_cycles = c; /* * according to imx pwm RM, the real period value should be * PERIOD value in PWMPR plus 2. */ if (period_cycles > 2) period_cycles -= 2; else period_cycles = 0; writel(duty_cycles, imx->mmio_base + MX3_PWMSAR); writel(period_cycles, imx->mmio_base + MX3_PWMPR); cr = MX3_PWMCR_PRESCALER(prescale) | MX3_PWMCR_DOZEEN | MX3_PWMCR_WAITEN | MX3_PWMCR_DBGEN | MX3_PWMCR_CLKSRC_IPG_HIGH; if (test_bit(PWMF_ENABLED, &pwm->flags)) cr |= MX3_PWMCR_EN; writel(cr, imx->mmio_base + MX3_PWMCR); return 0; }
void vmm_cfb_imageblit(struct vmm_fb_info *p, const struct vmm_fb_image *image) { u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0; u32 bpl = sizeof(u32), bpp = p->var.bits_per_pixel; u32 width = image->width; u32 dx = image->dx, dy = image->dy; u8 *dst1; if (p->state != FBINFO_STATE_RUNNING) return; bitstart = (dy * p->fix.line_length * 8) + (dx * bpp); start_index = bitstart & (32 - 1); pitch_index = (p->fix.line_length & (bpl - 1)) * 8; bitstart /= 8; bitstart &= ~(bpl - 1); dst1 = (u8 *)(p->screen_base + bitstart); if (p->fbops->fb_sync) p->fbops->fb_sync(p); if (image->depth == 1) { if (p->fix.visual == FB_VISUAL_TRUECOLOR || p->fix.visual == FB_VISUAL_DIRECTCOLOR) { fgcolor = ((u32*)(p->pseudo_palette))[image->fg_color]; bgcolor = ((u32*)(p->pseudo_palette))[image->bg_color]; } else { fgcolor = image->fg_color; bgcolor = image->bg_color; } if (umod32(32, bpp) == 0 && !start_index && !pitch_index && ((width & (udiv32(32,bpp)-1)) == 0) && bpp >= 8 && bpp <= 32) fast_imageblit(image, p, dst1, fgcolor, bgcolor); else slow_imageblit(image, p, dst1, fgcolor, bgcolor, start_index, pitch_index); } else color_imageblit(image, p, dst1, start_index, pitch_index); }
static int s3c_rtc_setfreq(struct rtc_device *rtc_dev, int freq) { //struct platform_device *pdev = to_platform_device(dev); //struct rtc_device *rtc_dev = platform_get_drvdata(pdev); unsigned int tmp = 0; int val; if (!is_power_of_2(freq)) { return -EINVAL; } clk_enable(rtc_clk); spin_lock_irq(&s3c_rtc_pie_lock); if (s3c_rtc_cpu_type != TYPE_S3C64XX) { tmp = readb(s3c_rtc_base + S3C2410_TICNT); tmp &= S3C2410_TICNT_ENABLE; } //val = (rtc_dev->max_user_freq / freq) - 1; val = udiv32(max_user_freq, freq) - 1; if (s3c_rtc_cpu_type == TYPE_S3C2416 || s3c_rtc_cpu_type == TYPE_S3C2443) { tmp |= S3C2443_TICNT_PART(val); writel(S3C2443_TICNT1_PART(val), s3c_rtc_base + S3C2443_TICNT1); if (s3c_rtc_cpu_type == TYPE_S3C2416) writel(S3C2416_TICNT2_PART(val), s3c_rtc_base + S3C2416_TICNT2); } else { tmp |= val; } writel(tmp, s3c_rtc_base + S3C2410_TICNT); spin_unlock_irq(&s3c_rtc_pie_lock); clk_disable(rtc_clk); return 0; }
static u32 vmm_fb_cvt_hblank(struct vmm_fb_cvt_data *cvt) { u32 hblank = 0; if (cvt->flags & FB_CVT_FLAG_REDUCED_BLANK) hblank = FB_CVT_RB_HBLANK; else { u32 ideal_duty_cycle = vmm_fb_cvt_ideal_duty_cycle(cvt); u32 active_pixels = cvt->active_pixels; if (ideal_duty_cycle < 20000) hblank = (active_pixels * 20000)/ (100000 - 20000); else { hblank = udiv32((active_pixels * ideal_duty_cycle), (100000 - ideal_duty_cycle)); } } hblank &= ~((2 * FB_CVT_CELLSIZE) - 1); return hblank; }
static void virtio_blk_do_io(struct virtio_device *dev, struct virtio_blk_dev *bdev) { u16 head; u32 i, iov_cnt, len; irq_flags_t flags; struct virtio_queue *vq = &bdev->vqs[VIRTIO_BLK_IO_QUEUE]; struct virtio_blk_dev_req *req; struct virtio_blk_outhdr hdr; struct vmm_blockdev *blk; while (virtio_queue_available(vq)) { head = virtio_queue_pop(vq); req = &bdev->reqs[head]; head = virtio_queue_get_head_iovec(vq, head, bdev->iov, &iov_cnt, &len); req->vq = vq; req->bdev = bdev; req->head = head; req->read_iov = NULL; req->read_iov_cnt = 0; req->len = 0; for (i = 1; i < (iov_cnt - 1); i++) { req->len += bdev->iov[i].len; } req->status_iov.addr = bdev->iov[iov_cnt - 1].addr; req->status_iov.len = bdev->iov[iov_cnt - 1].len; req->r.type = VMM_REQUEST_UNKNOWN; req->r.lba = 0; req->r.bcnt = 0; req->r.data = NULL; req->r.completed = virtio_blk_req_completed; req->r.failed = virtio_blk_req_failed; req->r.priv = req; len = virtio_iovec_to_buf_read(dev, &bdev->iov[0], 1, &hdr, sizeof(hdr)); if (len < sizeof(hdr)) { virtio_queue_set_used_elem(req->vq, req->head, 0); continue; } switch (hdr.type) { case VIRTIO_BLK_T_IN: req->r.type = VMM_REQUEST_READ; req->r.lba = hdr.sector; req->r.bcnt = udiv32(req->len, bdev->config.blk_size); req->r.data = vmm_malloc(req->len); if (!req->r.data) { virtio_blk_req_done(req, VIRTIO_BLK_S_IOERR); continue; } len = sizeof(struct virtio_iovec) * (iov_cnt - 2); req->read_iov = vmm_malloc(len); if (!req->read_iov) { virtio_blk_req_done(req, VIRTIO_BLK_S_IOERR); continue; } req->read_iov_cnt = iov_cnt - 2; for (i = 0; i < req->read_iov_cnt; i++) { req->read_iov[i].addr = bdev->iov[i + 1].addr; req->read_iov[i].len = bdev->iov[i + 1].len; } vmm_spin_lock_irqsave(&bdev->blk_lock, flags); blk = bdev->blk; vmm_spin_unlock_irqrestore(&bdev->blk_lock, flags); /* Note: We will get failed() or complete() callback * even if blk == NULL */ vmm_blockdev_submit_request(blk, &req->r); break; case VIRTIO_BLK_T_OUT: req->r.type = VMM_REQUEST_WRITE; req->r.lba = hdr.sector; req->r.bcnt = udiv32(req->len, bdev->config.blk_size); req->r.data = vmm_malloc(req->len); if (!req->r.data) { virtio_blk_req_done(req, VIRTIO_BLK_S_IOERR); continue; } else { virtio_iovec_to_buf_read(dev, &bdev->iov[1], iov_cnt - 2, req->r.data, req->len); } vmm_spin_lock_irqsave(&bdev->blk_lock, flags); blk = bdev->blk; vmm_spin_unlock_irqrestore(&bdev->blk_lock, flags); /* Note: We will get failed() or complete() callback * even if blk == NULL */ vmm_blockdev_submit_request(blk, &req->r); break; case VIRTIO_BLK_T_FLUSH: req->r.type = VMM_REQUEST_WRITE; req->r.lba = 0; req->r.bcnt = 0; req->r.data = NULL; vmm_spin_lock_irqsave(&bdev->blk_lock, flags); blk = bdev->blk; vmm_spin_unlock_irqrestore(&bdev->blk_lock, flags); if (vmm_blockdev_flush_cache(blk)) { virtio_blk_req_done(req, VIRTIO_BLK_S_IOERR); } else { virtio_blk_req_done(req, VIRTIO_BLK_S_OK); } break; case VIRTIO_BLK_T_GET_ID: req->len = VIRTIO_BLK_ID_BYTES; req->r.type = VMM_REQUEST_READ; req->r.lba = 0; req->r.bcnt = 0; req->r.data = vmm_zalloc(req->len); if (!req->r.data) { virtio_blk_req_done(req, VIRTIO_BLK_S_IOERR); continue; } req->read_iov = vmm_malloc(sizeof(struct virtio_iovec)); if (!req->read_iov) { virtio_blk_req_done(req, VIRTIO_BLK_S_IOERR); continue; } req->read_iov_cnt = 1; req->read_iov[0].addr = bdev->iov[1].addr; req->read_iov[0].len = bdev->iov[1].len; strncpy(req->r.data, bdev->blk_name, req->len); virtio_blk_req_done(req, VIRTIO_BLK_S_OK); break; default: break; }; } }