Example #1
0
/*!
 * @brief Enable LCD controller.
 * @param info	framebuffer information pointer
 */
static void _enable_lcdc(struct fb_info *info)
{
	static int first_enable = 1;
	struct mx2fb_info *mx2fbi = (struct mx2fb_info *)info->par;

	/*
	 * Graphic window can only be enabled while the HCLK to the LCDC
	 * is disabled. Once enabled it can subsequently be disabled and
	 * enabled without turning off the HCLK.
	 * The graphic window is enabled and then disabled here. So next
	 * time to enable graphic window the HCLK to LCDC does not need
	 * to be disabled, and the flicker (due to disabling of HCLK to
	 * LCDC) is avoided.
	 */
	if (first_enable) {
		_enable_graphic_window(info);
		_disable_graphic_window(info);
		first_enable = 0;
	}

	if (mx2fbi->type == MX2FB_TYPE_GW)
		_enable_graphic_window(info);
	else if (!fb_enabled) {
		clk_enable(lcdc_clk);
		gpio_lcdc_active();
		board_power_lcd(1);
		_set_brightness(brightness);
		fb_enabled++;
#ifdef CONFIG_FB_MXC_TVOUT
		if (fb_mode) {
			unsigned long mode = 0;

			if (strcmp(fb_mode, MODE_VGA) == 0)
				mode = VIDEO_ENCODER_VGA;
			else if (strcmp(fb_mode, MODE_NTSC) == 0)
				mode = VIDEO_ENCODER_NTSC;
			else if (strcmp(fb_mode, MODE_PAL) == 0)
				mode = VIDEO_ENCODER_PAL;
			if (mode)
				fs453_ioctl(ENCODER_SET_NORM, &mode);
		}
#endif
	}
}
Example #2
0
/*!
 * @brief Ioctl function to support customized ioctl operations.
 *
 * @param info	Framebuffer structure that represents a single frame buffer
 * @param cmd	The command number
 * @param arg	Argument which depends on cmd
 *
 * @return	Negative errno on error, or zero on success.
 */
static int mx2fb_ioctl(struct fb_info *info, unsigned int cmd,
		       unsigned long arg)
{
	struct mx2fb_info *mx2fbi = (struct mx2fb_info *)info->par;
	struct mx2fb_gbl_alpha ga;
	struct mx2fb_color_key ck;

	switch (cmd) {
	case MX2FB_SET_GBL_ALPHA:
		if (mx2fbi->type != MX2FB_TYPE_GW)
			return -ENODEV;

		if (!arg)
			return -EINVAL;

		/* set graphic window information */
		if (copy_from_user((void *)&ga, (void *)arg, sizeof(ga)))
			return -EFAULT;

		g_gwinfo.alpha_value = ga.alpha;

		if (g_gwinfo.enabled)
			_enable_graphic_window(info);
		else
			_disable_graphic_window(info);
		break;
	case MX2FB_SET_CLR_KEY:
		if (mx2fbi->type != MX2FB_TYPE_GW)
			return -ENODEV;

		if (!arg)
			return -EINVAL;

		/* set graphic window information */
		if (copy_from_user((void *)&ck, (void *)arg, sizeof(ck)))
			return -EFAULT;

		g_gwinfo.ck_enabled = ck.enable;
		g_gwinfo.ck_red = (ck.color_key & 0x003F0000) >> 16;
		g_gwinfo.ck_green = (ck.color_key & 0x00003F00) >> 8;
		g_gwinfo.ck_blue = ck.color_key & 0x0000003F;

		if (g_gwinfo.enabled)
			_enable_graphic_window(info);
		else
			_disable_graphic_window(info);
		break;
	case FBIOGET_GWINFO:
		if (mx2fbi->type != MX2FB_TYPE_GW)
			return -ENODEV;

		if (!arg)
			return -EINVAL;

		/* get graphic window information */
		if (copy_to_user((void *)arg, (void *)&g_gwinfo,
				 sizeof(g_gwinfo)))
			return -EFAULT;
		break;
	case FBIOPUT_GWINFO:
		if (mx2fbi->type != MX2FB_TYPE_GW)
			return -ENODEV;

		if (!arg)
			return -EINVAL;

		/* set graphic window information */
		if (copy_from_user((void *)&g_gwinfo, (void *)arg,
				   sizeof(g_gwinfo)))
			return -EFAULT;

		if (g_gwinfo.enabled)
			_enable_graphic_window(info);
		else
			_disable_graphic_window(info);
		break;
#ifdef CONFIG_FB_MXC_TVOUT
	case ENCODER_GET_CAPABILITIES:{
			int ret;
			struct video_encoder_capability cap;

			if (mx2fbi->type != MX2FB_TYPE_BG)
				return -ENODEV;

			ret = fs453_ioctl(cmd, &cap);
			if (ret)
				return ret;

			if (copy_to_user((void *)arg, &cap, sizeof(cap)))
				return -EFAULT;
			break;
		}
	case ENCODER_SET_NORM:{
			int ret;
			unsigned long mode;
			char *smode;
			struct fb_var_screeninfo var;

			if (mx2fbi->type != MX2FB_TYPE_BG)
				return -ENODEV;

			if (copy_from_user(&mode, (void *)arg, sizeof(mode)))
				return -EFAULT;
			if ((ret = fs453_ioctl(cmd, &mode)))
				return ret;

			if (mode == VIDEO_ENCODER_PAL)
				smode = MODE_PAL;
			else if (mode == VIDEO_ENCODER_NTSC)
				smode = MODE_NTSC;
			else
				smode = MODE_VGA;

			var = info->var;
			var.nonstd = 0;
			ret = fb_find_mode(&var, info, smode, mxcfb_modedb,
					   mxcfb_modedb_sz, NULL, default_bpp);
			if ((ret != 1) && (ret != 2))	/* specified mode not found */
				return -ENODEV;

			info->var = var;
			fb_mode = smode;
			return mx2fb_set_par(info);
		}
	case ENCODER_SET_INPUT:
	case ENCODER_SET_OUTPUT:
	case ENCODER_ENABLE_OUTPUT:{
			unsigned long varg;

			if (mx2fbi->type != MX2FB_TYPE_BG)
				return -ENODEV;

			if (copy_from_user(&varg, (void *)arg, sizeof(varg)))
				return -EFAULT;
			return fs453_ioctl(cmd, &varg);
		}
#endif
	default:
		dev_dbg(info->device, "Unknown ioctl command (0x%08X)\n", cmd);
		return -EINVAL;
	}

	return 0;
}
Example #3
0
/*!
 * @brief Update LCDC registers
 * @param info	framebuffer information pointer
 */
