Skip to content

Commit

Permalink
viafb: hardware acceleration initialization cleanup
Browse files Browse the repository at this point in the history
The main motivation of this patch was to merge the three initialization
functions in one and clean it up. However as some changes in other code
areas where needed to do it right some small other changes were made.

Changes to viafb_par:

io_virt renamed as engine_mmio and moved to shared
VQ_start renamed as vq_vram_addr and moved to shared
VQ_end removed as it is easily recalculatable

vq_vram_addr is not strictly needed but keep it to track where we
allocated video memory.  The memory allocated for the virtual queue was
shrunk to VQ_SIZE as VQ_SIZE+CURSOR_SIZE looked like a bug to me.  But to
be honest I don't have the faintest idea what virtual queues are for in
the graphic hardware and whether the driver needs them in any way.  I only
know that they aren't directly accessed by the driver and so the only
potential current use would be as hardware internal buffers.  For now keep
them to avoid regressions and only remove the double cursor allocation.

The most changes were caused by renames and the mentioned structure
changes so the chance of regressions is pretty low.  The meaning of
viafb_accel changed slightly as previously it was changed back and forth
in the code and allowed to enable the hardware acceleration by software if
previously disabled.  The new behaviour is that viafb_accel=0 always
prevents hardware acceleration.  With viafb_accel!=0 the acceleration can
be freely choosen by set_var.  This means viafb_accel is a diagnostic tool
and if someone has to use viafb_accel=0 the driver needs to be fixed.

As this is mostly a code cleanup no regressions beside the slightly change
of viafb_accel is expected.

Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Cc: Scott Fang <ScottFang@viatech.com.cn>
Cc: Joseph Chan <JosephChan@via.com.tw>
Cc: Harald Welte <laforge@gnumonks.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Florian Tobias Schandinat authored and Linus Torvalds committed Sep 23, 2009
1 parent 2d6e885 commit 31de59d
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 217 deletions.
268 changes: 106 additions & 162 deletions drivers/video/via/accel.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,9 +308,22 @@ static int hw_bitblt_2(void __iomem *engine, u8 op, u32 width, u32 height,
return 0;
}

