[prev in list] [next in list] [prev in thread] [next in thread] 

List:       moblin-dev
Subject:    [Moblin Dev] IEGD driver text mode, before X loads
From:       "Steven" <k9 () tibetsystem ! com>
Date:       2008-11-17 11:31:41
Message-ID: 000801c948a8$1008fd60$301af820$ () com
[Download RAW message or body]



Hi all

I have one question. 
I Intel Graphics driver text mode , before X loads. ( kernel intel frame
buffer driver supports video overlay). 

I made kernel space overlay driver based on intelfbdrv.c and directfb gfx
overlay driver. But I don't know how to get overlay base address. 
I think I make the code get the overlay base address in function
"intelfb_fix_iface_pointers". but it's not working. 
How can I do that?
Maybe you can point me to the right direction.


Best Regards.
Steven.

/*
 * Overlay Registers(30000h-03ffffh)
 
                                  _____________________
                                 |_____________________|
                                 | Graphics Controller |
                                 | Registger Range     |
                                 |         (512 KB)       |
                                 | ------------------- |
                                 |  Overlay 0 Reg      |
base+301xxh                | ------------------- |
                                 |                     |
(Base = MMADR PCI Reg.)  |_____________________|
                                 |  Graphics Memory    |
                                 | ------------------- |
                                 |   Overlay 0 Reg     |
           Base+xxh          | ------------------- |
(Base = OV0ADD Reg. )   |                     |
                                 |_____________________|

 
 * 30000h-30003h OVADDR                    Overlay Register Update
Address(RW)
 * 30004h-30007h OTEST            Overlay Test Register(RW)
 * 30008h-3000Bh DOVSTA                    Display/Overlay Status 
 * 3000Ch-3000Fh DOVSTAEX       Display/Overlay Extended Status 
 */

/* 
 * Overlay Memory Offset Registers 
 * Register Mnemonic                On-chip Address offset
 */

