fbdev changes for 4.6
* Miscallaneous small fixes to various fbdev drivers * Remove fb_rotate, which was never used * pmag fb improvements -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJW6ANUAAoJEPo9qoy8lh71H9MP/jSZz1vkvNCZI6n4IGu6VCJg hJo59TVk1N+ug7iIfYCeKa+4E02sJFoMo+agA9xrzWC/tHAVlyMviL3HqyEGr9hS NLq5vg5odLd1QaCIHL9aLZ2C3TmJQTbt5jaUDgWou7exw/w2UCSehw5dg36YMdAK LRE52Y7yvo0ZrPykbzMbJWYMEyiiSRiujm9ql3RslYjFgMezq4urkRXS3pchJ3YV LCv+c3KNTFXt5bbbhYjcgkR++ORQsp2BaZ98Nbl2SMbSWeIwsJFMAFM6w8kvO6jV R3bUgT8VzXUX8fZ+PjoilvA8PyFBD3UHUHfFmNjQdUnkQs1zn4et4RAOEVLHa2pm nXQwxfQqY/tzzjTJlPHaG+rjqvFN+UU+iycPTdfZXptAFraWEzC8YOOiCFjlMfmp Zt5A1+jy7QJcBqMIEjvWOZy/RpAMfeUSvo8RJfe2IRV/o8yZ5dRcZxsIXBTk+k71 s6YaylH9Jx2AMmckjm2noJLazb6gmSbX11x4tdhCIDDqs1ufqMBldU5lU7HJoLOz ZIsY7gWEkh50fZ1Rbi/lFw07T4cLgRaVeikGT3OGzCDboZRzrSmnhirZ7AYRsGRM AqmGDYde6CIEQIpUogsLWYTXHMK8sMNwzLC9vhRVnH+gry9e0dnLN4wh1nH4D7AK /v1JPHzTSUFKON9KySSt =HNGQ -----END PGP SIGNATURE----- Merge tag 'fbdev-4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux Pull fbdev updates from Tomi Valkeinen: - Miscallaneous small fixes to various fbdev drivers - Remove fb_rotate, which was never used - pmag fb improvements * tag 'fbdev-4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux: (21 commits) xen kconfig: don't "select INPUT_XEN_KBDDEV_FRONTEND" video: fbdev: sis: remove unused variable drivers/video: make fbdev/sunxvr2500.c explicitly non-modular drivers/video: make fbdev/sunxvr1000.c explicitly non-modular drivers/video: make fbdev/sunxvr500.c explicitly non-modular video: exynos: fix modular build fbdev: da8xx-fb: fix videomodes of lcd panels fbdev: kill fb_rotate video: fbdev: bt431: Correct cursor format control macro video: fbdev: pmag-ba-fb: Optimize Bt455 colormap addressing video: fbdev: pmag-ba-fb: Fix and rework Bt455 colormap handling video: fbdev: bt455: Remove unneeded colormap helpers for cursor support video: fbdev: pmag-aa-fb: Report video timings video: fbdev: pmag-aa-fb: Enable building as a module video: fbdev: pmag-aa-fb: Adapt to current APIs video: fbdev: pmag-ba-fb: Fix the lower margin size fbdev: sh_mobile_lcdc: Use ARCH_RENESAS fbdev: n411: check return value fbdev: exynos: fix IS_ERR_VALUE usage video: Use bool instead int pointer for get_opt_bool() argument ...
This commit is contained in:
commit
09fd671ccb
@ -1808,8 +1808,8 @@ config FB_HIT
|
||||
frame buffer card.
|
||||
|
||||
config FB_PMAG_AA
|
||||
bool "PMAG-AA TURBOchannel framebuffer support"
|
||||
depends on (FB = y) && TC
|
||||
tristate "PMAG-AA TURBOchannel framebuffer support"
|
||||
depends on FB && TC
|
||||
select FB_CFB_FILLRECT
|
||||
select FB_CFB_COPYAREA
|
||||
select FB_CFB_IMAGEBLIT
|
||||
@ -1985,7 +1985,7 @@ config FB_W100
|
||||
|
||||
config FB_SH_MOBILE_LCDC
|
||||
tristate "SuperH Mobile LCDC framebuffer support"
|
||||
depends on FB && (SUPERH || ARCH_SHMOBILE) && HAVE_CLK
|
||||
depends on FB && (SUPERH || ARCH_RENESAS) && HAVE_CLK
|
||||
depends on FB_SH_MOBILE_MERAM || !FB_SH_MOBILE_MERAM
|
||||
select FB_SYS_FILLRECT
|
||||
select FB_SYS_COPYAREA
|
||||
@ -2246,7 +2246,6 @@ config XEN_FBDEV_FRONTEND
|
||||
select FB_SYS_IMAGEBLIT
|
||||
select FB_SYS_FOPS
|
||||
select FB_DEFERRED_IO
|
||||
select INPUT_XEN_KBDDEV_FRONTEND if INPUT_MISC
|
||||
select XEN_XENBUS_FRONTEND
|
||||
default y
|
||||
help
|
||||
|
@ -313,9 +313,6 @@ extern unsigned char fontdata_8x16[];
|
||||
* * Draws cursor *
|
||||
* int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor);
|
||||
*
|
||||
* * Rotates the display *
|
||||
* void (*fb_rotate)(struct fb_info *info, int angle);
|
||||
*
|
||||
* * wait for blit idle, optional *
|
||||
* int (*fb_sync)(struct fb_info *info);
|
||||
*
|
||||
|
@ -334,27 +334,6 @@ int au1100fb_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* fb_rotate
|
||||
* Rotate the display of this angle. This doesn't seems to be used by the core,
|
||||
* but as our hardware supports it, so why not implementing it...
|
||||
*/
|
||||
void au1100fb_fb_rotate(struct fb_info *fbi, int angle)
|
||||
{
|
||||
struct au1100fb_device *fbdev = to_au1100fb_device(fbi);
|
||||
|
||||
print_dbg("fb_rotate %p %d", fbi, angle);
|
||||
|
||||
if (fbdev && (angle > 0) && !(angle % 90)) {
|
||||
|
||||
fbdev->regs->lcd_control &= ~LCD_CONTROL_GO;
|
||||
|
||||
fbdev->regs->lcd_control &= ~(LCD_CONTROL_SM_MASK);
|
||||
fbdev->regs->lcd_control |= ((angle/90) << LCD_CONTROL_SM_BIT);
|
||||
|
||||
fbdev->regs->lcd_control |= LCD_CONTROL_GO;
|
||||
}
|
||||
}
|
||||
|
||||
/* fb_mmap
|
||||
* Map video memory in user space. We don't use the generic fb_mmap method mainly
|
||||
* to allow the use of the TLB streaming flag (CCA=6)
|
||||
@ -380,7 +359,6 @@ static struct fb_ops au1100fb_ops =
|
||||
.fb_fillrect = cfb_fillrect,
|
||||
.fb_copyarea = cfb_copyarea,
|
||||
.fb_imageblit = cfb_imageblit,
|
||||
.fb_rotate = au1100fb_fb_rotate,
|
||||
.fb_mmap = au1100fb_fb_mmap,
|
||||
};
|
||||
|
||||
|
@ -554,28 +554,6 @@ static int bfin_lq035_fb_check_var(struct fb_var_screeninfo *var,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* fb_rotate
|
||||
* Rotate the display of this angle. This doesn't seems to be used by the core,
|
||||
* but as our hardware supports it, so why not implementing it...
|
||||
*/
|
||||
static void bfin_lq035_fb_rotate(struct fb_info *fbi, int angle)
|
||||
{
|
||||
pr_debug("%s: %p %d", __func__, fbi, angle);
|
||||
#if (defined(UD) && defined(LBR))
|
||||
switch (angle) {
|
||||
|
||||
case 180:
|
||||
gpio_set_value(LBR, 0);
|
||||
gpio_set_value(UD, 1);
|
||||
break;
|
||||
default:
|
||||
gpio_set_value(LBR, 1);
|
||||
gpio_set_value(UD, 0);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int bfin_lq035_fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
|
||||
{
|
||||
if (nocursor)
|
||||
@ -623,7 +601,6 @@ static struct fb_ops bfin_lq035_fb_ops = {
|
||||
.fb_open = bfin_lq035_fb_open,
|
||||
.fb_release = bfin_lq035_fb_release,
|
||||
.fb_check_var = bfin_lq035_fb_check_var,
|
||||
.fb_rotate = bfin_lq035_fb_rotate,
|
||||
.fb_fillrect = cfb_fillrect,
|
||||
.fb_copyarea = cfb_copyarea,
|
||||
.fb_imageblit = cfb_imageblit,
|
||||
|
@ -2,6 +2,7 @@
|
||||
* linux/drivers/video/bt431.h
|
||||
*
|
||||
* Copyright 2003 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
|
||||
* Copyright 2016 Maciej W. Rozycki <macro@linux-mips.org>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General
|
||||
* Public License. See the file COPYING in the main directory of this
|
||||
@ -9,6 +10,8 @@
|
||||
*/
|
||||
#include <linux/types.h>
|
||||
|
||||
#define BT431_CURSOR_SIZE 64
|
||||
|
||||
/*
|
||||
* Bt431 cursor generator registers, 32-bit aligned.
|
||||
* Two twin Bt431 are used on the DECstation's PMAG-AA.
|
||||
@ -60,7 +63,7 @@ static inline u8 bt431_get_value(u16 val)
|
||||
#define BT431_CMD_CURS_ENABLE 0x40
|
||||
#define BT431_CMD_XHAIR_ENABLE 0x20
|
||||
#define BT431_CMD_OR_CURSORS 0x10
|
||||
#define BT431_CMD_AND_CURSORS 0x00
|
||||
#define BT431_CMD_XOR_CURSORS 0x00
|
||||
#define BT431_CMD_1_1_MUX 0x00
|
||||
#define BT431_CMD_4_1_MUX 0x04
|
||||
#define BT431_CMD_5_1_MUX 0x08
|
||||
@ -196,28 +199,30 @@ static inline void bt431_position_cursor(struct bt431_regs *regs, u16 x, u16 y)
|
||||
bt431_write_reg_inc(regs, (y >> 8) & 0x0f); /* BT431_REG_CYHI */
|
||||
}
|
||||
|
||||
static inline void bt431_set_font(struct bt431_regs *regs, u8 fgc,
|
||||
u16 width, u16 height)
|
||||
static inline void bt431_set_cursor(struct bt431_regs *regs,
|
||||
const char *data, const char *mask,
|
||||
u16 rop, u16 width, u16 height)
|
||||
{
|
||||
u16 x, y;
|
||||
int i;
|
||||
u16 fgp = fgc ? 0xffff : 0x0000;
|
||||
u16 bgp = fgc ? 0x0000 : 0xffff;
|
||||
|
||||
i = 0;
|
||||
width = DIV_ROUND_UP(width, 8);
|
||||
bt431_select_reg(regs, BT431_REG_CRAM_BASE);
|
||||
for (i = BT431_REG_CRAM_BASE; i <= BT431_REG_CRAM_END; i++) {
|
||||
u16 value;
|
||||
for (y = 0; y < BT431_CURSOR_SIZE; y++)
|
||||
for (x = 0; x < BT431_CURSOR_SIZE / 8; x++) {
|
||||
u16 val = 0;
|
||||
|
||||
if (height << 6 <= i << 3)
|
||||
value = bgp;
|
||||
else if (width <= i % 8 << 3)
|
||||
value = bgp;
|
||||
else if (((width >> 3) & 0xffff) > i % 8)
|
||||
value = fgp;
|
||||
else
|
||||
value = fgp & ~(bgp << (width % 8 << 1));
|
||||
|
||||
bt431_write_cmap_inc(regs, value);
|
||||
}
|
||||
if (y < height && x < width) {
|
||||
val = mask[i];
|
||||
if (rop == ROP_XOR)
|
||||
val = (val << 8) | (val ^ data[i]);
|
||||
else
|
||||
val = (val << 8) | (val & data[i]);
|
||||
i++;
|
||||
}
|
||||
bt431_write_cmap_inc(regs, val);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void bt431_init_cursor(struct bt431_regs *regs)
|
||||
|
@ -2,6 +2,7 @@
|
||||
* linux/drivers/video/bt455.h
|
||||
*
|
||||
* Copyright 2003 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
|
||||
* Copyright 2016 Maciej W. Rozycki <macro@linux-mips.org>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General
|
||||
* Public License. See the file COPYING in the main directory of this
|
||||
@ -29,66 +30,61 @@ static inline void bt455_select_reg(struct bt455_regs *regs, int ir)
|
||||
regs->addr_cmap = ir & 0x0f;
|
||||
}
|
||||
|
||||
static inline void bt455_reset_reg(struct bt455_regs *regs)
|
||||
{
|
||||
mb();
|
||||
regs->addr_clr = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read/write to a Bt455 color map register.
|
||||
*/
|
||||
static inline void bt455_read_cmap_entry(struct bt455_regs *regs, int cr,
|
||||
u8* red, u8* green, u8* blue)
|
||||
{
|
||||
bt455_select_reg(regs, cr);
|
||||
mb();
|
||||
*red = regs->addr_cmap_data & 0x0f;
|
||||
rmb();
|
||||
*green = regs->addr_cmap_data & 0x0f;
|
||||
rmb();
|
||||
*blue = regs->addr_cmap_data & 0x0f;
|
||||
}
|
||||
|
||||
static inline void bt455_write_cmap_entry(struct bt455_regs *regs, int cr,
|
||||
u8 red, u8 green, u8 blue)
|
||||
{
|
||||
bt455_select_reg(regs, cr);
|
||||
wmb();
|
||||
regs->addr_cmap_data = red & 0x0f;
|
||||
wmb();
|
||||
regs->addr_cmap_data = green & 0x0f;
|
||||
wmb();
|
||||
regs->addr_cmap_data = blue & 0x0f;
|
||||
}
|
||||
|
||||
static inline void bt455_write_ovly_entry(struct bt455_regs *regs, int cr,
|
||||
u8 red, u8 green, u8 blue)
|
||||
{
|
||||
bt455_select_reg(regs, cr);
|
||||
wmb();
|
||||
regs->addr_ovly = red & 0x0f;
|
||||
wmb();
|
||||
regs->addr_ovly = green & 0x0f;
|
||||
wmb();
|
||||
regs->addr_ovly = blue & 0x0f;
|
||||
}
|
||||
|
||||
static inline void bt455_set_cursor(struct bt455_regs *regs)
|
||||
static inline void bt455_read_cmap_next(struct bt455_regs *regs, u8 *grey)
|
||||
{
|
||||
mb();
|
||||
regs->addr_ovly = 0x0f;
|
||||
wmb();
|
||||
regs->addr_ovly = 0x0f;
|
||||
wmb();
|
||||
regs->addr_ovly = 0x0f;
|
||||
regs->addr_cmap_data;
|
||||
rmb();
|
||||
*grey = regs->addr_cmap_data & 0xf;
|
||||
rmb();
|
||||
regs->addr_cmap_data;
|
||||
}
|
||||
|
||||
static inline void bt455_erase_cursor(struct bt455_regs *regs)
|
||||
static inline void bt455_write_cmap_next(struct bt455_regs *regs, u8 grey)
|
||||
{
|
||||
/* bt455_write_cmap_entry(regs, 8, 0x00, 0x00, 0x00); */
|
||||
/* bt455_write_cmap_entry(regs, 9, 0x00, 0x00, 0x00); */
|
||||
bt455_write_ovly_entry(regs, 8, 0x03, 0x03, 0x03);
|
||||
bt455_write_ovly_entry(regs, 9, 0x07, 0x07, 0x07);
|
||||
|
||||
wmb();
|
||||
regs->addr_ovly = 0x09;
|
||||
regs->addr_cmap_data = 0x0;
|
||||
wmb();
|
||||
regs->addr_ovly = 0x09;
|
||||
regs->addr_cmap_data = grey & 0xf;
|
||||
wmb();
|
||||
regs->addr_ovly = 0x09;
|
||||
regs->addr_cmap_data = 0x0;
|
||||
}
|
||||
|
||||
static inline void bt455_write_ovly_next(struct bt455_regs *regs, u8 grey)
|
||||
{
|
||||
wmb();
|
||||
regs->addr_ovly = 0x0;
|
||||
wmb();
|
||||
regs->addr_ovly = grey & 0xf;
|
||||
wmb();
|
||||
regs->addr_ovly = 0x0;
|
||||
}
|
||||
|
||||
static inline void bt455_read_cmap_entry(struct bt455_regs *regs,
|
||||
int cr, u8 *grey)
|
||||
{
|
||||
bt455_select_reg(regs, cr);
|
||||
bt455_read_cmap_next(regs, grey);
|
||||
}
|
||||
|
||||
static inline void bt455_write_cmap_entry(struct bt455_regs *regs,
|
||||
int cr, u8 grey)
|
||||
{
|
||||
bt455_select_reg(regs, cr);
|
||||
bt455_write_cmap_next(regs, grey);
|
||||
}
|
||||
|
||||
static inline void bt455_write_ovly_entry(struct bt455_regs *regs, u8 grey)
|
||||
{
|
||||
bt455_reset_reg(regs);
|
||||
bt455_write_ovly_next(regs, grey);
|
||||
}
|
||||
|
@ -209,8 +209,7 @@ static struct fb_videomode known_lcd_panels[] = {
|
||||
.lower_margin = 2,
|
||||
.hsync_len = 0,
|
||||
.vsync_len = 0,
|
||||
.sync = FB_SYNC_CLK_INVERT |
|
||||
FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
|
||||
.sync = FB_SYNC_CLK_INVERT,
|
||||
},
|
||||
/* Sharp LK043T1DG01 */
|
||||
[1] = {
|
||||
@ -224,7 +223,7 @@ static struct fb_videomode known_lcd_panels[] = {
|
||||
.lower_margin = 2,
|
||||
.hsync_len = 41,
|
||||
.vsync_len = 10,
|
||||
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
|
||||
.sync = 0,
|
||||
.flag = 0,
|
||||
},
|
||||
[2] = {
|
||||
@ -239,7 +238,7 @@ static struct fb_videomode known_lcd_panels[] = {
|
||||
.lower_margin = 10,
|
||||
.hsync_len = 10,
|
||||
.vsync_len = 10,
|
||||
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
|
||||
.sync = 0,
|
||||
.flag = 0,
|
||||
},
|
||||
[3] = {
|
||||
|
@ -3,7 +3,7 @@
|
||||
#
|
||||
|
||||
menuconfig EXYNOS_VIDEO
|
||||
bool "Exynos Video driver support"
|
||||
tristate "Exynos Video driver support"
|
||||
depends on ARCH_S5PV210 || ARCH_EXYNOS
|
||||
help
|
||||
This enables support for EXYNOS Video device.
|
||||
@ -15,13 +15,13 @@ if EXYNOS_VIDEO
|
||||
#
|
||||
|
||||
config EXYNOS_MIPI_DSI
|
||||
bool "EXYNOS MIPI DSI driver support."
|
||||
tristate "EXYNOS MIPI DSI driver support."
|
||||
select GENERIC_PHY
|
||||
help
|
||||
This enables support for MIPI-DSI device.
|
||||
|
||||
config EXYNOS_LCD_S6E8AX0
|
||||
bool "S6E8AX0 MIPI AMOLED LCD Driver"
|
||||
tristate "S6E8AX0 MIPI AMOLED LCD Driver"
|
||||
depends on EXYNOS_MIPI_DSI && BACKLIGHT_CLASS_DEVICE
|
||||
depends on (LCD_CLASS_DEVICE = y)
|
||||
default n
|
||||
|
@ -2,6 +2,8 @@
|
||||
# Makefile for the exynos video drivers.
|
||||
#
|
||||
|
||||
obj-$(CONFIG_EXYNOS_MIPI_DSI) += exynos_mipi_dsi.o exynos_mipi_dsi_common.o \
|
||||
exynos_mipi_dsi_lowlevel.o
|
||||
obj-$(CONFIG_EXYNOS_MIPI_DSI) += exynos-mipi-dsi-mod.o
|
||||
|
||||
exynos-mipi-dsi-mod-objs += exynos_mipi_dsi.o exynos_mipi_dsi_common.o \
|
||||
exynos_mipi_dsi_lowlevel.o
|
||||
obj-$(CONFIG_EXYNOS_LCD_S6E8AX0) += s6e8ax0.o
|
||||
|
@ -263,6 +263,7 @@ int exynos_mipi_dsi_register_lcd_driver(struct mipi_dsim_lcd_driver *lcd_drv)
|
||||
return 0;
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(exynos_mipi_dsi_register_lcd_driver);
|
||||
|
||||
static struct mipi_dsim_ddi *exynos_mipi_dsi_bind_lcd_ddi(
|
||||
struct mipi_dsim_device *dsim,
|
||||
@ -402,12 +403,12 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)
|
||||
goto error;
|
||||
}
|
||||
|
||||
dsim->irq = platform_get_irq(pdev, 0);
|
||||
if (IS_ERR_VALUE(dsim->irq)) {
|
||||
ret = platform_get_irq(pdev, 0);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "failed to request dsim irq resource\n");
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
dsim->irq = ret;
|
||||
|
||||
init_completion(&dsim_wr_comp);
|
||||
init_completion(&dsim_rd_comp);
|
||||
|
@ -302,7 +302,7 @@ static __inline__ int get_opt_int(const char *this_opt, const char *name,
|
||||
}
|
||||
|
||||
static __inline__ int get_opt_bool(const char *this_opt, const char *name,
|
||||
int *ret)
|
||||
bool *ret)
|
||||
{
|
||||
if (!ret)
|
||||
return 0;
|
||||
|
@ -354,7 +354,8 @@ static int metronome_powerup_cmd(struct metronomefb_par *par)
|
||||
}
|
||||
|
||||
/* the rest are 0 */
|
||||
memset((u8 *) (par->metromem_cmd->args + i), 0, (32-i)*2);
|
||||
memset(&par->metromem_cmd->args[i], 0,
|
||||
(ARRAY_SIZE(par->metromem_cmd->args) - i) * 2);
|
||||
|
||||
par->metromem_cmd->csum = cs;
|
||||
|
||||
@ -376,7 +377,8 @@ static int metronome_config_cmd(struct metronomefb_par *par)
|
||||
memcpy(par->metromem_cmd->args, epd_frame_table[par->dt].config,
|
||||
sizeof(epd_frame_table[par->dt].config));
|
||||
/* the rest are 0 */
|
||||
memset((u8 *) (par->metromem_cmd->args + 4), 0, (32-4)*2);
|
||||
memset(&par->metromem_cmd->args[4], 0,
|
||||
(ARRAY_SIZE(par->metromem_cmd->args) - 4) * 2);
|
||||
|
||||
par->metromem_cmd->csum = 0xCC10;
|
||||
par->metromem_cmd->csum += calc_img_cksum(par->metromem_cmd->args, 4);
|
||||
|
@ -165,16 +165,22 @@ static int __init n411_init(void)
|
||||
if (!n411_device)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_device_add_data(n411_device, &n411_board, sizeof(n411_board));
|
||||
ret = platform_device_add_data(n411_device, &n411_board,
|
||||
sizeof(n411_board));
|
||||
if (ret)
|
||||
goto put_plat_device;
|
||||
|
||||
/* this _add binds hecubafb to n411. hecubafb refcounts n411 */
|
||||
ret = platform_device_add(n411_device);
|
||||
|
||||
if (ret)
|
||||
platform_device_put(n411_device);
|
||||
goto put_plat_device;
|
||||
|
||||
return 0;
|
||||
|
||||
put_plat_device:
|
||||
platform_device_put(n411_device);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
static void __exit n411_exit(void)
|
||||
|
@ -594,27 +594,6 @@ static int set_fb_var(struct fb_info *fbi,
|
||||
}
|
||||
|
||||
|
||||
/* Set rotation (0, 90, 180, 270 degree), and switch to the new mode. */
|
||||
static void omapfb_rotate(struct fb_info *fbi, int rotate)
|
||||
{
|
||||
struct omapfb_plane_struct *plane = fbi->par;
|
||||
struct omapfb_device *fbdev = plane->fbdev;
|
||||
|
||||
omapfb_rqueue_lock(fbdev);
|
||||
if (rotate != fbi->var.rotate) {
|
||||
struct fb_var_screeninfo *new_var = &fbdev->new_var;
|
||||
|
||||
memcpy(new_var, &fbi->var, sizeof(*new_var));
|
||||
new_var->rotate = rotate;
|
||||
if (set_fb_var(fbi, new_var) == 0 &&
|
||||
memcmp(new_var, &fbi->var, sizeof(*new_var))) {
|
||||
memcpy(&fbi->var, new_var, sizeof(*new_var));
|
||||
ctrl_change_mode(fbi);
|
||||
}
|
||||
}
|
||||
omapfb_rqueue_unlock(fbdev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set new x,y offsets in the virtual display for the visible area and switch
|
||||
* to the new mode.
|
||||
@ -1256,7 +1235,6 @@ static struct fb_ops omapfb_ops = {
|
||||
.fb_ioctl = omapfb_ioctl,
|
||||
.fb_check_var = omapfb_check_var,
|
||||
.fb_set_par = omapfb_set_par,
|
||||
.fb_rotate = omapfb_rotate,
|
||||
.fb_pan_display = omapfb_pan_display,
|
||||
};
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
* and Harald Koerfgen <hkoerfg@web.de>, which itself is derived from
|
||||
* "HP300 Topcat framebuffer support (derived from macfb of all things)
|
||||
* Phil Blundell <philb@gnu.org> 1998"
|
||||
* Copyright (c) 2016 Maciej W. Rozycki
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General
|
||||
* Public License. See the file COPYING in the main directory of this
|
||||
@ -21,37 +22,29 @@
|
||||
*
|
||||
* 2003-09-21 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
|
||||
* Hardware cursor support.
|
||||
*
|
||||
* 2016-02-21 Maciej W. Rozycki <macro@linux-mips.org>
|
||||
* Version 0.03: Rewritten for the new FB and TC APIs.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/console.h>
|
||||
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/dec/machtype.h>
|
||||
#include <asm/dec/tc.h>
|
||||
|
||||
#include <video/fbcon.h>
|
||||
#include <video/fbcon-cfb8.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/tc.h>
|
||||
#include <linux/timer.h>
|
||||
|
||||
#include "bt455.h"
|
||||
#include "bt431.h"
|
||||
|
||||
/* Version information */
|
||||
#define DRIVER_VERSION "0.02"
|
||||
#define DRIVER_VERSION "0.03"
|
||||
#define DRIVER_AUTHOR "Karsten Merker <merker@linuxtag.org>"
|
||||
#define DRIVER_DESCRIPTION "PMAG-AA Framebuffer Driver"
|
||||
|
||||
/* Prototypes */
|
||||
static int aafb_set_var(struct fb_var_screeninfo *var, int con,
|
||||
struct fb_info *info);
|
||||
|
||||
/*
|
||||
* Bt455 RAM DAC register base offset (rel. to TC slot base address).
|
||||
*/
|
||||
@ -68,443 +61,246 @@ static int aafb_set_var(struct fb_var_screeninfo *var, int con,
|
||||
*/
|
||||
#define PMAG_AA_ONBOARD_FBMEM_OFFSET 0x200000
|
||||
|
||||
struct aafb_cursor {
|
||||
struct timer_list timer;
|
||||
int enable;
|
||||
int on;
|
||||
int vbl_cnt;
|
||||
int blink_rate;
|
||||
u16 x, y, width, height;
|
||||
struct aafb_par {
|
||||
void __iomem *mmio;
|
||||
struct bt455_regs __iomem *bt455;
|
||||
struct bt431_regs __iomem *bt431;
|
||||
};
|
||||
|
||||
#define CURSOR_TIMER_FREQ (HZ / 50)
|
||||
#define CURSOR_BLINK_RATE (20)
|
||||
#define CURSOR_DRAW_DELAY (2)
|
||||
|
||||
struct aafb_info {
|
||||
struct fb_info info;
|
||||
struct display disp;
|
||||
struct aafb_cursor cursor;
|
||||
struct bt455_regs *bt455;
|
||||
struct bt431_regs *bt431;
|
||||
unsigned long fb_start;
|
||||
unsigned long fb_size;
|
||||
unsigned long fb_line_length;
|
||||
static struct fb_var_screeninfo aafb_defined = {
|
||||
.xres = 1280,
|
||||
.yres = 1024,
|
||||
.xres_virtual = 2048,
|
||||
.yres_virtual = 1024,
|
||||
.bits_per_pixel = 8,
|
||||
.grayscale = 1,
|
||||
.red.length = 0,
|
||||
.green.length = 1,
|
||||
.blue.length = 0,
|
||||
.activate = FB_ACTIVATE_NOW,
|
||||
.accel_flags = FB_ACCEL_NONE,
|
||||
.pixclock = 7645,
|
||||
.left_margin = 224,
|
||||
.right_margin = 32,
|
||||
.upper_margin = 33,
|
||||
.lower_margin = 3,
|
||||
.hsync_len = 160,
|
||||
.vsync_len = 3,
|
||||
.sync = FB_SYNC_ON_GREEN,
|
||||
.vmode = FB_VMODE_NONINTERLACED,
|
||||
};
|
||||
|
||||
/*
|
||||
* Max 3 TURBOchannel slots -> max 3 PMAG-AA.
|
||||
*/
|
||||
static struct aafb_info my_fb_info[3];
|
||||
static struct fb_fix_screeninfo aafb_fix = {
|
||||
.id = "PMAG-AA",
|
||||
.smem_len = (2048 * 1024),
|
||||
.type = FB_TYPE_PACKED_PIXELS,
|
||||
.visual = FB_VISUAL_MONO10,
|
||||
.ypanstep = 1,
|
||||
.ywrapstep = 1,
|
||||
.line_length = 2048,
|
||||
.mmio_len = PMAG_AA_ONBOARD_FBMEM_OFFSET - PMAG_AA_BT455_OFFSET,
|
||||
};
|
||||
|
||||
static struct aafb_par {
|
||||
} current_par;
|
||||
|
||||
static int currcon = -1;
|
||||
|
||||
static void aafb_set_cursor(struct aafb_info *info, int on)
|
||||
static int aafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
|
||||
{
|
||||
struct aafb_cursor *c = &info->cursor;
|
||||
struct aafb_par *par = info->par;
|
||||
|
||||
if (on) {
|
||||
bt431_position_cursor(info->bt431, c->x, c->y);
|
||||
bt431_enable_cursor(info->bt431);
|
||||
} else
|
||||
bt431_erase_cursor(info->bt431);
|
||||
}
|
||||
|
||||
static void aafbcon_cursor(struct display *disp, int mode, int x, int y)
|
||||
{
|
||||
struct aafb_info *info = (struct aafb_info *)disp->fb_info;
|
||||
struct aafb_cursor *c = &info->cursor;
|
||||
|
||||
x *= fontwidth(disp);
|
||||
y *= fontheight(disp);
|
||||
|
||||
if (c->x == x && c->y == y && (mode == CM_ERASE) == !c->enable)
|
||||
return;
|
||||
|
||||
c->enable = 0;
|
||||
if (c->on)
|
||||
aafb_set_cursor(info, 0);
|
||||
c->x = x - disp->var.xoffset;
|
||||
c->y = y - disp->var.yoffset;
|
||||
|
||||
switch (mode) {
|
||||
case CM_ERASE:
|
||||
c->on = 0;
|
||||
break;
|
||||
case CM_DRAW:
|
||||
case CM_MOVE:
|
||||
if (c->on)
|
||||
aafb_set_cursor(info, c->on);
|
||||
else
|
||||
c->vbl_cnt = CURSOR_DRAW_DELAY;
|
||||
c->enable = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int aafbcon_set_font(struct display *disp, int width, int height)
|
||||
{
|
||||
struct aafb_info *info = (struct aafb_info *)disp->fb_info;
|
||||
struct aafb_cursor *c = &info->cursor;
|
||||
u8 fgc = ~attr_bgcol_ec(disp, disp->conp, &info->info);
|
||||
|
||||
if (width > 64 || height > 64 || width < 0 || height < 0)
|
||||
if (cursor->image.height > BT431_CURSOR_SIZE ||
|
||||
cursor->image.width > BT431_CURSOR_SIZE) {
|
||||
bt431_erase_cursor(par->bt431);
|
||||
return -EINVAL;
|
||||
|
||||
c->height = height;
|
||||
c->width = width;
|
||||
|
||||
bt431_set_font(info->bt431, fgc, width, height);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void aafb_cursor_timer_handler(unsigned long data)
|
||||
{
|
||||
struct aafb_info *info = (struct aafb_info *)data;
|
||||
struct aafb_cursor *c = &info->cursor;
|
||||
|
||||
if (!c->enable)
|
||||
goto out;
|
||||
|
||||
if (c->vbl_cnt && --c->vbl_cnt == 0) {
|
||||
c->on ^= 1;
|
||||
aafb_set_cursor(info, c->on);
|
||||
c->vbl_cnt = c->blink_rate;
|
||||
}
|
||||
|
||||
out:
|
||||
c->timer.expires = jiffies + CURSOR_TIMER_FREQ;
|
||||
add_timer(&c->timer);
|
||||
}
|
||||
if (!cursor->enable)
|
||||
bt431_erase_cursor(par->bt431);
|
||||
|
||||
static void __init aafb_cursor_init(struct aafb_info *info)
|
||||
{
|
||||
struct aafb_cursor *c = &info->cursor;
|
||||
if (cursor->set & FB_CUR_SETPOS)
|
||||
bt431_position_cursor(par->bt431,
|
||||
cursor->image.dx, cursor->image.dy);
|
||||
if (cursor->set & FB_CUR_SETCMAP) {
|
||||
u8 fg = cursor->image.fg_color ? 0xf : 0x0;
|
||||
u8 bg = cursor->image.bg_color ? 0xf : 0x0;
|
||||
|
||||
c->enable = 1;
|
||||
c->on = 1;
|
||||
c->x = c->y = 0;
|
||||
c->width = c->height = 0;
|
||||
c->vbl_cnt = CURSOR_DRAW_DELAY;
|
||||
c->blink_rate = CURSOR_BLINK_RATE;
|
||||
bt455_write_cmap_entry(par->bt455, 8, bg);
|
||||
bt455_write_cmap_next(par->bt455, bg);
|
||||
bt455_write_ovly_next(par->bt455, fg);
|
||||
}
|
||||
if (cursor->set & (FB_CUR_SETSIZE | FB_CUR_SETSHAPE | FB_CUR_SETIMAGE))
|
||||
bt431_set_cursor(par->bt431,
|
||||
cursor->image.data, cursor->mask, cursor->rop,
|
||||
cursor->image.width, cursor->image.height);
|
||||
|
||||
init_timer(&c->timer);
|
||||
c->timer.data = (unsigned long)info;
|
||||
c->timer.function = aafb_cursor_timer_handler;
|
||||
mod_timer(&c->timer, jiffies + CURSOR_TIMER_FREQ);
|
||||
}
|
||||
|
||||
static void __exit aafb_cursor_exit(struct aafb_info *info)
|
||||
{
|
||||
struct aafb_cursor *c = &info->cursor;
|
||||
|
||||
del_timer_sync(&c->timer);
|
||||
}
|
||||
|
||||
static struct display_switch aafb_switch8 = {
|
||||
.setup = fbcon_cfb8_setup,
|
||||
.bmove = fbcon_cfb8_bmove,
|
||||
.clear = fbcon_cfb8_clear,
|
||||
.putc = fbcon_cfb8_putc,
|
||||
.putcs = fbcon_cfb8_putcs,
|
||||
.revc = fbcon_cfb8_revc,
|
||||
.cursor = aafbcon_cursor,
|
||||
.set_font = aafbcon_set_font,
|
||||
.clear_margins = fbcon_cfb8_clear_margins,
|
||||
.fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
|
||||
};
|
||||
|
||||
static void aafb_get_par(struct aafb_par *par)
|
||||
{
|
||||
*par = current_par;
|
||||
}
|
||||
|
||||
static int aafb_get_fix(struct fb_fix_screeninfo *fix, int con,
|
||||
struct fb_info *info)
|
||||
{
|
||||
struct aafb_info *ip = (struct aafb_info *)info;
|
||||
|
||||
memset(fix, 0, sizeof(struct fb_fix_screeninfo));
|
||||
strcpy(fix->id, "PMAG-AA");
|
||||
fix->smem_start = ip->fb_start;
|
||||
fix->smem_len = ip->fb_size;
|
||||
fix->type = FB_TYPE_PACKED_PIXELS;
|
||||
fix->ypanstep = 1;
|
||||
fix->ywrapstep = 1;
|
||||
fix->visual = FB_VISUAL_MONO10;
|
||||
fix->line_length = 1280;
|
||||
fix->accel = FB_ACCEL_NONE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void aafb_set_disp(struct display *disp, int con,
|
||||
struct aafb_info *info)
|
||||
{
|
||||
struct fb_fix_screeninfo fix;
|
||||
|
||||
disp->fb_info = &info->info;
|
||||
aafb_set_var(&disp->var, con, &info->info);
|
||||
if (disp->conp && disp->conp->vc_sw && disp->conp->vc_sw->con_cursor)
|
||||
disp->conp->vc_sw->con_cursor(disp->conp, CM_ERASE);
|
||||
disp->dispsw = &aafb_switch8;
|
||||
disp->dispsw_data = 0;
|
||||
|
||||
aafb_get_fix(&fix, con, &info->info);
|
||||
disp->screen_base = (u8 *) fix.smem_start;
|
||||
disp->visual = fix.visual;
|
||||
disp->type = fix.type;
|
||||
disp->type_aux = fix.type_aux;
|
||||
disp->ypanstep = fix.ypanstep;
|
||||
disp->ywrapstep = fix.ywrapstep;
|
||||
disp->line_length = fix.line_length;
|
||||
disp->next_line = 2048;
|
||||
disp->can_soft_blank = 1;
|
||||
disp->inverse = 0;
|
||||
disp->scrollmode = SCROLL_YREDRAW;
|
||||
|
||||
aafbcon_set_font(disp, fontwidth(disp), fontheight(disp));
|
||||
}
|
||||
|
||||
static int aafb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
|
||||
struct fb_info *info)
|
||||
{
|
||||
static u16 color[2] = {0x0000, 0x000f};
|
||||
static struct fb_cmap aafb_cmap = {0, 2, color, color, color, NULL};
|
||||
|
||||
fb_copy_cmap(&aafb_cmap, cmap, kspc ? 0 : 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aafb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
|
||||
struct fb_info *info)
|
||||
{
|
||||
u16 color[2] = {0x0000, 0x000f};
|
||||
|
||||
if (cmap->start == 0
|
||||
&& cmap->len == 2
|
||||
&& memcmp(cmap->red, color, sizeof(color)) == 0
|
||||
&& memcmp(cmap->green, color, sizeof(color)) == 0
|
||||
&& memcmp(cmap->blue, color, sizeof(color)) == 0
|
||||
&& cmap->transp == NULL)
|
||||
return 0;
|
||||
else
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int aafb_ioctl(struct fb_info *info, u32 cmd, unsigned long arg)
|
||||
{
|
||||
/* TODO: Not yet implemented */
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
|
||||
static int aafb_switch(int con, struct fb_info *info)
|
||||
{
|
||||
struct aafb_info *ip = (struct aafb_info *)info;
|
||||
struct display *old = (currcon < 0) ? &ip->disp : (fb_display + currcon);
|
||||
struct display *new = (con < 0) ? &ip->disp : (fb_display + con);
|
||||
|
||||
if (old->conp && old->conp->vc_sw && old->conp->vc_sw->con_cursor)
|
||||
old->conp->vc_sw->con_cursor(old->conp, CM_ERASE);
|
||||
|
||||
/* Set the current console. */
|
||||
currcon = con;
|
||||
aafb_set_disp(new, con, ip);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void aafb_encode_var(struct fb_var_screeninfo *var,
|
||||
struct aafb_par *par)
|
||||
{
|
||||
var->xres = 1280;
|
||||
var->yres = 1024;
|
||||
var->xres_virtual = 2048;
|
||||
var->yres_virtual = 1024;
|
||||
var->xoffset = 0;
|
||||
var->yoffset = 0;
|
||||
var->bits_per_pixel = 8;
|
||||
var->grayscale = 1;
|
||||
var->red.offset = 0;
|
||||
var->red.length = 0;
|
||||
var->red.msb_right = 0;
|
||||
var->green.offset = 0;
|
||||
var->green.length = 1;
|
||||
var->green.msb_right = 0;
|
||||
var->blue.offset = 0;
|
||||
var->blue.length = 0;
|
||||
var->blue.msb_right = 0;
|
||||
var->transp.offset = 0;
|
||||
var->transp.length = 0;
|
||||
var->transp.msb_right = 0;
|
||||
var->nonstd = 0;
|
||||
var->activate &= ~FB_ACTIVATE_MASK & FB_ACTIVATE_NOW;
|
||||
var->accel_flags = 0;
|
||||
var->sync = FB_SYNC_ON_GREEN;
|
||||
var->vmode &= ~FB_VMODE_MASK & FB_VMODE_NONINTERLACED;
|
||||
}
|
||||
|
||||
static int aafb_get_var(struct fb_var_screeninfo *var, int con,
|
||||
struct fb_info *info)
|
||||
{
|
||||
if (con < 0) {
|
||||
struct aafb_par par;
|
||||
|
||||
memset(var, 0, sizeof(struct fb_var_screeninfo));
|
||||
aafb_get_par(&par);
|
||||
aafb_encode_var(var, &par);
|
||||
} else
|
||||
*var = info->var;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aafb_set_var(struct fb_var_screeninfo *var, int con,
|
||||
struct fb_info *info)
|
||||
{
|
||||
struct aafb_par par;
|
||||
|
||||
aafb_get_par(&par);
|
||||
aafb_encode_var(var, &par);
|
||||
info->var = *var;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aafb_update_var(int con, struct fb_info *info)
|
||||
{
|
||||
struct aafb_info *ip = (struct aafb_info *)info;
|
||||
struct display *disp = (con < 0) ? &ip->disp : (fb_display + con);
|
||||
|
||||
if (con == currcon)
|
||||
aafbcon_cursor(disp, CM_ERASE, ip->cursor.x, ip->cursor.y);
|
||||
if (cursor->enable)
|
||||
bt431_enable_cursor(par->bt431);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 0 unblanks, any other blanks. */
|
||||
|
||||
static void aafb_blank(int blank, struct fb_info *info)
|
||||
static int aafb_blank(int blank, struct fb_info *info)
|
||||
{
|
||||
struct aafb_info *ip = (struct aafb_info *)info;
|
||||
struct aafb_par *par = info->par;
|
||||
u8 val = blank ? 0x00 : 0x0f;
|
||||
|
||||
bt455_write_cmap_entry(ip->bt455, 1, val, val, val);
|
||||
aafbcon_cursor(&ip->disp, CM_ERASE, ip->cursor.x, ip->cursor.y);
|
||||
}
|
||||
|
||||
static struct fb_ops aafb_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.fb_get_fix = aafb_get_fix,
|
||||
.fb_get_var = aafb_get_var,
|
||||
.fb_set_var = aafb_set_var,
|
||||
.fb_get_cmap = aafb_get_cmap,
|
||||
.fb_set_cmap = aafb_set_cmap,
|
||||
.fb_ioctl = aafb_ioctl
|
||||
};
|
||||
|
||||
static int __init init_one(int slot)
|
||||
{
|
||||
unsigned long base_addr = CKSEG1ADDR(get_tc_base_addr(slot));
|
||||
struct aafb_info *ip = &my_fb_info[slot];
|
||||
|
||||
memset(ip, 0, sizeof(struct aafb_info));
|
||||
|
||||
/*
|
||||
* Framebuffer display memory base address and friends.
|
||||
*/
|
||||
ip->bt455 = (struct bt455_regs *) (base_addr + PMAG_AA_BT455_OFFSET);
|
||||
ip->bt431 = (struct bt431_regs *) (base_addr + PMAG_AA_BT431_OFFSET);
|
||||
ip->fb_start = base_addr + PMAG_AA_ONBOARD_FBMEM_OFFSET;
|
||||
ip->fb_size = 2048 * 1024; /* fb_fix_screeninfo.smem_length
|
||||
seems to be physical */
|
||||
ip->fb_line_length = 2048;
|
||||
|
||||
/*
|
||||
* Let there be consoles..
|
||||
*/
|
||||
strcpy(ip->info.modename, "PMAG-AA");
|
||||
ip->info.node = -1;
|
||||
ip->info.flags = FBINFO_FLAG_DEFAULT;
|
||||
ip->info.fbops = &aafb_ops;
|
||||
ip->info.disp = &ip->disp;
|
||||
ip->info.changevar = NULL;
|
||||
ip->info.switch_con = &aafb_switch;
|
||||
ip->info.updatevar = &aafb_update_var;
|
||||
ip->info.blank = &aafb_blank;
|
||||
|
||||
aafb_set_disp(&ip->disp, currcon, ip);
|
||||
|
||||
/*
|
||||
* Configure the RAM DACs.
|
||||
*/
|
||||
bt455_erase_cursor(ip->bt455);
|
||||
|
||||
/* Init colormap. */
|
||||
bt455_write_cmap_entry(ip->bt455, 0, 0x00, 0x00, 0x00);
|
||||
bt455_write_cmap_entry(ip->bt455, 1, 0x0f, 0x0f, 0x0f);
|
||||
|
||||
/* Init hardware cursor. */
|
||||
bt431_init_cursor(ip->bt431);
|
||||
aafb_cursor_init(ip);
|
||||
|
||||
/* Clear the screen. */
|
||||
memset ((void *)ip->fb_start, 0, ip->fb_size);
|
||||
|
||||
if (register_framebuffer(&ip->info) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
printk(KERN_INFO "fb%d: %s frame buffer in TC slot %d\n",
|
||||
GET_FB_IDX(ip->info.node), ip->info.modename, slot);
|
||||
|
||||
bt455_write_cmap_entry(par->bt455, 1, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __exit exit_one(int slot)
|
||||
static struct fb_ops aafb_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.fb_blank = aafb_blank,
|
||||
.fb_fillrect = cfb_fillrect,
|
||||
.fb_copyarea = cfb_copyarea,
|
||||
.fb_imageblit = cfb_imageblit,
|
||||
.fb_cursor = aafb_cursor,
|
||||
};
|
||||
|
||||
static int pmagaafb_probe(struct device *dev)
|
||||
{
|
||||
struct aafb_info *ip = &my_fb_info[slot];
|
||||
struct tc_dev *tdev = to_tc_dev(dev);
|
||||
resource_size_t start, len;
|
||||
struct fb_info *info;
|
||||
struct aafb_par *par;
|
||||
int err;
|
||||
|
||||
if (unregister_framebuffer(&ip->info) < 0)
|
||||
return -EINVAL;
|
||||
info = framebuffer_alloc(sizeof(struct aafb_par), dev);
|
||||
if (!info) {
|
||||
printk(KERN_ERR "%s: Cannot allocate memory\n", dev_name(dev));
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
par = info->par;
|
||||
dev_set_drvdata(dev, info);
|
||||
|
||||
info->fbops = &aafb_ops;
|
||||
info->fix = aafb_fix;
|
||||
info->var = aafb_defined;
|
||||
info->flags = FBINFO_DEFAULT;
|
||||
|
||||
/* Request the I/O MEM resource. */
|
||||
start = tdev->resource.start;
|
||||
len = tdev->resource.end - start + 1;
|
||||
if (!request_mem_region(start, len, dev_name(dev))) {
|
||||
printk(KERN_ERR "%s: Cannot reserve FB region\n",
|
||||
dev_name(dev));
|
||||
err = -EBUSY;
|
||||
goto err_alloc;
|
||||
}
|
||||
|
||||
/* MMIO mapping setup. */
|
||||
info->fix.mmio_start = start + PMAG_AA_BT455_OFFSET;
|
||||
par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
|
||||
if (!par->mmio) {
|
||||
printk(KERN_ERR "%s: Cannot map MMIO\n", dev_name(dev));
|
||||
err = -ENOMEM;
|
||||
goto err_resource;
|
||||
}
|
||||
par->bt455 = par->mmio - PMAG_AA_BT455_OFFSET + PMAG_AA_BT455_OFFSET;
|
||||
par->bt431 = par->mmio - PMAG_AA_BT455_OFFSET + PMAG_AA_BT431_OFFSET;
|
||||
|
||||
/* Frame buffer mapping setup. */
|
||||
info->fix.smem_start = start + PMAG_AA_ONBOARD_FBMEM_OFFSET;
|
||||
info->screen_base = ioremap_nocache(info->fix.smem_start,
|
||||
info->fix.smem_len);
|
||||
if (!info->screen_base) {
|
||||
printk(KERN_ERR "%s: Cannot map FB\n", dev_name(dev));
|
||||
err = -ENOMEM;
|
||||
goto err_mmio_map;
|
||||
}
|
||||
info->screen_size = info->fix.smem_len;
|
||||
|
||||
/* Init colormap. */
|
||||
bt455_write_cmap_entry(par->bt455, 0, 0x0);
|
||||
bt455_write_cmap_next(par->bt455, 0xf);
|
||||
|
||||
/* Init hardware cursor. */
|
||||
bt431_erase_cursor(par->bt431);
|
||||
bt431_init_cursor(par->bt431);
|
||||
|
||||
err = register_framebuffer(info);
|
||||
if (err < 0) {
|
||||
printk(KERN_ERR "%s: Cannot register framebuffer\n",
|
||||
dev_name(dev));
|
||||
goto err_smem_map;
|
||||
}
|
||||
|
||||
get_device(dev);
|
||||
|
||||
pr_info("fb%d: %s frame buffer device at %s\n",
|
||||
info->node, info->fix.id, dev_name(dev));
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
err_smem_map:
|
||||
iounmap(info->screen_base);
|
||||
|
||||
err_mmio_map:
|
||||
iounmap(par->mmio);
|
||||
|
||||
err_resource:
|
||||
release_mem_region(start, len);
|
||||
|
||||
err_alloc:
|
||||
framebuffer_release(info);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __exit pmagaafb_remove(struct device *dev)
|
||||
{
|
||||
struct tc_dev *tdev = to_tc_dev(dev);
|
||||
struct fb_info *info = dev_get_drvdata(dev);
|
||||
struct aafb_par *par = info->par;
|
||||
resource_size_t start, len;
|
||||
|
||||
put_device(dev);
|
||||
unregister_framebuffer(info);
|
||||
iounmap(info->screen_base);
|
||||
iounmap(par->mmio);
|
||||
start = tdev->resource.start;
|
||||
len = tdev->resource.end - start + 1;
|
||||
release_mem_region(start, len);
|
||||
framebuffer_release(info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialise the framebuffer.
|
||||
*/
|
||||
int __init pmagaafb_init(void)
|
||||
static const struct tc_device_id pmagaafb_tc_table[] = {
|
||||
{ "DEC ", "PMAG-AA " },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(tc, pmagaafb_tc_table);
|
||||
|
||||
static struct tc_driver pmagaafb_driver = {
|
||||
.id_table = pmagaafb_tc_table,
|
||||
.driver = {
|
||||
.name = "pmagaafb",
|
||||
.bus = &tc_bus_type,
|
||||
.probe = pmagaafb_probe,
|
||||
.remove = __exit_p(pmagaafb_remove),
|
||||
},
|
||||
};
|
||||
|
||||
static int __init pmagaafb_init(void)
|
||||
{
|
||||
int sid;
|
||||
int found = 0;
|
||||
|
||||
while ((sid = search_tc_card("PMAG-AA")) >= 0) {
|
||||
found = 1;
|
||||
claim_tc_card(sid);
|
||||
init_one(sid);
|
||||
}
|
||||
|
||||
return found ? 0 : -ENXIO;
|
||||
#ifndef MODULE
|
||||
if (fb_get_options("pmagaafb", NULL))
|
||||
return -ENXIO;
|
||||
#endif
|
||||
return tc_register_driver(&pmagaafb_driver);
|
||||
}
|
||||
|
||||
static void __exit pmagaafb_exit(void)
|
||||
{
|
||||
int sid;
|
||||
|
||||
while ((sid = search_tc_card("PMAG-AA")) >= 0) {
|
||||
exit_one(sid);
|
||||
release_tc_card(sid);
|
||||
}
|
||||
tc_unregister_driver(&pmagaafb_driver);
|
||||
}
|
||||
|
||||
module_init(pmagaafb_init);
|
||||
module_exit(pmagaafb_exit);
|
||||
|
||||
MODULE_AUTHOR(DRIVER_AUTHOR);
|
||||
MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
|
||||
MODULE_LICENSE("GPL");
|
||||
#ifdef MODULE
|
||||
module_init(pmagaafb_init);
|
||||
module_exit(pmagaafb_exit);
|
||||
#endif
|
||||
|
@ -60,7 +60,7 @@ static struct fb_var_screeninfo pmagbafb_defined = {
|
||||
.left_margin = 116,
|
||||
.right_margin = 12,
|
||||
.upper_margin = 34,
|
||||
.lower_margin = 12,
|
||||
.lower_margin = 0,
|
||||
.hsync_len = 128,
|
||||
.vsync_len = 3,
|
||||
.sync = FB_SYNC_ON_GREEN,
|
||||
|
@ -2151,17 +2151,15 @@ SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned shor
|
||||
unsigned short RefreshRateTableIndex)
|
||||
{
|
||||
unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0;
|
||||
unsigned short modeflag, resinfo, tempbx;
|
||||
unsigned short resinfo, tempbx;
|
||||
const unsigned char *CHTVVCLKPtr = NULL;
|
||||
|
||||
if(ModeNo <= 0x13) {
|
||||
modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
|
||||
resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
|
||||
CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
|
||||
VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
|
||||
VCLKIndexGENCRT = VCLKIndexGEN;
|
||||
} else {
|
||||
modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
|
||||
resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
|
||||
CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
|
||||
VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
|
||||
@ -7270,7 +7268,7 @@ SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift)
|
||||
static void
|
||||
SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
|
||||
{
|
||||
unsigned short temp, temp1, resinfo = 0;
|
||||
unsigned short temp, temp1;
|
||||
unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
|
||||
|
||||
if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return;
|
||||
@ -7282,10 +7280,6 @@ SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned
|
||||
if(!(ROMAddr[0x61] & 0x04)) return;
|
||||
}
|
||||
|
||||
if(ModeNo > 0x13) {
|
||||
resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
|
||||
}
|
||||
|
||||
SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
|
||||
temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
|
||||
if(!(temp & 0x01)) {
|
||||
|
@ -613,22 +613,6 @@ int xxxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* xxxfb_rotate - NOT a required function. If your hardware
|
||||
* supports rotation the whole screen then
|
||||
* you would provide a hook for this.
|
||||
*
|
||||
* @info: frame buffer structure that represents a single frame buffer
|
||||
* @angle: The angle we rotate the screen.
|
||||
*
|
||||
* This operation is used to set or alter the properities of the
|
||||
* cursor.
|
||||
*/
|
||||
void xxxfb_rotate(struct fb_info *info, int angle)
|
||||
{
|
||||
/* Will be deprecated */
|
||||
}
|
||||
|
||||
/**
|
||||
* xxxfb_sync - NOT a required function. Normally the accel engine
|
||||
* for a graphics card take a specific amount of time.
|
||||
@ -665,7 +649,6 @@ static struct fb_ops xxxfb_ops = {
|
||||
.fb_copyarea = xxxfb_copyarea, /* Needed !!! */
|
||||
.fb_imageblit = xxxfb_imageblit, /* Needed !!! */
|
||||
.fb_cursor = xxxfb_cursor, /* Optional !!! */
|
||||
.fb_rotate = xxxfb_rotate,
|
||||
.fb_sync = xxxfb_sync,
|
||||
.fb_ioctl = xxxfb_ioctl,
|
||||
.fb_mmap = xxxfb_mmap,
|
||||
|
@ -1,9 +1,10 @@
|
||||
/* sunxvr1000.c: Sun XVR-1000 driver for sparc64 systems
|
||||
/* sunxvr1000.c: Sun XVR-1000 fb driver for sparc64 systems
|
||||
*
|
||||
* License: GPL
|
||||
*
|
||||
* Copyright (C) 2010 David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/init.h>
|
||||
@ -173,36 +174,19 @@ err_out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int gfb_remove(struct platform_device *op)
|
||||
{
|
||||
struct fb_info *info = dev_get_drvdata(&op->dev);
|
||||
struct gfb_info *gp = info->par;
|
||||
|
||||
unregister_framebuffer(info);
|
||||
|
||||
iounmap(gp->fb_base);
|
||||
|
||||
of_iounmap(&op->resource[6], gp->fb_base, gp->fb_size);
|
||||
|
||||
framebuffer_release(info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id gfb_match[] = {
|
||||
{
|
||||
.name = "SUNW,gfb",
|
||||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ffb_match);
|
||||
|
||||
static struct platform_driver gfb_driver = {
|
||||
.probe = gfb_probe,
|
||||
.remove = gfb_remove,
|
||||
.driver = {
|
||||
.name = "gfb",
|
||||
.of_match_table = gfb_match,
|
||||
.name = "gfb",
|
||||
.of_match_table = gfb_match,
|
||||
.suppress_bind_attrs = true,
|
||||
},
|
||||
};
|
||||
|
||||
@ -213,16 +197,4 @@ static int __init gfb_init(void)
|
||||
|
||||
return platform_driver_register(&gfb_driver);
|
||||
}
|
||||
|
||||
static void __exit gfb_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&gfb_driver);
|
||||
}
|
||||
|
||||
module_init(gfb_init);
|
||||
module_exit(gfb_exit);
|
||||
|
||||
MODULE_DESCRIPTION("framebuffer driver for Sun XVR-1000 graphics");
|
||||
MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
|
||||
MODULE_VERSION("1.0");
|
||||
MODULE_LICENSE("GPL");
|
||||
device_initcall(gfb_init);
|
||||
|
@ -1,9 +1,10 @@
|
||||
/* s3d.c: Sun 3DLABS XVR-2500 et al. driver for sparc64 systems
|
||||
/* sunxvr2500.c: Sun 3DLABS XVR-2500 et al. fb driver for sparc64 systems
|
||||
*
|
||||
* License: GPL
|
||||
*
|
||||
* Copyright (C) 2007 David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/pci.h>
|
||||
@ -219,22 +220,6 @@ err_out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static void s3d_pci_unregister(struct pci_dev *pdev)
|
||||
{
|
||||
struct fb_info *info = pci_get_drvdata(pdev);
|
||||
struct s3d_info *sp = info->par;
|
||||
|
||||
unregister_framebuffer(info);
|
||||
|
||||
iounmap(sp->fb_base);
|
||||
|
||||
pci_release_region(pdev, 1);
|
||||
|
||||
framebuffer_release(info);
|
||||
|
||||
pci_disable_device(pdev);
|
||||
}
|
||||
|
||||
static struct pci_device_id s3d_pci_table[] = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x002c), },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x002d), },
|
||||
@ -248,10 +233,12 @@ static struct pci_device_id s3d_pci_table[] = {
|
||||
};
|
||||
|
||||
static struct pci_driver s3d_driver = {
|
||||
.driver = {
|
||||
.suppress_bind_attrs = true,
|
||||
},
|
||||
.name = "s3d",
|
||||
.id_table = s3d_pci_table,
|
||||
.probe = s3d_pci_register,
|
||||
.remove = s3d_pci_unregister,
|
||||
};
|
||||
|
||||
static int __init s3d_init(void)
|
||||
@ -261,16 +248,4 @@ static int __init s3d_init(void)
|
||||
|
||||
return pci_register_driver(&s3d_driver);
|
||||
}
|
||||
|
||||
static void __exit s3d_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&s3d_driver);
|
||||
}
|
||||
|
||||
module_init(s3d_init);
|
||||
module_exit(s3d_exit);
|
||||
|
||||
MODULE_DESCRIPTION("framebuffer driver for Sun XVR-2500 graphics");
|
||||
MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
|
||||
MODULE_VERSION("1.0");
|
||||
MODULE_LICENSE("GPL");
|
||||
device_initcall(s3d_init);
|
||||
|
@ -1,9 +1,10 @@
|
||||
/* sunxvr500.c: Sun 3DLABS XVR-500 Expert3D driver for sparc64 systems
|
||||
/* sunxvr500.c: Sun 3DLABS XVR-500 Expert3D fb driver for sparc64 systems
|
||||
*
|
||||
* License: GPL
|
||||
*
|
||||
* Copyright (C) 2007 David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/pci.h>
|
||||
@ -392,25 +393,6 @@ err_out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static void e3d_pci_unregister(struct pci_dev *pdev)
|
||||
{
|
||||
struct fb_info *info = pci_get_drvdata(pdev);
|
||||
struct e3d_info *ep = info->par;
|
||||
|
||||
unregister_framebuffer(info);
|
||||
|
||||
iounmap(ep->ramdac);
|
||||
iounmap(ep->fb_base);
|
||||
|
||||
pci_release_region(pdev, 0);
|
||||
pci_release_region(pdev, 1);
|
||||
|
||||
fb_dealloc_cmap(&info->cmap);
|
||||
framebuffer_release(info);
|
||||
|
||||
pci_disable_device(pdev);
|
||||
}
|
||||
|
||||
static struct pci_device_id e3d_pci_table[] = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x7a0), },
|
||||
{ PCI_DEVICE(0x1091, 0x7a0), },
|
||||
@ -434,10 +416,12 @@ static struct pci_device_id e3d_pci_table[] = {
|
||||
};
|
||||
|
||||
static struct pci_driver e3d_driver = {
|
||||
.driver = {
|
||||
.suppress_bind_attrs = true,
|
||||
},
|
||||
.name = "e3d",
|
||||
.id_table = e3d_pci_table,
|
||||
.probe = e3d_pci_register,
|
||||
.remove = e3d_pci_unregister,
|
||||
};
|
||||
|
||||
static int __init e3d_init(void)
|
||||
@ -447,16 +431,4 @@ static int __init e3d_init(void)
|
||||
|
||||
return pci_register_driver(&e3d_driver);
|
||||
}
|
||||
|
||||
static void __exit e3d_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&e3d_driver);
|
||||
}
|
||||
|
||||
module_init(e3d_init);
|
||||
module_exit(e3d_exit);
|
||||
|
||||
MODULE_DESCRIPTION("framebuffer driver for Sun XVR-500 graphics");
|
||||
MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
|
||||
MODULE_VERSION("1.0");
|
||||
MODULE_LICENSE("GPL");
|
||||
device_initcall(e3d_init);
|
||||
|
@ -296,9 +296,6 @@ struct fb_ops {
|
||||
/* Draws cursor */
|
||||
int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor);
|
||||
|
||||
/* Rotates the display */
|
||||
void (*fb_rotate)(struct fb_info *info, int angle);
|
||||
|
||||
/* wait for blit idle, optional */
|
||||
int (*fb_sync)(struct fb_info *info);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user