Beispiel #1
0
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);
}
Beispiel #3
0
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);
}
Beispiel #4
0
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);
}
Beispiel #5
0
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;
}
Beispiel #6
0
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));
}
Beispiel #7
0
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;
}
Beispiel #8
0
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;
}
Beispiel #9
0
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);
}
Beispiel #10
0
/*
 * 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;
	}
}	
Beispiel #11
0
/* 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);
}
Beispiel #12
0
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);
}
Beispiel #13
0
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);
}
Beispiel #14
0
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;
}
Beispiel #15
0
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;
}
Beispiel #16
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);
}
Beispiel #17
0
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;
}
Beispiel #18
0
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");
}
Beispiel #19
0
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
}
Beispiel #20
0
/**
 * 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);
}
Beispiel #21
0
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;
}
Beispiel #22
0
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;
}
Beispiel #23
0
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;
}
Beispiel #24
0
/* 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;
}
Beispiel #25
0
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);
}
Beispiel #26
0
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;
}
Beispiel #27
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);
}
Beispiel #28
0
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;
}
Beispiel #29
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;
}
Beispiel #30
0
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;
		};
	}
}