typedef struct {
    uint32_t OBUF_0Y;      /* 30100h-30103h Overlay Buffer 0 Y Pointer */
    uint32_t OBUF_1Y;      /* 30104h-30107h Overlay Buffer 1 Y Pointer*/
    uint32_t OBUF_0U;     /* 30108h-3010Bh Overlay Buffer 0 U Pointer*/
    uint32_t OBUF_0V;     /* 3010Ch-3010Fh Overlay Buffer 0 V Pointer*/
    uint32_t OBUF_1U;     /* 30110h-30113h Overlay Buffer 1 U Pointer*/
    uint32_t OBUF_1V;     /* 30114h??0117h Overlay Buffer 1 V Pointer */
    uint32_t OSTRIDE;      /* 30118h??011Bh Overlay Stride */
    uint32_t YRGB_VPH;    /* 3011Ch??011Fh Y/RGB Vertical Phase 0/1 */
    uint32_t UV_VPH;       /* 30120h??0123h UV Vertical Phase 0/1 */
    uint32_t HORZ_PH;     /* 30124h??0127h Horizontal Phase */
    uint32_t INIT_PHS;      /* 30128h??012Bh Initial Phase Shift */
    uint32_t DWINPOS;     /* 3012Ch-3012Fh Destination Window Position */
    uint32_t DWINSZ;      /* 30130h-30133h Destination Window Size */
    uint32_t SWIDTH;       /* 30134h-30137h Source Width */
    uint32_t SWIDTHSW;   /* 3013Ch??013Fh Source Height */
    uint32_t SHEIGHT;      /* 3013Ch-3013Fh Source Height */
    uint32_t YRGBSCALE;   /* 30140h-30143h Y/RGB Scale Factor */
    uint32_t UVSCALE;      /* 30144h-30147h U V Scale Factor */
    uint32_t OCLRC0;       /* 30148h??014Bh Overlay Color Correction 0 */
    uint32_t OCLRC1;       /* 3014Ch??014Fh Overlay Color Correction 1 */
    uint32_t DCLRKV;       /* 30150h-30153h Destination Color Key Value */
    uint32_t DCLRKM;      /* 30154h-30157h Destination Color Key Mask */
    uint32_t SCLRKVH;      /* 30158h??015Bh Source Chroma Key Value High */
    uint32_t SCLRKVL;      /* 3015Ch??015Fh Source Chroma Key Value Low */
    uint32_t SCLRKEN;      /* 30160h??0163h Source Chroma Key Enable */
    uint32_t OCONFIG;     /* 30164h-30167h Overlay Configuration */
    uint32_t OCMD;         /* 30168h-3016Bh Overlay Command */
    uint32_t RESERVED1; /* 0x6C */
    uint32_t OSTART_0Y;   /* 30170h-30173h Overlay Surface Y 0 Base Address
for i965 */
    uint32_t OSTART_1Y;   /* 30174h-30177h Overlay Surface Y 1 Base Address
for i965 */
    uint32_t OSTART_0U;
    uint32_t OSTART_0V;
    uint32_t OSTART_1U;
    uint32_t OSTART_1V;
    uint32_t OTILEOFF_0Y;
    uint32_t OTILEOFF_1Y;
    uint32_t OTILEOFF_0U;
    uint32_t OTILEOFF_0V;
    uint32_t OTILEOFF_1U;
    uint32_t OTILEOFF_1V;
    uint32_t FASTHSCALE;                  /* 0xA0 */
    uint32_t UVSCALEV;                    /* 0xA4 */


    uint32_t RESERVEDC[(0x200 - 0xA8) / 4];                  /* 0xA8 - 0x1FC
*/
    uint16_t Y_VCOEFS[N_VERT_Y_TAPS * N_PHASES];             /* 0x200 */
    uint16_t RESERVEDD[0x100 / 2 - N_VERT_Y_TAPS * N_PHASES];
    uint16_t Y_HCOEFS[N_HORIZ_Y_TAPS * N_PHASES];            /* 0x300 */
    uint16_t RESERVEDE[0x200 / 2 - N_HORIZ_Y_TAPS * N_PHASES];
    uint16_t UV_VCOEFS[N_VERT_UV_TAPS * N_PHASES];                   /*
0x500 */
    uint16_t RESERVEDF[0x100 / 2 - N_VERT_UV_TAPS * N_PHASES];
    uint16_t UV_HCOEFS[N_HORIZ_UV_TAPS * N_PHASES];          /* 0x600 */
    uint16_t RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES]; /*
30768h??07FFh */
} IntelOverlayRegRec, *IntelOverlayRegPtr

IntelOverlayRegPtr = g_overlay_ptr;

static void intel_overlay_test(struct intelfb_info *dinfo)
{
           
           IntelOverlayRegPtr   overlay;
           int width = 1024;
           int height = 768;
           overlay = g_overlay_ptr;

           overlay->SWIDTH = width | ((width/2 & 0x7ff) << 16);
           overlay->SHEIGHT = height | ((height / 2) << 16);

           START_RING(6);
           OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE);
           OUT_RING(MI_NOOP);

           OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE);

           //OUT_RING(overlay);
           //OUT_RING(g_ovl_start_phys |  OFC_UPDATE);
           OUT_RING( g_overlay_ptr );
           OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
           OUT_RING(MI_NOOP);
           ADVANCE_RING();
}

static int intelvid_ioctl(struct inode *inode, struct file *file, unsigned
int cmd, unsigned long arg)
{
           switch(cmd){
           case INTELVID_OVERLAY_TEST:
                     DBG_MSG("INTELVID_OVERLAY_TEST\n");
                     intel_overlay_test(g_dinfo);
                     break;
           }
}