static void _update_lcdc(struct fb_info *info)
{
	unsigned long base;
	unsigned long perclk3, pcd, pcr;
	struct fb_var_screeninfo *var = &info->var;
	struct mx2fb_info *mx2fbi = (struct mx2fb_info *)info->par;

	if (mx2fbi->type == MX2FB_TYPE_GW) {
		_enable_graphic_window(info);
		return;
	}

	base = (var->yoffset * var->xres_virtual + var->xoffset);
	base *= (var->bits_per_pixel) / 8;
	base += info->fix.smem_start;

	/* Screen start address register */
	__raw_writel(base, LCDC_REG(LCDC_LSSAR));

	/* Size register */
	dev_dbg(info->device, "xres = %d, yres = %d\n",
		info->var.xres, info->var.yres);
	__raw_writel(((info->var.xres >> 4) << 20) + info->var.yres,
		     LCDC_REG(LCDC_LSR));

	/* Virtual page width register */
	__raw_writel(info->var.xres_virtual >> 1, LCDC_REG(LCDC_LVPWR));

	/* To setup LCDC pixel clock */
	perclk3 = clk_round_rate(lcdc_clk, 134000000);
	if (clk_set_rate(lcdc_clk, perclk3)) {
		printk(KERN_INFO "mx2fb: Unable to set clock to %lu\n",
		       perclk3);
		perclk3 = clk_get_rate(lcdc_clk);
	}

	/* Calculate pixel clock divider, and round to the nearest integer */
	pcd = (perclk3 * 8 / (PICOS2KHZ(var->pixclock) * 1000UL) + 4) / 8;
	if (--pcd > 0x3F)
		pcd = 0x3F;

	/* Panel configuration register */
	pcr = 0xFA008B80 | pcd;
	pcr |= (var->sync & FB_SYNC_CLK_INVERT) ? 0x01000000 : 0;
	pcr |= (var->sync & FB_SYNC_SHARP_MODE) ? 0x00000040 : 0;
	pcr |= (var->sync & FB_SYNC_OE_ACT_HIGH) ? 0 : 0x00100000;
	__raw_writel(pcr, LCDC_REG(LCDC_LPCR));

	/* Horizontal and vertical configuration register */
	__raw_writel(((var->hsync_len - 1) << 26)
		     + ((var->right_margin - 1) << 8)
		     + (var->left_margin - 3), LCDC_REG(LCDC_LHCR));
	__raw_writel((var->vsync_len << 26)
		     + (var->lower_margin << 8)
		     + var->upper_margin, LCDC_REG(LCDC_LVCR));

	/* Sharp configuration register */
	__raw_writel(0x00120300, LCDC_REG(LCDC_LSCR));

	/* Refresh mode control reigster */
	__raw_writel(0x00000000, LCDC_REG(LCDC_LRMCR));

	/* DMA control register */
	if (cpu_is_mx27_rev(CHIP_REV_2_0) > 0)
		__raw_writel(0x00040060, LCDC_REG(LCDC_LDCR));
	else
		__raw_writel(0x00020010, LCDC_REG(LCDC_LDCR));
}