[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, >t_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