diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-08-03 14:00:16 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-08-03 14:00:16 -0700 |
commit | 05119217a9bd199c4b8b12c01f86df09108b109b (patch) | |
tree | f74f4227e3a7610821c1243b4424f5769c88697b /drivers/video | |
parent | 45365a06aa305c9eca1cbf48aef48a7a0cea3b4e (diff) | |
parent | 3346dd99fb4cd174fdbfb68dc62cd109e4323f0f (diff) |
Merge tag 'rm-unicore32' of git://git.kernel.org/pub/scm/linux/kernel/git/rppt/linux
Pull unicore32 removal from Mike Rapoport:
"Remove unicore32 support.
The unicore32 port do not seem maintained for a long time now, there
is no upstream toolchain that can create unicore32 binaries and all
the links to prebuilt toolchains for unicore32 are dead. Even
compilers that were available are not supported by the kernel anymore.
Guenter Roeck says:
"I have stopped building unicore32 images since v4.19 since there is
no available compiler that is still supported by the kernel. I am
surprised that support for it has not been removed from the kernel"
However, it's worth pointing out two things:
- Guan Xuetao is still listed as maintainer and asked for the port to
be kept around the last time Arnd suggested removing it two years
ago. He promised that there would be compiler sources (presumably
llvm), but has not made those available since.
- https://github.com/gxt has patches to linux-4.9 and qemu-2.7, both
released in 2016, with patches dated early 2019. These patches
mainly restore a syscall ABI that was never part of mainline Linux
but apparently used in production. qemu-2.8 removed support for
that ABI and newer kernels (4.19+) can no longer be built with the
old toolchain, so apparently there will not be any future updates
to that git tree"
* tag 'rm-unicore32' of git://git.kernel.org/pub/scm/linux/kernel/git/rppt/linux:
MAINTAINERS: remove "PKUNITY SOC DRIVERS" entry
rtc: remove fb-puv3 driver
video: fbdev: remove fb-puv3 driver
pwm: remove pwm-puv3 driver
input: i8042: remove support for 8042-unicore32io
i2c/buses: remove i2c-puv3 driver
cpufreq: remove unicore32 driver
arch: remove unicore32 port
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/fbdev/Kconfig | 11 | ||||
-rw-r--r-- | drivers/video/fbdev/Makefile | 1 | ||||
-rw-r--r-- | drivers/video/fbdev/fb-puv3.c | 836 |
3 files changed, 0 insertions, 848 deletions
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 0f559aeaf469..32a2698914c3 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -2198,17 +2198,6 @@ config FB_BROADSHEET and could also have been called by other names when coupled with a bridge adapter. -config FB_PUV3_UNIGFX - tristate "PKUnity v3 Unigfx framebuffer support" - depends on FB && UNICORE32 && ARCH_PUV3 - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - select FB_SYS_FOPS - help - Choose this option if you want to use the Unigfx device as a - framebuffer device. Without the support of PCI & AGP. - config FB_HYPERV tristate "Microsoft Hyper-V Synthetic Video support" depends on FB && HYPERV diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile index aa6352798cf4..a0705b99e643 100644 --- a/drivers/video/fbdev/Makefile +++ b/drivers/video/fbdev/Makefile @@ -116,7 +116,6 @@ obj-y += omap2/ obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o obj-$(CONFIG_FB_CARMINE) += carminefb.o obj-$(CONFIG_FB_MB862XX) += mb862xx/ -obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o obj-$(CONFIG_FB_HYPERV) += hyperv_fb.o obj-$(CONFIG_FB_OPENCORES) += ocfb.o obj-$(CONFIG_FB_SM712) += sm712fb.o diff --git a/drivers/video/fbdev/fb-puv3.c b/drivers/video/fbdev/fb-puv3.c deleted file mode 100644 index 030e85c11a78..000000000000 --- a/drivers/video/fbdev/fb-puv3.c +++ /dev/null @@ -1,836 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Frame Buffer Driver for PKUnity-v3 Unigfx - * Code specific to PKUnity SoC and UniCore ISA - * - * Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn> - * Copyright (C) 2001-2010 Guan Xuetao - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/platform_device.h> -#include <linux/clk.h> -#include <linux/fb.h> -#include <linux/init.h> -#include <linux/console.h> -#include <linux/mm.h> - -#include <linux/sizes.h> -#include <mach/hardware.h> - -/* Platform_data reserved for unifb registers. */ -#define UNIFB_REGS_NUM 10 -/* RAM reserved for the frame buffer. */ -#define UNIFB_MEMSIZE (SZ_4M) /* 4 MB for 1024*768*32b */ - -/* - * cause UNIGFX don not have EDID - * all the modes are organized as follow - */ -static const struct fb_videomode unifb_modes[] = { - /* 0 640x480-60 VESA */ - { "640x480@60", 60, 640, 480, 25175000, 48, 16, 34, 10, 96, 1, - 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, - /* 1 640x480-75 VESA */ - { "640x480@75", 75, 640, 480, 31500000, 120, 16, 18, 1, 64, 1, - 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, - /* 2 800x600-60 VESA */ - { "800x600@60", 60, 800, 600, 40000000, 88, 40, 26, 1, 128, 1, - 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, - /* 3 800x600-75 VESA */ - { "800x600@75", 75, 800, 600, 49500000, 160, 16, 23, 1, 80, 1, - 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, - /* 4 1024x768-60 VESA */ - { "1024x768@60", 60, 1024, 768, 65000000, 160, 24, 34, 3, 136, 1, - 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, - /* 5 1024x768-75 VESA */ - { "1024x768@75", 75, 1024, 768, 78750000, 176, 16, 30, 1, 96, 1, - 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, - /* 6 1280x960-60 VESA */ - { "1280x960@60", 60, 1280, 960, 108000000, 312, 96, 38, 1, 112, 1, - 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, - /* 7 1440x900-60 VESA */ - { "1440x900@60", 60, 1440, 900, 106500000, 232, 80, 30, 3, 152, 1, - 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, - /* 8 FIXME 9 1024x600-60 VESA UNTESTED */ - { "1024x600@60", 60, 1024, 600, 50650000, 160, 24, 26, 1, 136, 1, - 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, - /* 9 FIXME 10 1024x600-75 VESA UNTESTED */ - { "1024x600@75", 75, 1024, 600, 61500000, 176, 16, 23, 1, 96, 1, - 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, - /* 10 FIXME 11 1366x768-60 VESA UNTESTED */ - { "1366x768@60", 60, 1366, 768, 85500000, 256, 58, 18, 1, 112, 3, - 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, -}; - -static const struct fb_var_screeninfo unifb_default = { - .xres = 640, - .yres = 480, - .xres_virtual = 640, - .yres_virtual = 480, - .bits_per_pixel = 16, - .red = { 11, 5, 0 }, - .green = { 5, 6, 0 }, - .blue = { 0, 5, 0 }, - .activate = FB_ACTIVATE_NOW, - .height = -1, - .width = -1, - .pixclock = 25175000, - .left_margin = 48, - .right_margin = 16, - .upper_margin = 33, - .lower_margin = 10, - .hsync_len = 96, - .vsync_len = 2, - .vmode = FB_VMODE_NONINTERLACED, -}; - -static struct fb_fix_screeninfo unifb_fix = { - .id = "UNIGFX FB", - .type = FB_TYPE_PACKED_PIXELS, - .visual = FB_VISUAL_TRUECOLOR, - .xpanstep = 1, - .ypanstep = 1, - .ywrapstep = 1, - .accel = FB_ACCEL_NONE, -}; - -static void unifb_sync(struct fb_info *info) -{ - /* TODO: may, this can be replaced by interrupt */ - int cnt; - - for (cnt = 0; cnt < 0x10000000; cnt++) { - if (readl(UGE_COMMAND) & 0x1000000) - return; - } - - if (cnt > 0x8000000) - dev_warn(info->device, "Warning: UniGFX GE time out ...\n"); -} - -static void unifb_prim_fillrect(struct fb_info *info, - const struct fb_fillrect *region) -{ - int awidth = region->width; - int aheight = region->height; - int m_iBpp = info->var.bits_per_pixel; - int screen_width = info->var.xres; - int src_sel = 1; /* from fg_color */ - int pat_sel = 1; - int src_x0 = 0; - int dst_x0 = region->dx; - int src_y0 = 0; - int dst_y0 = region->dy; - int rop_alpha_sel = 0; - int rop_alpha_code = 0xCC; - int x_dir = 1; - int y_dir = 1; - int alpha_r = 0; - int alpha_sel = 0; - int dst_pitch = screen_width * (m_iBpp / 8); - int dst_offset = dst_y0 * dst_pitch + dst_x0 * (m_iBpp / 8); - int src_pitch = screen_width * (m_iBpp / 8); - int src_offset = src_y0 * src_pitch + src_x0 * (m_iBpp / 8); - unsigned int command = 0; - int clip_region = 0; - int clip_en = 0; - int tp_en = 0; - int fg_color = 0; - int bottom = info->var.yres - 1; - int right = info->var.xres - 1; - int top = 0; - - bottom = (bottom << 16) | right; - command = (rop_alpha_sel << 26) | (pat_sel << 18) | (src_sel << 16) - | (x_dir << 20) | (y_dir << 21) | (command << 24) - | (clip_region << 23) | (clip_en << 22) | (tp_en << 27); - src_pitch = (dst_pitch << 16) | src_pitch; - awidth = awidth | (aheight << 16); - alpha_r = ((rop_alpha_code & 0xff) << 8) | (alpha_r & 0xff) - | (alpha_sel << 16); - src_x0 = (src_x0 & 0x1fff) | ((src_y0 & 0x1fff) << 16); - dst_x0 = (dst_x0 & 0x1fff) | ((dst_y0 & 0x1fff) << 16); - fg_color = region->color; - - unifb_sync(info); - - writel(((u32 *)(info->pseudo_palette))[fg_color], UGE_FCOLOR); - writel(0, UGE_BCOLOR); - writel(src_pitch, UGE_PITCH); - writel(src_offset, UGE_SRCSTART); - writel(dst_offset, UGE_DSTSTART); - writel(awidth, UGE_WIDHEIGHT); - writel(top, UGE_CLIP0); - writel(bottom, UGE_CLIP1); - writel(alpha_r, UGE_ROPALPHA); - writel(src_x0, UGE_SRCXY); - writel(dst_x0, UGE_DSTXY); - writel(command, UGE_COMMAND); -} - -static void unifb_fillrect(struct fb_info *info, - const struct fb_fillrect *region) -{ - struct fb_fillrect modded; - int vxres, vyres; - - if (info->flags & FBINFO_HWACCEL_DISABLED) { - sys_fillrect(info, region); - return; - } - - vxres = info->var.xres_virtual; - vyres = info->var.yres_virtual; - - memcpy(&modded, region, sizeof(struct fb_fillrect)); - - if (!modded.width || !modded.height || - modded.dx >= vxres || modded.dy >= vyres) - return; - - if (modded.dx + modded.width > vxres) - modded.width = vxres - modded.dx; - if (modded.dy + modded.height > vyres) - modded.height = vyres - modded.dy; - - unifb_prim_fillrect(info, &modded); -} - -static void unifb_prim_copyarea(struct fb_info *info, - const struct fb_copyarea *area) -{ - int awidth = area->width; - int aheight = area->height; - int m_iBpp = info->var.bits_per_pixel; - int screen_width = info->var.xres; - int src_sel = 2; /* from mem */ - int pat_sel = 0; - int src_x0 = area->sx; - int dst_x0 = area->dx; - int src_y0 = area->sy; - int dst_y0 = area->dy; - - int rop_alpha_sel = 0; - int rop_alpha_code = 0xCC; - int x_dir = 1; - int y_dir = 1; - - int alpha_r = 0; - int alpha_sel = 0; - int dst_pitch = screen_width * (m_iBpp / 8); - int dst_offset = dst_y0 * dst_pitch + dst_x0 * (m_iBpp / 8); - int src_pitch = screen_width * (m_iBpp / 8); - int src_offset = src_y0 * src_pitch + src_x0 * (m_iBpp / 8); - unsigned int command = 0; - int clip_region = 0; - int clip_en = 1; - int tp_en = 0; - int top = 0; - int bottom = info->var.yres; - int right = info->var.xres; - int fg_color = 0; - int bg_color = 0; - - if (src_x0 < 0) - src_x0 = 0; - if (src_y0 < 0) - src_y0 = 0; - - if (src_y0 - dst_y0 > 0) { - y_dir = 1; - } else { - y_dir = 0; - src_offset = (src_y0 + aheight) * src_pitch + - src_x0 * (m_iBpp / 8); - dst_offset = (dst_y0 + aheight) * dst_pitch + - dst_x0 * (m_iBpp / 8); - src_y0 += aheight; - dst_y0 += aheight; - } - - command = (rop_alpha_sel << 26) | (pat_sel << 18) | (src_sel << 16) | - (x_dir << 20) | (y_dir << 21) | (command << 24) | - (clip_region << 23) | (clip_en << 22) | (tp_en << 27); - src_pitch = (dst_pitch << 16) | src_pitch; - awidth = awidth | (aheight << 16); - alpha_r = ((rop_alpha_code & 0xff) << 8) | (alpha_r & 0xff) | - (alpha_sel << 16); - src_x0 = (src_x0 & 0x1fff) | ((src_y0 & 0x1fff) << 16); - dst_x0 = (dst_x0 & 0x1fff) | ((dst_y0 & 0x1fff) << 16); - bottom = (bottom << 16) | right; - - unifb_sync(info); - - writel(src_pitch, UGE_PITCH); - writel(src_offset, UGE_SRCSTART); - writel(dst_offset, UGE_DSTSTART); - writel(awidth, UGE_WIDHEIGHT); - writel(top, UGE_CLIP0); - writel(bottom, UGE_CLIP1); - writel(bg_color, UGE_BCOLOR); - writel(fg_color, UGE_FCOLOR); - writel(alpha_r, UGE_ROPALPHA); - writel(src_x0, UGE_SRCXY); - writel(dst_x0, UGE_DSTXY); - writel(command, UGE_COMMAND); -} - -static void unifb_copyarea(struct fb_info *info, const struct fb_copyarea *area) -{ - struct fb_copyarea modded; - u32 vxres, vyres; - modded.sx = area->sx; - modded.sy = area->sy; - modded.dx = area->dx; - modded.dy = area->dy; - modded.width = area->width; - modded.height = area->height; - - if (info->flags & FBINFO_HWACCEL_DISABLED) { - sys_copyarea(info, area); - return; - } - - vxres = info->var.xres_virtual; - vyres = info->var.yres_virtual; - - if (!modded.width || !modded.height || - modded.sx >= vxres || modded.sy >= vyres || - modded.dx >= vxres || modded.dy >= vyres) - return; - - if (modded.sx + modded.width > vxres) - modded.width = vxres - modded.sx; - if (modded.dx + modded.width > vxres) - modded.width = vxres - modded.dx; - if (modded.sy + modded.height > vyres) - modded.height = vyres - modded.sy; - if (modded.dy + modded.height > vyres) - modded.height = vyres - modded.dy; - - unifb_prim_copyarea(info, &modded); -} - -static void unifb_imageblit(struct fb_info *info, const struct fb_image *image) -{ - sys_imageblit(info, image); -} - -static u_long get_line_length(int xres_virtual, int bpp) -{ - u_long length; - - length = xres_virtual * bpp; - length = (length + 31) & ~31; - length >>= 3; - return length; -} - -/* - * Setting the video mode has been split into two parts. - * First part, xxxfb_check_var, must not write anything - * to hardware, it should only verify and adjust var. - * This means it doesn't alter par but it does use hardware - * data from it to check this var. - */ -static int unifb_check_var(struct fb_var_screeninfo *var, - struct fb_info *info) -{ - u_long line_length; - - /* - * FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal! - * as FB_VMODE_SMOOTH_XPAN is only used internally - */ - - if (var->vmode & FB_VMODE_CONUPDATE) { - var->vmode |= FB_VMODE_YWRAP; - var->xoffset = info->var.xoffset; - var->yoffset = info->var.yoffset; - } - - /* - * Some very basic checks - */ - if (!var->xres) - var->xres = 1; - if (!var->yres) - var->yres = 1; - if (var->xres > var->xres_virtual) - var->xres_virtual = var->xres; - if (var->yres > var->yres_virtual) - var->yres_virtual = var->yres; - if (var->bits_per_pixel <= 1) - var->bits_per_pixel = 1; - else if (var->bits_per_pixel <= 8) - var->bits_per_pixel = 8; - else if (var->bits_per_pixel <= 16) - var->bits_per_pixel = 16; - else if (var->bits_per_pixel <= 24) - var->bits_per_pixel = 24; - else if (var->bits_per_pixel <= 32) - var->bits_per_pixel = 32; - else - return -EINVAL; - - if (var->xres_virtual < var->xoffset + var->xres) - var->xres_virtual = var->xoffset + var->xres; - if (var->yres_virtual < var->yoffset + var->yres) - var->yres_virtual = var->yoffset + var->yres; - - /* - * Memory limit - */ - line_length = - get_line_length(var->xres_virtual, var->bits_per_pixel); - if (line_length * var->yres_virtual > UNIFB_MEMSIZE) - return -ENOMEM; - - /* - * Now that we checked it we alter var. The reason being is that the - * video mode passed in might not work but slight changes to it might - * make it work. This way we let the user know what is acceptable. - */ - switch (var->bits_per_pixel) { - case 1: - case 8: - var->red.offset = 0; - var->red.length = 8; - var->green.offset = 0; - var->green.length = 8; - var->blue.offset = 0; - var->blue.length = 8; - var->transp.offset = 0; - var->transp.length = 0; - break; - case 16: /* RGBA 5551 */ - if (var->transp.length) { - var->red.offset = 0; - var->red.length = 5; - var->green.offset = 5; - var->green.length = 5; - var->blue.offset = 10; - var->blue.length = 5; - var->transp.offset = 15; - var->transp.length = 1; - } else { /* RGB 565 */ - var->red.offset = 11; - var->red.length = 5; - var->green.offset = 5; - var->green.length = 6; - var->blue.offset = 0; - var->blue.length = 5; - var->transp.offset = 0; - var->transp.length = 0; - } - break; - case 24: /* RGB 888 */ - var->red.offset = 0; - var->red.length = 8; - var->green.offset = 8; - var->green.length = 8; - var->blue.offset = 16; - var->blue.length = 8; - var->transp.offset = 0; - var->transp.length = 0; - break; - case 32: /* RGBA 8888 */ - var->red.offset = 16; - var->red.length = 8; - var->green.offset = 8; - var->green.length = 8; - var->blue.offset = 0; - var->blue.length = 8; - var->transp.offset = 24; - var->transp.length = 8; - break; - } - var->red.msb_right = 0; - var->green.msb_right = 0; - var->blue.msb_right = 0; - var->transp.msb_right = 0; - - return 0; -} - -/* - * This routine actually sets the video mode. It's in here where we - * the hardware state info->par and fix which can be affected by the - * change in par. For this driver it doesn't do much. - */ -static int unifb_set_par(struct fb_info *info) -{ - int hTotal, vTotal, hSyncStart, hSyncEnd, vSyncStart, vSyncEnd; - int format; - -#ifdef CONFIG_PUV3_PM - struct clk *clk_vga; - u32 pixclk = 0; - int i; - - for (i = 0; i <= 10; i++) { - if (info->var.xres == unifb_modes[i].xres - && info->var.yres == unifb_modes[i].yres - && info->var.upper_margin == unifb_modes[i].upper_margin - && info->var.lower_margin == unifb_modes[i].lower_margin - && info->var.left_margin == unifb_modes[i].left_margin - && info->var.right_margin == unifb_modes[i].right_margin - && info->var.hsync_len == unifb_modes[i].hsync_len - && info->var.vsync_len == unifb_modes[i].vsync_len) { - pixclk = unifb_modes[i].pixclock; - break; - } - } - - /* set clock rate */ - clk_vga = clk_get(info->device, "VGA_CLK"); - if (clk_vga == ERR_PTR(-ENOENT)) - return -ENOENT; - - if (pixclk != 0) { - if (clk_set_rate(clk_vga, pixclk)) { /* set clock failed */ - info->fix = unifb_fix; - info->var = unifb_default; - if (clk_set_rate(clk_vga, unifb_default.pixclock)) - return -EINVAL; - } - } -#endif - - info->fix.line_length = get_line_length(info->var.xres_virtual, - info->var.bits_per_pixel); - - hSyncStart = info->var.xres + info->var.right_margin; - hSyncEnd = hSyncStart + info->var.hsync_len; - hTotal = hSyncEnd + info->var.left_margin; - - vSyncStart = info->var.yres + info->var.lower_margin; - vSyncEnd = vSyncStart + info->var.vsync_len; - vTotal = vSyncEnd + info->var.upper_margin; - - switch (info->var.bits_per_pixel) { - case 8: - format = UDE_CFG_DST8; - break; - case 16: - format = UDE_CFG_DST16; - break; - case 24: - format = UDE_CFG_DST24; - break; - case 32: - format = UDE_CFG_DST32; - break; - default: - return -EINVAL; - } - - writel(info->fix.smem_start, UDE_FSA); - writel(info->var.yres, UDE_LS); - writel(get_line_length(info->var.xres, - info->var.bits_per_pixel) >> 3, UDE_PS); - /* >> 3 for hardware required. */ - writel((hTotal << 16) | (info->var.xres), UDE_HAT); - writel(((hTotal - 1) << 16) | (info->var.xres - 1), UDE_HBT); - writel(((hSyncEnd - 1) << 16) | (hSyncStart - 1), UDE_HST); - writel((vTotal << 16) | (info->var.yres), UDE_VAT); - writel(((vTotal - 1) << 16) | (info->var.yres - 1), UDE_VBT); - writel(((vSyncEnd - 1) << 16) | (vSyncStart - 1), UDE_VST); - writel(UDE_CFG_GDEN_ENABLE | UDE_CFG_TIMEUP_ENABLE - | format | 0xC0000001, UDE_CFG); - - return 0; -} - -/* - * Set a single color register. The values supplied are already - * rounded down to the hardware's capabilities (according to the - * entries in the var structure). Return != 0 for invalid regno. - */ -static int unifb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, - u_int transp, struct fb_info *info) -{ - if (regno >= 256) /* no. of hw registers */ - return 1; - - /* grayscale works only partially under directcolor */ - if (info->var.grayscale) { - /* grayscale = 0.30*R + 0.59*G + 0.11*B */ - red = green = blue = - (red * 77 + green * 151 + blue * 28) >> 8; - } - -#define CNVT_TOHW(val, width) ((((val)<<(width))+0x7FFF-(val))>>16) - switch (info->fix.visual) { - case FB_VISUAL_TRUECOLOR: - case FB_VISUAL_PSEUDOCOLOR: - red = CNVT_TOHW(red, info->var.red.length); - green = CNVT_TOHW(green, info->var.green.length); - blue = CNVT_TOHW(blue, info->var.blue.length); - transp = CNVT_TOHW(transp, info->var.transp.length); - break; - case FB_VISUAL_DIRECTCOLOR: - red = CNVT_TOHW(red, 8); /* expect 8 bit DAC */ - green = CNVT_TOHW(green, 8); - blue = CNVT_TOHW(blue, 8); - /* hey, there is bug in transp handling... */ - transp = CNVT_TOHW(transp, 8); - break; - } -#undef CNVT_TOHW - /* Truecolor has hardware independent palette */ - if (info->fix.visual == FB_VISUAL_TRUECOLOR) { - u32 v; - - if (regno >= 16) - return 1; - - v = (red << info->var.red.offset) | - (green << info->var.green.offset) | - (blue << info->var.blue.offset) | - (transp << info->var.transp.offset); - switch (info->var.bits_per_pixel) { - case 8: - break; - case 16: - case 24: - case 32: - ((u32 *) (info->pseudo_palette))[regno] = v; - break; - default: - return 1; - } - return 0; - } - return 0; -} - -/* - * Pan or Wrap the Display - * - * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag - */ -static int unifb_pan_display(struct fb_var_screeninfo *var, - struct fb_info *info) -{ - if (var->vmode & FB_VMODE_YWRAP) { - if (var->yoffset < 0 - || var->yoffset >= info->var.yres_virtual - || var->xoffset) - return -EINVAL; - } else { - if (var->xoffset + info->var.xres > info->var.xres_virtual || - var->yoffset + info->var.yres > info->var.yres_virtual) - return -EINVAL; - } - info->var.xoffset = var->xoffset; - info->var.yoffset = var->yoffset; - if (var->vmode & FB_VMODE_YWRAP) - info->var.vmode |= FB_VMODE_YWRAP; - else - info->var.vmode &= ~FB_VMODE_YWRAP; - return 0; -} - -int unifb_mmap(struct fb_info *info, - struct vm_area_struct *vma) -{ - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - - return vm_iomap_memory(vma, info->fix.smem_start, info->fix.smem_len); -} - -static const struct fb_ops unifb_ops = { - .fb_read = fb_sys_read, - .fb_write = fb_sys_write, - .fb_check_var = unifb_check_var, - .fb_set_par = unifb_set_par, - .fb_setcolreg = unifb_setcolreg, - .fb_pan_display = unifb_pan_display, - .fb_fillrect = unifb_fillrect, - .fb_copyarea = unifb_copyarea, - .fb_imageblit = unifb_imageblit, - .fb_mmap = unifb_mmap, -}; - -/* - * Initialisation - */ -static int unifb_probe(struct platform_device *dev) -{ - struct fb_info *info; - u32 unifb_regs[UNIFB_REGS_NUM]; - int retval = -ENOMEM; - struct resource *iomem; - void *videomemory; - - videomemory = (void *)__get_free_pages(GFP_KERNEL | __GFP_COMP, - get_order(UNIFB_MEMSIZE)); - if (!videomemory) - goto err; - - memset(videomemory, 0, UNIFB_MEMSIZE); - - unifb_fix.smem_start = virt_to_phys(videomemory); - unifb_fix.smem_len = UNIFB_MEMSIZE; - - iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); - unifb_fix.mmio_start = iomem->start; - - info = framebuffer_alloc(sizeof(u32)*256, &dev->dev); - if (!info) - goto err; - - info->screen_base = (char __iomem *)videomemory; - info->fbops = &unifb_ops; - - retval = fb_find_mode(&info->var, info, NULL, - unifb_modes, 10, &unifb_modes[0], 16); - - if (!retval || (retval == 4)) - info->var = unifb_default; - - info->fix = unifb_fix; - info->pseudo_palette = info->par; - info->par = NULL; - info->flags = FBINFO_FLAG_DEFAULT; -#ifdef FB_ACCEL_PUV3_UNIGFX - info->fix.accel = FB_ACCEL_PUV3_UNIGFX; -#endif - - retval = fb_alloc_cmap(&info->cmap, 256, 0); - if (retval < 0) - goto err1; - - retval = register_framebuffer(info); - if (retval < 0) - goto err2; - platform_set_drvdata(dev, info); - platform_device_add_data(dev, unifb_regs, sizeof(u32) * UNIFB_REGS_NUM); - - fb_info(info, "Virtual frame buffer device, using %dM of video memory\n", - UNIFB_MEMSIZE >> 20); - return 0; -err2: - fb_dealloc_cmap(&info->cmap); -err1: - framebuffer_release(info); -err: - return retval; -} - -static int unifb_remove(struct platform_device *dev) -{ - struct fb_info *info = platform_get_drvdata(dev); - - if (info) { - unregister_framebuffer(info); - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } - return 0; -} - -#ifdef CONFIG_PM -static int unifb_resume(struct platform_device *dev) -{ - int rc = 0; - u32 *unifb_regs = dev->dev.platform_data; - - if (dev->dev.power.power_state.event == PM_EVENT_ON) - return 0; - - console_lock(); - - if (dev->dev.power.power_state.event == PM_EVENT_SUSPEND) { - writel(unifb_regs[0], UDE_FSA); - writel(unifb_regs[1], UDE_LS); - writel(unifb_regs[2], UDE_PS); - writel(unifb_regs[3], UDE_HAT); - writel(unifb_regs[4], UDE_HBT); - writel(unifb_regs[5], UDE_HST); - writel(unifb_regs[6], UDE_VAT); - writel(unifb_regs[7], UDE_VBT); - writel(unifb_regs[8], UDE_VST); - writel(unifb_regs[9], UDE_CFG); - } - dev->dev.power.power_state = PMSG_ON; - - console_unlock(); - - return rc; -} - -static int unifb_suspend(struct platform_device *dev, pm_message_t mesg) -{ - u32 *unifb_regs = dev->dev.platform_data; - - unifb_regs[0] = readl(UDE_FSA); - unifb_regs[1] = readl(UDE_LS); - unifb_regs[2] = readl(UDE_PS); - unifb_regs[3] = readl(UDE_HAT); - unifb_regs[4] = readl(UDE_HBT); - unifb_regs[5] = readl(UDE_HST); - unifb_regs[6] = readl(UDE_VAT); - unifb_regs[7] = readl(UDE_VBT); - unifb_regs[8] = readl(UDE_VST); - unifb_regs[9] = readl(UDE_CFG); - - if (mesg.event == dev->dev.power.power_state.event) - return 0; - - switch (mesg.event) { - case PM_EVENT_FREEZE: /* about to take snapshot */ - case PM_EVENT_PRETHAW: /* before restoring snapshot */ - goto done; - } - - console_lock(); - - /* do nothing... */ - - console_unlock(); - -done: - dev->dev.power.power_state = mesg; - - return 0; -} -#else -#define unifb_resume NULL -#define unifb_suspend NULL -#endif - -static struct platform_driver unifb_driver = { - .probe = unifb_probe, - .remove = unifb_remove, - .resume = unifb_resume, - .suspend = unifb_suspend, - .driver = { - .name = "PKUnity-v3-UNIGFX", - }, -}; - -static int __init unifb_init(void) -{ -#ifndef MODULE - if (fb_get_options("unifb", NULL)) - return -ENODEV; -#endif - - return platform_driver_register(&unifb_driver); -} - -module_init(unifb_init); - -static void __exit unifb_exit(void) -{ - platform_driver_unregister(&unifb_driver); -} - -module_exit(unifb_exit); - -MODULE_LICENSE("GPL v2"); |