void viafb_init_accel(struct viafb_shared *shared)
int viafb_init_engine(struct fb_info *info)
{
switch (shared->chip_info.gfx_chip_name) {
struct viafb_par *viapar = info->par;
void __iomem *engine;
u32 vq_start_addr, vq_end_addr, vq_start_low, vq_end_low, vq_high,
vq_len, chip_name = viapar->shared->chip_info.gfx_chip_name;

engine = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
viapar->shared->engine_mmio = engine;
if (!engine) {
printk(KERN_WARNING "viafb_init_accel: ioremap failed, "
"hardware acceleration disabled\n");
return -ENOMEM;
}

switch (chip_name) {
case UNICHROME_CLE266:
case UNICHROME_K400:
case UNICHROME_K800:
Expand All @@ -321,186 +334,115 @@ void viafb_init_accel(struct viafb_shared *shared)
case UNICHROME_K8M890:
case UNICHROME_P4M890:
case UNICHROME_P4M900:
shared->hw_bitblt = hw_bitblt_1;
viapar->shared->hw_bitblt = hw_bitblt_1;
break;
case UNICHROME_VX800:
shared->hw_bitblt = hw_bitblt_2;
viapar->shared->hw_bitblt = hw_bitblt_2;
break;
default:
shared->hw_bitblt = NULL;
viapar->shared->hw_bitblt = NULL;
}

viaparinfo->fbmem_free -= CURSOR_SIZE;
shared->cursor_vram_addr = viaparinfo->fbmem_free;
viaparinfo->fbmem_used += CURSOR_SIZE;
viapar->fbmem_free -= CURSOR_SIZE;
viapar->shared->cursor_vram_addr = viapar->fbmem_free;
viapar->fbmem_used += CURSOR_SIZE;

/* Reverse 8*1024 memory space for cursor image */
viaparinfo->fbmem_free -= (CURSOR_SIZE + VQ_SIZE);
viaparinfo->VQ_start = viaparinfo->fbmem_free;
viaparinfo->VQ_end = viaparinfo->VQ_start + VQ_SIZE - 1;
viaparinfo->fbmem_used += (CURSOR_SIZE + VQ_SIZE);
}

void viafb_init_2d_engine(void)
{
u32 dwVQStartAddr, dwVQEndAddr;
u32 dwVQLen, dwVQStartL, dwVQEndL, dwVQStartEndH;
viapar->fbmem_free -= VQ_SIZE;
viapar->shared->vq_vram_addr = viapar->fbmem_free;
viapar->fbmem_used += VQ_SIZE;

/* Init AGP and VQ regs */
switch (viaparinfo->chip_info->gfx_chip_name) {
switch (chip_name) {
case UNICHROME_K8M890:
case UNICHROME_P4M900:
writel(0x00100000, viaparinfo->io_virt + VIA_REG_CR_TRANSET);
writel(0x680A0000, viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
writel(0x02000000, viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
writel(0x00100000, engine + VIA_REG_CR_TRANSET);
writel(0x680A0000, engine + VIA_REG_CR_TRANSPACE);
writel(0x02000000, engine + VIA_REG_CR_TRANSPACE);
break;

default:
writel(0x00100000, viaparinfo->io_virt + VIA_REG_TRANSET);
writel(0x00000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
writel(0x00333004, viaparinfo->io_virt + VIA_REG_TRANSPACE);
writel(0x60000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
writel(0x61000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
writel(0x62000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
writel(0x63000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
writel(0x64000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
writel(0x7D000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);

writel(0xFE020000, viaparinfo->io_virt + VIA_REG_TRANSET);
writel(0x00000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
writel(0x00100000, engine + VIA_REG_TRANSET);
writel(0x00000000, engine + VIA_REG_TRANSPACE);
writel(0x00333004, engine + VIA_REG_TRANSPACE);
writel(0x60000000, engine + VIA_REG_TRANSPACE);
writel(0x61000000, engine + VIA_REG_TRANSPACE);
writel(0x62000000, engine + VIA_REG_TRANSPACE);
writel(0x63000000, engine + VIA_REG_TRANSPACE);
writel(0x64000000, engine + VIA_REG_TRANSPACE);
writel(0x7D000000, engine + VIA_REG_TRANSPACE);

writel(0xFE020000, engine + VIA_REG_TRANSET);
writel(0x00000000, engine + VIA_REG_TRANSPACE);
break;
}
if (viaparinfo->VQ_start != 0) {
/* Enable VQ */
dwVQStartAddr = viaparinfo->VQ_start;
dwVQEndAddr = viaparinfo->VQ_end;

dwVQStartL = 0x50000000 | (dwVQStartAddr & 0xFFFFFF);
dwVQEndL = 0x51000000 | (dwVQEndAddr & 0xFFFFFF);
dwVQStartEndH = 0x52000000 |
((dwVQStartAddr & 0xFF000000) >> 24) |
((dwVQEndAddr & 0xFF000000) >> 16);
dwVQLen = 0x53000000 | (VQ_SIZE >> 3);
switch (viaparinfo->chip_info->gfx_chip_name) {
case UNICHROME_K8M890:
case UNICHROME_P4M900:
dwVQStartL |= 0x20000000;
dwVQEndL |= 0x20000000;
dwVQStartEndH |= 0x20000000;
dwVQLen |= 0x20000000;
break;
default:
break;
}

switch (viaparinfo->chip_info->gfx_chip_name) {
case UNICHROME_K8M890:
case UNICHROME_P4M900:
writel(0x00100000,
viaparinfo->io_virt + VIA_REG_CR_TRANSET);
writel(dwVQStartEndH,
viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
writel(dwVQStartL,
viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
writel(dwVQEndL,
viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
writel(dwVQLen,
viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
writel(0x74301001,
viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
writel(0x00000000,
viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
break;
default:
writel(0x00FE0000,
viaparinfo->io_virt + VIA_REG_TRANSET);
writel(0x080003FE,
viaparinfo->io_virt + VIA_REG_TRANSPACE);
writel(0x0A00027C,
viaparinfo->io_virt + VIA_REG_TRANSPACE);
writel(0x0B000260,
viaparinfo->io_virt + VIA_REG_TRANSPACE);
writel(0x0C000274,
viaparinfo->io_virt + VIA_REG_TRANSPACE);
writel(0x0D000264,
viaparinfo->io_virt + VIA_REG_TRANSPACE);
writel(0x0E000000,
viaparinfo->io_virt + VIA_REG_TRANSPACE);
writel(0x0F000020,
viaparinfo->io_virt + VIA_REG_TRANSPACE);
writel(0x1000027E,
viaparinfo->io_virt + VIA_REG_TRANSPACE);
writel(0x110002FE,
viaparinfo->io_virt + VIA_REG_TRANSPACE);
writel(0x200F0060,
viaparinfo->io_virt + VIA_REG_TRANSPACE);

writel(0x00000006,
viaparinfo->io_virt + VIA_REG_TRANSPACE);
writel(0x40008C0F,
viaparinfo->io_virt + VIA_REG_TRANSPACE);
writel(0x44000000,
viaparinfo->io_virt + VIA_REG_TRANSPACE);
writel(0x45080C04,
viaparinfo->io_virt + VIA_REG_TRANSPACE);
writel(0x46800408,
viaparinfo->io_virt + VIA_REG_TRANSPACE);

writel(dwVQStartEndH,
viaparinfo->io_virt + VIA_REG_TRANSPACE);
writel(dwVQStartL,
viaparinfo->io_virt + VIA_REG_TRANSPACE);
writel(dwVQEndL,
viaparinfo->io_virt + VIA_REG_TRANSPACE);
writel(dwVQLen,
viaparinfo->io_virt + VIA_REG_TRANSPACE);
break;
}
} else {
/* Disable VQ */
switch (viaparinfo->chip_info->gfx_chip_name) {
case UNICHROME_K8M890:
case UNICHROME_P4M900:
writel(0x00100000,
viaparinfo->io_virt + VIA_REG_CR_TRANSET);
writel(0x74301000,
viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
break;
default:
writel(0x00FE0000,
viaparinfo->io_virt + VIA_REG_TRANSET);
writel(0x00000004,
viaparinfo->io_virt + VIA_REG_TRANSPACE);
writel(0x40008C0F,
viaparinfo->io_virt + VIA_REG_TRANSPACE);
writel(0x44000000,
viaparinfo->io_virt + VIA_REG_TRANSPACE);
writel(0x45080C04,
viaparinfo->io_virt + VIA_REG_TRANSPACE);
writel(0x46800408,
viaparinfo->io_virt + VIA_REG_TRANSPACE);
break;
}
/* Enable VQ */
vq_start_addr = viapar->shared->vq_vram_addr;
vq_end_addr = viapar->shared->vq_vram_addr + VQ_SIZE - 1;

vq_start_low = 0x50000000 | (vq_start_addr & 0xFFFFFF);
vq_end_low = 0x51000000 | (vq_end_addr & 0xFFFFFF);
vq_high = 0x52000000 | ((vq_start_addr & 0xFF000000) >> 24) |
((vq_end_addr & 0xFF000000) >> 16);
vq_len = 0x53000000 | (VQ_SIZE >> 3);

switch (chip_name) {
case UNICHROME_K8M890:
case UNICHROME_P4M900:
vq_start_low |= 0x20000000;
vq_end_low |= 0x20000000;
vq_high |= 0x20000000;
vq_len |= 0x20000000;

writel(0x00100000, engine + VIA_REG_CR_TRANSET);
writel(vq_high, engine + VIA_REG_CR_TRANSPACE);
writel(vq_start_low, engine + VIA_REG_CR_TRANSPACE);
writel(vq_end_low, engine + VIA_REG_CR_TRANSPACE);
writel(vq_len, engine + VIA_REG_CR_TRANSPACE);
writel(0x74301001, engine + VIA_REG_CR_TRANSPACE);
writel(0x00000000, engine + VIA_REG_CR_TRANSPACE);
break;
default:
writel(0x00FE0000, engine + VIA_REG_TRANSET);
writel(0x080003FE, engine + VIA_REG_TRANSPACE);
writel(0x0A00027C, engine + VIA_REG_TRANSPACE);
writel(0x0B000260, engine + VIA_REG_TRANSPACE);
writel(0x0C000274, engine + VIA_REG_TRANSPACE);
writel(0x0D000264, engine + VIA_REG_TRANSPACE);
writel(0x0E000000, engine + VIA_REG_TRANSPACE);
writel(0x0F000020, engine + VIA_REG_TRANSPACE);
writel(0x1000027E, engine + VIA_REG_TRANSPACE);
writel(0x110002FE, engine + VIA_REG_TRANSPACE);
writel(0x200F0060, engine + VIA_REG_TRANSPACE);

writel(0x00000006, engine + VIA_REG_TRANSPACE);
writel(0x40008C0F, engine + VIA_REG_TRANSPACE);
writel(0x44000000, engine + VIA_REG_TRANSPACE);
writel(0x45080C04, engine + VIA_REG_TRANSPACE);
writel(0x46800408, engine + VIA_REG_TRANSPACE);

writel(vq_high, engine + VIA_REG_TRANSPACE);
writel(vq_start_low, engine + VIA_REG_TRANSPACE);
writel(vq_end_low, engine + VIA_REG_TRANSPACE);
writel(vq_len, engine + VIA_REG_TRANSPACE);
break;
}
}

void viafb_hw_cursor_init(void)
{
/* Set Cursor Image Base Address */
writel(viaparinfo->shared->cursor_vram_addr,
viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_POS);
writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_ORG);
writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_BG);
writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_FG);
writel(viapar->shared->cursor_vram_addr, engine + VIA_REG_CURSOR_MODE);
writel(0x0, engine + VIA_REG_CURSOR_POS);
writel(0x0, engine + VIA_REG_CURSOR_ORG);
writel(0x0, engine + VIA_REG_CURSOR_BG);
writel(0x0, engine + VIA_REG_CURSOR_FG);
return 0;
}

void viafb_show_hw_cursor(struct fb_info *info, int Status)
{
u32 temp;
u32 iga_path = ((struct viafb_par *)(info->par))->iga_path;
struct viafb_par *viapar = info->par;
u32 temp, iga_path = viapar->iga_path;

temp = readl(viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
temp = readl(viapar->shared->engine_mmio + VIA_REG_CURSOR_MODE);
switch (Status) {
case HW_Cursor_ON:
temp |= 0x1;
Expand All @@ -517,25 +459,27 @@ void viafb_show_hw_cursor(struct fb_info *info, int Status)
default:
temp &= 0x7FFFFFFF;
}
writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
writel(temp, viapar->shared->engine_mmio + VIA_REG_CURSOR_MODE);
}

int viafb_wait_engine_idle(void)
void viafb_wait_engine_idle(struct fb_info *info)
{
struct viafb_par *viapar = info->par;
int loop = 0;

while (!(readl(viaparinfo->io_virt + VIA_REG_STATUS) &
while (!(readl(viapar->shared->engine_mmio + VIA_REG_STATUS) &
VIA_VR_QUEUE_BUSY) && (loop < MAXLOOP)) {
loop++;
cpu_relax();
}

while ((readl(viaparinfo->io_virt + VIA_REG_STATUS) &
while ((readl(viapar->shared->engine_mmio + VIA_REG_STATUS) &
(VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) &&
(loop < MAXLOOP)) {
loop++;
cpu_relax();
}

return loop >= MAXLOOP;
if (loop >= MAXLOOP)
printk(KERN_ERR "viafb_wait_engine_idle: not syncing\n");
}
8 changes: 3 additions & 5 deletions drivers/video/via/accel.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,8 @@
#define VIA_BITBLT_MONO 2
#define VIA_BITBLT_FILL 3

void viafb_init_accel(struct viafb_shared *shared);
void viafb_init_2d_engine(void);
void viafb_hw_cursor_init(void);
void viafb_show_hw_cursor(struct fb_info *info, int Status); int
viafb_wait_engine_idle(void); void viafb_set_2d_color_depth(int bpp);
int viafb_init_engine(struct fb_info *info);
void viafb_show_hw_cursor(struct fb_info *info, int Status);
void viafb_wait_engine_idle(struct fb_info *info);

#endif /* __ACCEL_H__ */
1 change: 0 additions & 1 deletion drivers/video/via/global.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ int viafb_lcd_dsp_method = LCD_EXPANDSION;
int viafb_lcd_mode = LCD_OPENLDI;
int viafb_bpp = 32;
int viafb_bpp1 = 32;
int viafb_accel = 1;
int viafb_CRT_ON = 1;
int viafb_DVI_ON;
int viafb_LCD_ON ;
Expand Down
1 change: 0 additions & 1 deletion drivers/video/via/hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -855,7 +855,6 @@ extern int viafb_dual_fb;
extern int viafb_LCD2_ON;
extern int viafb_LCD_ON;
extern int viafb_DVI_ON;
extern int viafb_accel;
extern int viafb_hotplug;

void viafb_write_reg_mask(u8 index, int io_port, u8 data, u8 mask);
Expand Down
Loading

0 comments on commit 31de59d

Please sign in to comment.