void intelfb_fix_iface_pointers(u32 fb_size, u32 aper_size, 
                     u32 fb_base_phys, u32 fb_base_virtual,
                     u32 cursor_phys, u32 cursor_virtual)
{
           printk("[%s] enter\n", __func__);
           g_ovl_start_phys = cursor_phys + 1024;
           g_ovl_start_virt =(u32*) (cursor_virtual + 1024);
           //g_overlay_ptr =(volatile IntelOverlayRegPtr)
(g_ovl_start_phys);
           printk("[%s]g_ovl_start_phys:%lx leave\n", __func__,
g_ovl_start_phys);
           g_overlay_ptr =(volatile IntelOverlayRegPtr) (g_ovl_start_virt);
           printk("[%s]g_ovl_start_virt:%lx leave\n", __func__,
g_ovl_start_virt);
}
static int __devinit intelfb_pci_register(struct pci_dev *pdev, const struct
pci_device_id *ent)
{
struct fb_info *info;
        struct intelfb_info *dinfo;
        int i, err, dvo;
        int aperture_size, stolen_size;
        struct agp_kern_info gtt_info;
        int agp_memtype;
        const char *s;
        struct agp_bridge_data *bridge;
        int aperture_bar = 0;
        int mmio_bar = 1;
        int offset;

           DBG_MSG("intelfb_pci_register\n");

        info = framebuffer_alloc(sizeof(struct intelfb_info), &pdev->dev);
        if (!info) {
                ERR_MSG("Could not allocate memory for intelfb_info.\n");
                return -ENODEV;
        }
        if (fb_alloc_cmap(&info->cmap, 256, 1) < 0) {
                ERR_MSG("Could not allocate cmap for intelfb_info.\n");
                goto err_out_cmap;
                return -ENODEV;
        }

dinfo = info->par;
        dinfo->info  = info;
#if 0 //Steven
        dinfo->fbops = &intel_fb_ops;
#else
        //dinfo->fbops = &intelvid_fops;
#endif
        dinfo->pdev  = pdev;

        /* Reserve pixmap space. */
        info->pixmap.addr = kzalloc(64 * 1024, GFP_KERNEL);
        if (info->pixmap.addr == NULL) {
                //ERR_MSG("Cannot reserve pixmap memory.\n");
                printk(KERN_ERR"Cannot reserve pixmap memory.\n");
                goto err_out_pixmap;
        }

        /* set early this option because it could be changed by tv encoder
           driver */
        dinfo->fixed_mode = fixed;

        /* Enable device. */
        if ((err = pci_enable_device(pdev))) {
                //ERR_MSG("Cannot enable device.\n");
                printk(KERN_ERR"Cannot enable device.\n");
                cleanup(dinfo);
                return -ENODEV;
        }

        /* Set base addresses. */
        if ((ent->device == PCI_DEVICE_ID_INTEL_915G) ||
            (ent->device == PCI_DEVICE_ID_INTEL_915GM) ||
            (ent->device == PCI_DEVICE_ID_INTEL_945G)  ||
            (ent->device == PCI_DEVICE_ID_INTEL_945GM)) {
                aperture_bar = 2;
                mmio_bar = 0;
        }

        dinfo->aperture.physical = pci_resource_start(pdev, aperture_bar);
        dinfo->aperture.size     = pci_resource_len(pdev, aperture_bar);
dinfo->mmio_base_phys    = pci_resource_start(pdev, mmio_bar);
        printk("fb aperture: 0x%llx/0x%llx, MMIO region: 0x%llx/0x%llx\n",
                (unsigned long long)pci_resource_start(pdev, aperture_bar),
                (unsigned long long)pci_resource_len(pdev, aperture_bar),
                (unsigned long long)pci_resource_start(pdev, mmio_bar),
                (unsigned long long)pci_resource_len(pdev, mmio_bar));

#if 0 //kscho
        /* Reserve the fb and MMIO regions */
        if (!request_mem_region(dinfo->aperture.physical,
dinfo->aperture.size,
                                INTELFB_MODULE_NAME)) {
                ERR_MSG("Cannot reserve FB region.\n");
                cleanup(dinfo);
                return -ENODEV;
        }

        dinfo->flag |= INTELFB_FB_ACQUIRED;

        if (!request_mem_region(dinfo->mmio_base_phys,
                                INTEL_REG_SIZE,
                                INTELFB_MODULE_NAME)) {
                ERR_MSG("Cannot reserve MMIO region.\n");
                cleanup(dinfo);
                return -ENODEV;
        }

        dinfo->flag |= INTELFB_MMIO_ACQUIRED;
#endif
           /* Get the chipset info. */
        dinfo->pci_chipset = pdev->device;
#if 1 //kscho added
           g_IntelRec.PciInfo = pdev->device;
#endif
        if (intelfbhw_get_chipset(pdev, dinfo)) {
                cleanup(dinfo);
                return -ENODEV;
        }

        if (intelfbhw_get_memory(pdev, &aperture_size,&stolen_size)) {
                cleanup(dinfo);
                return -ENODEV;
        }

        INF_MSG("%02x:%02x.%d: %s, aperture size %dMB, " "stolen memory
%dkB\n",
                pdev->bus->number, PCI_SLOT(pdev->devfn),
PCI_FUNC(pdev->devfn), dinfo->name,
                BtoMB(aperture_size), BtoKB(stolen_size));


           /* Set these from the options. */
        dinfo->accel    = accel;
        dinfo->hwcursor = hwcursor;

           if (NOACCEL_CHIPSET(dinfo) && dinfo->accel == 1) {
                INF_MSG("Acceleration is not supported for the %s
chipset.\n",
                        dinfo->name);
                dinfo->accel = 0;
        }

           /* Framebuffer parameters - Use all the stolen memory if >= vram
*/
        if (ROUND_UP_TO_PAGE(stolen_size) >= MB(vram)) {
                dinfo->fb.size = ROUND_UP_TO_PAGE(stolen_size);
                dinfo->fbmem_gart = 0;
        } else {
                dinfo->fb.size =  MB(vram);
                dinfo->fbmem_gart = 1;
        }


        /* Allocate space for the ring buffer and HW cursor if enabled. */
        if (dinfo->accel) {
                dinfo->ring.size = RINGBUFFER_SIZE;
                dinfo->ring_tail_mask = dinfo->ring.size - 1;
        }
        if (dinfo->hwcursor){
                dinfo->cursor.size = HW_CURSOR_SIZE;
           }

#if 1 //kscho
        /* Use agpgart to manage the GATT */
        if (!(bridge = agp_backend_acquire(pdev))) {
                ERR_MSG("cannot acquire agp\n");
                cleanup(dinfo);
                return -ENODEV;
        }
#else
           if (!(bridge = agp_find_bridge(pdev))) {
                ERR_MSG("cannot find agp\n");
                cleanup(dinfo);
                return -ENODEV;
           }
#endif

        /* get the current gatt info */
        if (agp_copy_info(bridge, &gtt_info)) {
                ERR_MSG("cannot get agp info\n");
                //agp_backend_release(bridge);
                cleanup(dinfo);
                return -ENODEV;
        }

           printk("[%s:%d]voffset:%d\n", __func__, __LINE__, voffset);
        if (MB(voffset) < stolen_size)
                offset = (stolen_size >> 12);
        else
                offset = ROUND_UP_TO_PAGE(MB(voffset))/GTT_PAGE_SIZE;

        /* set the mem offsets - set them after the already used pages */
        if (dinfo->accel)
                dinfo->ring.offset = offset + gtt_info.current_memory;
           if (dinfo->hwcursor) {
                dinfo->cursor.offset = offset +
                        + gtt_info.current_memory + (dinfo->ring.size >>
12);
        }
        if (dinfo->fbmem_gart) {
                dinfo->fb.offset = offset +
                        + gtt_info.current_memory + (dinfo->ring.size >> 12)
                        + (dinfo->cursor.size >> 12);
           }

           /* Allocate memories (which aren't stolen) */
        /* Map the fb and MMIO regions */
        /* ioremap only up to the end of used aperture */
#if 1
        dinfo->aperture.virtual = (u8 __iomem *)ioremap_nocache
                (dinfo->aperture.physical, ((offset + dinfo->fb.offset) <<
12) + dinfo->fb.size);
#else
        dinfo->aperture.virtual = (u8 __iomem *)ioremap_nocache
                (dinfo->aperture.physical, 131072);
#endif
        if (!dinfo->aperture.virtual) {
                ERR_MSG("Cannot remap FB region.\n");
                cleanup(dinfo);
                return -ENODEV;
        }


        dinfo->mmio_base =
                (u8 __iomem *)ioremap_nocache(dinfo->mmio_base_phys,
                                              INTEL_REG_SIZE);

        if (!dinfo->mmio_base) {
                ERR_MSG("Cannot remap MMIO region.\n");
                cleanup(dinfo);
                return -ENODEV;
        }

           if(dinfo->accel){
                     printk("[%s:%d]dinfo->accel\n", __func__, __LINE__);
#if 1
                      if (!(dinfo->gtt_ring_mem =
                      agp_allocate_memory(bridge, dinfo->ring.size >> 12,
                                          AGP_NORMAL_MEMORY))) {
                        ERR_MSG("cannot allocate ring buffer memory\n");
                        agp_backend_release(bridge);
                        cleanup(dinfo);
                        return -ENOMEM;
                }
                if (agp_bind_memory(dinfo->gtt_ring_mem,
                                    dinfo->ring.offset)) {
                        ERR_MSG("cannot bind ring buffer memory\n");
                        agp_backend_release(bridge);
                        cleanup(dinfo);
                        return -EBUSY;
                }
#endif
                     dinfo->ring.physical = dinfo->aperture.physical
                        + (dinfo->ring.offset << 12);

                dinfo->ring.virtual  = dinfo->aperture.virtual
                        + (dinfo->ring.offset << 12);
                dinfo->ring_head = 0;
           }

        if (dinfo->hwcursor) {
                DBG_MSG("[%d]dinfo->hwcursor\n", __LINE__);
#if 1
                agp_memtype = dinfo->mobile ? AGP_PHYSICAL_MEMORY
                        : AGP_NORMAL_MEMORY;

                DBG_MSG("agp_memtype:%d\n", agp_memtype);
                     if(agp_memtype == AGP_PHYSICAL_MEMORY){
                     DBG_MSG("dinfo->hwcursor AGP_PHYSICAL_MEMORY\n");
                     }else{
                     DBG_MSG("dinfo->hwcursor AGP_NORMAL_MEMORY\n");
                     }

                if (!(dinfo->gtt_cursor_mem =
                      agp_allocate_memory(bridge, dinfo->cursor.size >> 12,
                                          agp_memtype))) {
                        ERR_MSG("cannot allocate cursor memory\n");
                        agp_backend_release(bridge);
                        cleanup(dinfo);
                        return -ENOMEM;
                }
                if (agp_bind_memory(dinfo->gtt_cursor_mem,
                                    dinfo->cursor.offset)) {
                        ERR_MSG("cannot bind cursor memory\n");
                        agp_backend_release(bridge);
                        cleanup(dinfo);
                        return -EBUSY;
                }
                if (dinfo->mobile)
                        dinfo->cursor.physical
                                = dinfo->gtt_cursor_mem->physical;
                else
                        dinfo->cursor.physical = dinfo->aperture.physical
                                + (dinfo->cursor.offset << 12);
                dinfo->cursor.virtual = dinfo->aperture.virtual
                        + (dinfo->cursor.offset << 12);
#endif
        }

#if 1 //kscho, 2008/11/14
        if (dinfo->fbmem_gart) {

                if (!(dinfo->gtt_fb_mem =
                      agp_allocate_memory(bridge, dinfo->fb.size >> 12,
                                          AGP_NORMAL_MEMORY))) {
                        WRN_MSG("cannot allocate framebuffer memory - use "
                                "the stolen one\n");
                        dinfo->fbmem_gart = 0;
                }
                if (agp_bind_memory(dinfo->gtt_fb_mem,
                                    dinfo->fb.offset)) {
                        WRN_MSG("cannot bind framebuffer memory - use "
                                "the stolen one\n");
                        dinfo->fbmem_gart = 0;
                }
        }
#endif


        /* update framebuffer memory parameters */
        if (!dinfo->fbmem_gart){
                dinfo->fb.offset = 0;   /* starts at offset 0 */
                     printk("[%s]starts at offset 0\n", __func__);
           }
        dinfo->fb.physical = dinfo->aperture.physical
                + (dinfo->fb.offset << 12);
        dinfo->fb.virtual = dinfo->aperture.virtual + (dinfo->fb.offset <<
12);
        dinfo->fb_start = dinfo->fb.offset << 12;

           intelfb_fix_iface_pointers(dinfo->fb.size,  dinfo->aperture.size,
                                dinfo->fb.physical, dinfo->fb.virtual, 
                                dinfo->cursor.physical,
dinfo->cursor.virtual);


           /* release agpgart */
        agp_backend_release(bridge);

#if 1
        if (mtrr)
                set_mtrr(dinfo);
#endif

        DBG_MSG("fb: 0x%x(+ 0x%x)/0x%x (0x%p)\n",
                dinfo->fb.physical, dinfo->fb.offset, dinfo->fb.size,
                dinfo->fb.virtual);
        DBG_MSG("MMIO: 0x%x/0x%x (0x%p)\n",
                dinfo->mmio_base_phys, INTEL_REG_SIZE,
                dinfo->mmio_base);
        DBG_MSG("ring buffer: 0x%x/0x%x (0x%p)\n",
                dinfo->ring.physical, dinfo->ring.size,
                dinfo->ring.virtual);
        DBG_MSG("HW cursor: 0x%x/0x%x (0x%p) (offset 0x%x) (phys 0x%x)\n",
                dinfo->cursor.physical, dinfo->cursor.size,
                dinfo->cursor.virtual, dinfo->cursor.offset,
                dinfo->cursor.physical);

        DBG_MSG("options: vram = %d, accel = %d, hwcursor = %d, fixed = %d,
"
                "noinit = %d\n", vram, accel, hwcursor, fixed, noinit);
        DBG_MSG("options: mode = \"%s\"\n", mode ? mode : "");



           
        pci_set_drvdata(pdev, dinfo);
           g_dinfo = dinfo;
           
           
#if 0
        /* 2d acceleration init */
        if (dinfo->accel){
                     //intelfbhw_2d_stop(dinfo);
                intelfbhw_2d_start(dinfo);
           }
#endif

#if 1
           //intel_overlay_test(dinfo);
#endif
           return 0;
err_out_pixmap:
        fb_dealloc_cmap(&info->cmap);
err_out_cmap:
        framebuffer_release(info);
        return -ENODEV;
}


---------------------------------------------------------------------
6F Lotte IT Castle II 550-1 Gasan-dong, 
Geumcheon-gu, Seoul, 153-768, Korea
Research Engineer/R&D software Team
Tel: 82-2-890-1657(Direct)
FAX:02-890-1639


_______________________________________________
Moblin dev Mailing List
dev@lists.moblin.org

To manage or unsubscribe from this mailing list visit:
https://lists.moblin.org/mailman/listinfo/dev or your user account on http://moblin.org once logged in.

For more information on the Moblin Developer Mailing lists visit:
http://moblin.org/community/mailing-lists
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic