/* some pm2v driver hints ... */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include int save_vga(void) { 1. The 128K byte region at the base of the frame buffer is used for vga text mode font information. Save this region slowly, one byte at a time, to a static kernel array. 2. The 4K byte region at offset 0x6000 contains vga registers. Save this region to a static kernel array. 3. Save these register values - note that some are indirect: ApertureOne ApertureTwo FramebufferWriteMask BypassWriteMask DFIFODiscon FIFODiscon MemConfig VideoControl HgEnd ScreenBase VClkCtl ScreenStride HTotal HbEnd HsStart HsEnd VTotal VbEnd VsStart VsEnd ChipConfig PM2VDACRDIndexControl PM2VDACRDOverlayKey PM2VDACRDSyncControl PM2VDACRDMiscControl PM2VDACRDDACControl PM2VDACRDPixelSize PM2VDACRDColorFormat 4. It does no good to save the pixel clock - registers are write only. 5. Save the color palette. (Write 0 to RDPaletteReadAddress, then read from RDPaletteData.) return 0; } int restore_vga(void) { 1. Restore saved vga text mode font information to the frame buffer. 2. Restore saved vga registers. 3. Restore the other saved registers. 4. Reload the clock for vga timing: clockread = K_READ_INDIRECT_REG(PM2VDACIndexClockControl); clockread &= 0xfc; K_WRITE_INDIRECT_REG(PM2VDACRDDClk0m,0x1c); K_WRITE_INDIRECT_REG(PM2VDACRDDClk0n,0x02); K_WRITE_INDIRECT_REG(PM2VDACRDDClk0p,0x23); K_WRITE_INDIRECT_REG(PM2VDACIndexClockControl,clockread|(0x03)); 5. Restore the color palette. return 0; } void load_dac(void){ int i; FIFOSYNC; K_WRITE_REG(PM2VDACRDIndexControl,0x00000000); /* 8-bit DAC x01 and 32bpp 0x08 */ K_WRITE_INDIRECT_REG(PM2VDACRDMiscControl,0x09); /* no invert on hsync or vsync */ K_WRITE_INDIRECT_REG(PM2VDACRDSyncControl,0x00); K_WRITE_INDIRECT_REG(PM2VDACRDDACControl,0x00); /* 32 bpp ... other part */ K_WRITE_INDIRECT_REG(PM2VDACRDPixelSize,0x02); /* 8888 color */ K_WRITE_INDIRECT_REG(PM2VDACRDColorFormat,0x20); FIFOSYNC; /* load a standard palette */ K_WRITE_REG(RDPaletteWriteAddress,0x0); for(i=0;i<256;i++){ FIFOSYNC; K_WRITE_REG(RDPaletteData,i); K_WRITE_REG(RDPaletteData,i); K_WRITE_REG(RDPaletteData,i); } } void set_res_dependent_regs(int vmode) { unsigned int clockread; /* ignore vmode ... V_800x600_75Hz 32bpp is the only one supported */ 1. Determine appropriate values for this mode, and set these registers: ApertureOne ApertureTwo HTotal HsStart HsEnd HgEnd HbEnd VTotal VsStart VsEnd VbEnd ScissorMaxXY ScreenSize ScreenStride LBReadMode Window FBReadMode 2. Load the pixel clock with values for 800x600@75Hz: clockread = K_READ_INDIRECT_REG(PM2VDACIndexClockControl); clockread &= 0xfc; K_WRITE_INDIRECT_REG(PM2VDACRDDClk0m,0x1d); K_WRITE_INDIRECT_REG(PM2VDACRDDClk0n,0x64); K_WRITE_INDIRECT_REG(PM2VDACRDDClk0p,0x00); K_WRITE_INDIRECT_REG(PM2VDACIndexClockControl,clockread|(0x03)); } void load_control_defaults(void) { 1. Determine appropriate values, and set these registers: InterruptLine DisplayData FifoControl LineCount ScreenBaseRight ScreenBase IntFlags VClkCtl DMAControl FIFODiscon MemControl BypassWriteMask 2. Be sure to get these two right: K_WRITE_REG(BootAddress,0x00000020); K_WRITE_REG(MemConfig,0xe6002021); } void load_graphics_defaults(void){ Determine reasonable start values for all the registers >= 0x8000, and set them. } int pm2_mmap(struct file *fp, struct vm_area_struct *vma) { This is a 1-line call to io_remap_pfn_range(). } int pm2_ioctl(struct inode *inode, struct file *fp, unsigned int cmd, unsigned long arg) { unsigned int *uspace_ptr; unsigned int *udmaspace_ptr; struct page *page, *firstpage, *lastpage; struct file *memfp; unsigned int size, offset, prot, flags; switch(cmd){ case VMODE: /* get desired video mode from user space and set it */ vmode = (int)(arg); /* only one supported ... */ if(vmode==V_800x600_75Hz){ save_vga(); load_dac(); set_res_dependent_regs(vmode); load_control_defaults(); load_graphics_defaults(); /* draw a rectangle of size 800x600 in a recognizable color from kernel level */ clear_framebuffer(); /* light it up ... */ K_WRITE_REG(ChipConfig,0x00001404); K_WRITE_REG(VideoControl,0x0010029); return 0; } else{ /* * everything else is "V_OFF" */ Worry here about whether graphics are really done? K_WRITE_REG(ColorDDAMode,0x0); K_WRITE_REG(VideoControl,0x0); big_fat_sync(); restore_vga(); K_WRITE_REG(Reboot,0x00000001); K_WRITE_REG(ChipConfig,0x00001406); return 0; } break; case BIND_DMA: 1. for(i=0;i