static struct pixclock * acornfb_valid_pixrate(struct fb_var_screeninfo *var) { u_long pixclock = var->pixclock; u_int i; if (!var->pixclock) return NULL; for (i = 0; i < ARRAY_SIZE(arc_clocks); i++) if (pixclock > arc_clocks[i].min_clock && pixclock < arc_clocks[i].max_clock) return arc_clocks + i; #ifdef CONFIG_ARCH_A5K if (machine_is_a5k()) { for (i = 0; i < ARRAY_SIZE(a5k_clocks); i++) if (pixclock > a5k_clocks[i].min_clock && pixclock < a5k_clocks[i].max_clock) return a5k_clocks + i; } #endif return NULL; }
void __init arch_dma_init(dma_t *dma) { #if defined(CONFIG_BLK_DEV_FD1772) || defined(CONFIG_BLK_DEV_FD1772_MODULE) if (machine_is_archimedes()) { dma[DMA_VIRTUAL_FLOPPY0].dma_irq = FIQ_FLOPPYDATA; dma[DMA_VIRTUAL_FLOPPY0].d_ops = &arc_floppy_data_dma_ops; dma[DMA_VIRTUAL_FLOPPY1].dma_irq = 1; dma[DMA_VIRTUAL_FLOPPY1].d_ops = &arc_floppy_cmdend_dma_ops; } #endif #ifdef CONFIG_ARCH_A5K if (machine_is_a5k()) { dma[DMA_VIRTUAL_FLOPPY0].dma_irq = FIQ_FLOPPYDATA; dma[DMA_VIRTUAL_FLOPPY0].d_ops = &a5k_floppy_dma_ops; } #endif dma[DMA_VIRTUAL_SOUND].d_ops = &sound_dma_ops; }
/* VIDC Rules: * hcr : must be even (interlace, hcr/2 must be even) * hswr : must be even * hdsr : must be odd * hder : must be odd * * vcr : must be odd * vswr : >= 1 * vdsr : >= 1 * vder : >= vdsr * if interlaced, then hcr/2 must be even */ static void acornfb_set_timing(struct fb_var_screeninfo *var) { struct pixclock *pclk; struct vidc_timing vidc; u_int horiz_correction; u_int sync_len, display_start, display_end, cycle; u_int is_interlaced; u_int vid_ctl, vidc_ctl; u_int bandwidth; memset(&vidc, 0, sizeof(vidc)); pclk = acornfb_valid_pixrate(var); vidc_ctl = pclk->vidc_ctl; vid_ctl = pclk->vid_ctl; bandwidth = var->pixclock * 8 / var->bits_per_pixel; /* 25.175, 4bpp = 79.444ns per byte, 317.776ns per word: fifo = 2,6 */ if (bandwidth > 143500) vidc_ctl |= VIDC_CTRL_FIFO_3_7; else if (bandwidth > 71750) vidc_ctl |= VIDC_CTRL_FIFO_2_6; else if (bandwidth > 35875) vidc_ctl |= VIDC_CTRL_FIFO_1_5; else vidc_ctl |= VIDC_CTRL_FIFO_0_4; switch (var->bits_per_pixel) { case 1: horiz_correction = 19; vidc_ctl |= VIDC_CTRL_1BPP; break; case 2: horiz_correction = 11; vidc_ctl |= VIDC_CTRL_2BPP; break; case 4: horiz_correction = 7; vidc_ctl |= VIDC_CTRL_4BPP; break; default: case 8: horiz_correction = 5; vidc_ctl |= VIDC_CTRL_8BPP; break; } if (var->sync & FB_SYNC_COMP_HIGH_ACT) /* should be FB_SYNC_COMP */ vidc_ctl |= VIDC_CTRL_CSYNC; else { if (!(var->sync & FB_SYNC_HOR_HIGH_ACT)) vid_ctl |= VID_CTL_HS_NHSYNC; if (!(var->sync & FB_SYNC_VERT_HIGH_ACT)) vid_ctl |= VID_CTL_VS_NVSYNC; } sync_len = var->hsync_len; display_start = sync_len + var->left_margin; display_end = display_start + var->xres; cycle = display_end + var->right_margin; /* if interlaced, then hcr/2 must be even */ is_interlaced = (var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED; if (is_interlaced) { vidc_ctl |= VIDC_CTRL_INTERLACE; if (cycle & 2) { cycle += 2; var->right_margin += 2; } } vidc.h_cycle = (cycle - 2) / 2; vidc.h_sync_width = (sync_len - 2) / 2; vidc.h_border_start = (display_start - 1) / 2; vidc.h_display_start = (display_start - horiz_correction) / 2; vidc.h_display_end = (display_end - horiz_correction) / 2; vidc.h_border_end = (display_end - 1) / 2; vidc.h_interlace = (vidc.h_cycle + 1) / 2; sync_len = var->vsync_len; display_start = sync_len + var->upper_margin; display_end = display_start + var->yres; cycle = display_end + var->lower_margin; if (is_interlaced) cycle = (cycle - 3) / 2; else cycle = cycle - 1; vidc.v_cycle = cycle; vidc.v_sync_width = sync_len - 1; vidc.v_border_start = display_start - 1; vidc.v_display_start = vidc.v_border_start; vidc.v_display_end = display_end - 1; vidc.v_border_end = vidc.v_display_end; if (machine_is_a5k()) __raw_writeb(vid_ctl, IOEB_VID_CTL); if (memcmp(¤t_vidc, &vidc, sizeof(vidc))) { current_vidc = vidc; vidc_writel(0xe0000000 | vidc_ctl); vidc_writel(0x80000000 | (vidc.h_cycle << 14)); vidc_writel(0x84000000 | (vidc.h_sync_width << 14)); vidc_writel(0x88000000 | (vidc.h_border_start << 14)); vidc_writel(0x8c000000 | (vidc.h_display_start << 14)); vidc_writel(0x90000000 | (vidc.h_display_end << 14)); vidc_writel(0x94000000 | (vidc.h_border_end << 14)); vidc_writel(0x98000000); vidc_writel(0x9c000000 | (vidc.h_interlace << 14)); vidc_writel(0xa0000000 | (vidc.v_cycle << 14)); vidc_writel(0xa4000000 | (vidc.v_sync_width << 14)); vidc_writel(0xa8000000 | (vidc.v_border_start << 14)); vidc_writel(0xac000000 | (vidc.v_display_start << 14)); vidc_writel(0xb0000000 | (vidc.v_display_end << 14)); vidc_writel(0xb4000000 | (vidc.v_border_end << 14)); vidc_writel(0xb8000000); vidc_writel(0xbc000000); } #ifdef DEBUG_MODE_SELECTION printk(KERN_DEBUG "VIDC registers for %dx%dx%d:\n", var->xres, var->yres, var->bits_per_pixel); printk(KERN_DEBUG " H-cycle : %d\n", vidc.h_cycle); printk(KERN_DEBUG " H-sync-width : %d\n", vidc.h_sync_width); printk(KERN_DEBUG " H-border-start : %d\n", vidc.h_border_start); printk(KERN_DEBUG " H-display-start : %d\n", vidc.h_display_start); printk(KERN_DEBUG " H-display-end : %d\n", vidc.h_display_end); printk(KERN_DEBUG " H-border-end : %d\n", vidc.h_border_end); printk(KERN_DEBUG " H-interlace : %d\n", vidc.h_interlace); printk(KERN_DEBUG " V-cycle : %d\n", vidc.v_cycle); printk(KERN_DEBUG " V-sync-width : %d\n", vidc.v_sync_width); printk(KERN_DEBUG " V-border-start : %d\n", vidc.v_border_start); printk(KERN_DEBUG " V-display-start : %d\n", vidc.v_display_start); printk(KERN_DEBUG " V-display-end : %d\n", vidc.v_display_end); printk(KERN_DEBUG " V-border-end : %d\n", vidc.v_border_end); printk(KERN_DEBUG " VIDC Ctrl (E) : 0x%08X\n", vidc_ctl); printk(KERN_DEBUG " IOEB Ctrl : 0x%08X\n", vid_ctl); #endif }