From f064c3cbc1fc68c7e08bc43400fa2940de575e39 Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Sat, 24 Oct 2009 21:42:25 +0000 Subject: [PATCH] kms: add r600 and r700 read command line git-svn-id: svn://kolibrios.org@1233 a494cfbc-eb01-0410-851d-a64ba20cac60 --- drivers/video/drm/drm_crtc_helper.c | 12 - drivers/video/drm/includes/linux/seq_file.h | 2 + drivers/video/drm/includes/syscall.h | 23 ++ drivers/video/drm/radeon/atikms.asm | 2 +- drivers/video/drm/radeon/makefile | 2 + drivers/video/drm/radeon/r600.c | 90 ++++--- drivers/video/drm/radeon/radeon.h | 13 +- drivers/video/drm/radeon/radeon_asic.h | 85 ++++++ drivers/video/drm/radeon/radeon_bios.c | 46 +++- drivers/video/drm/radeon/radeon_connectors.c | 6 +- drivers/video/drm/radeon/radeon_device.c | 104 +++++--- drivers/video/drm/radeon/radeon_fb.c | 103 +------- drivers/video/drm/radeon/rdisplay.c | 259 ++++++++++++++++--- 13 files changed, 513 insertions(+), 234 deletions(-) diff --git a/drivers/video/drm/drm_crtc_helper.c b/drivers/video/drm/drm_crtc_helper.c index 66b5820922..7294e7286f 100644 --- a/drivers/video/drm/drm_crtc_helper.c +++ b/drivers/video/drm/drm_crtc_helper.c @@ -1153,18 +1153,6 @@ int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, } EXPORT_SYMBOL(drm_helper_mode_fill_fb_struct); -void sysSetScreen(int width, int height, int pitch) -{ - asm __volatile__ - ( - "call *__imp__SetScreen" - : - :"a" (width-1),"d"(height-1), "c"(pitch) - :"memory","cc" - ); -} - - int drm_helper_resume_force_mode(struct drm_device *dev) { struct drm_crtc *crtc; diff --git a/drivers/video/drm/includes/linux/seq_file.h b/drivers/video/drm/includes/linux/seq_file.h index 22c5845034..fc43a40a55 100644 --- a/drivers/video/drm/includes/linux/seq_file.h +++ b/drivers/video/drm/includes/linux/seq_file.h @@ -1 +1,3 @@ /* stub */ + +#include diff --git a/drivers/video/drm/includes/syscall.h b/drivers/video/drm/includes/syscall.h index 418f3254c8..c0397e4b69 100644 --- a/drivers/video/drm/includes/syscall.h +++ b/drivers/video/drm/includes/syscall.h @@ -52,6 +52,7 @@ int STDCALL UserFree(void *mem)__asm__("UserFree"); void* STDCALL GetDisplay()__asm__("GetDisplay"); +addr_t STDCALL AllocPage()__asm__("AllocPage"); addr_t STDCALL AllocPages(count_t count)__asm__("AllocPages"); void* STDCALL CreateRingBuffer(size_t size, u32_t map)__asm__("CreateRingBuffer"); @@ -346,6 +347,28 @@ static inline void change_task() "call *__imp__ChangeTask"); } +static inline sysSetScreen(int width, int height, int pitch) +{ + __asm__ __volatile__ + ( + "call *__imp__SetScreen" + : + :"a" (width-1),"d"(height-1), "c"(pitch) + ); + __asm__ __volatile__ + ("" :::"eax","ecx","edx"); +} + int drm_order(unsigned long size); +static inline void __iomem *ioremap(uint32_t offset, size_t size) +{ + return (void __iomem*) MapIoMem(offset, size, 3); +} + +static inline void iounmap(void *addr) +{ + FreeKernelSpace(addr); +} + #endif diff --git a/drivers/video/drm/radeon/atikms.asm b/drivers/video/drm/radeon/atikms.asm index 249fbd0059..ff48074257 100644 --- a/drivers/video/drm/radeon/atikms.asm +++ b/drivers/video/drm/radeon/atikms.asm @@ -21,7 +21,7 @@ start: int 0x40 sz_kms db '/rd/1/drivers/atikms.dll',0 -sz_mode db '1024x768',0 +sz_mode db '-m 1024x768 -l/hd0/2/atikms.log',0 align 4 i_end: diff --git a/drivers/video/drm/radeon/makefile b/drivers/video/drm/radeon/makefile index 4560b79b6c..402a07410d 100644 --- a/drivers/video/drm/radeon/makefile +++ b/drivers/video/drm/radeon/makefile @@ -64,9 +64,11 @@ NAME_SRC= \ r420.c \ rv515.c \ r520.c \ + r600.c \ rs400.c \ rs600.c \ rs690.c \ + rv770.c \ radeon_fb.c \ rdisplay.c diff --git a/drivers/video/drm/radeon/r600.c b/drivers/video/drm/radeon/r600.c index 4fce504ead..e35c9d5ecc 100644 --- a/drivers/video/drm/radeon/r600.c +++ b/drivers/video/drm/radeon/r600.c @@ -25,7 +25,7 @@ * Alex Deucher * Jerome Glisse */ -#include +#include #include #include "drmP.h" #include "radeon_drm.h" @@ -207,8 +207,8 @@ void r600_pcie_gart_disable(struct radeon_device *rdev) WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp); WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp); if (rdev->gart.table.vram.robj) { - radeon_object_kunmap(rdev->gart.table.vram.robj); - radeon_object_unpin(rdev->gart.table.vram.robj); +// radeon_object_kunmap(rdev->gart.table.vram.robj); +// radeon_object_unpin(rdev->gart.table.vram.robj); } } @@ -1137,7 +1137,31 @@ void r600_cp_commit(struct radeon_device *rdev) (void)RREG32(CP_RB_WPTR); } +void r600_ring_init(struct radeon_device *rdev, unsigned ring_size) +{ + u32 rb_bufsz; + /* Align ring size */ + rb_bufsz = drm_order(ring_size / 8); + ring_size = (1 << (rb_bufsz + 1)) * 4; + rdev->cp.ring_size = ring_size; + rdev->cp.align_mask = 16 - 1; +} + + +/* + * GPU scratch registers helpers function. + */ +void r600_scratch_init(struct radeon_device *rdev) +{ + int i; + + rdev->scratch.num_reg = 7; + for (i = 0; i < rdev->scratch.num_reg; i++) { + rdev->scratch.free[i] = true; + rdev->scratch.reg[i] = SCRATCH_REG0 + (i * 4); + } +} int r600_set_surface_reg(struct radeon_device *rdev, int reg, uint32_t tiling_flags, uint32_t pitch, uint32_t offset, uint32_t obj_size) @@ -1183,24 +1207,24 @@ int r600_startup(struct radeon_device *rdev) } r600_gpu_init(rdev); - r = radeon_object_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, - &rdev->r600_blit.shader_gpu_addr); - if (r) { - DRM_ERROR("failed to pin blit object %d\n", r); - return r; - } +// r = radeon_object_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, +// &rdev->r600_blit.shader_gpu_addr); +// if (r) { +// DRM_ERROR("failed to pin blit object %d\n", r); +// return r; +// } - r = radeon_ring_init(rdev, rdev->cp.ring_size); - if (r) - return r; - r = r600_cp_load_microcode(rdev); - if (r) - return r; - r = r600_cp_resume(rdev); - if (r) - return r; +// r = radeon_ring_init(rdev, rdev->cp.ring_size); +// if (r) +// return r; +// r = r600_cp_load_microcode(rdev); +// if (r) +// return r; +// r = r600_cp_resume(rdev); +// if (r) +// return r; /* write back buffer are not vital so don't worry about failure */ - r600_wb_enable(rdev); +// r600_wb_enable(rdev); return 0; } @@ -1279,27 +1303,27 @@ int r600_init(struct radeon_device *rdev) r = radeon_object_init(rdev); if (r) return r; - rdev->cp.ring_obj = NULL; - r600_ring_init(rdev, 1024 * 1024); +// rdev->cp.ring_obj = NULL; +// r600_ring_init(rdev, 1024 * 1024); - if (!rdev->me_fw || !rdev->pfp_fw) { - r = r600_cp_init_microcode(rdev); - if (r) { - DRM_ERROR("Failed to load firmware!\n"); - return r; - } - } +// if (!rdev->me_fw || !rdev->pfp_fw) { +// r = r600_cp_init_microcode(rdev); +// if (r) { +// DRM_ERROR("Failed to load firmware!\n"); +// return r; +// } +// } r = r600_pcie_gart_init(rdev); if (r) return r; rdev->accel_working = true; - r = r600_blit_init(rdev); - if (r) { - DRM_ERROR("radeon: failled blitter (%d).\n", r); - return r; - } +// r = r600_blit_init(rdev); +// if (r) { +// DRM_ERROR("radeon: failled blitter (%d).\n", r); +// return r; +// } r = r600_startup(rdev); if (r) { diff --git a/drivers/video/drm/radeon/radeon.h b/drivers/video/drm/radeon/radeon.h index c7011ffa5f..84282793e4 100644 --- a/drivers/video/drm/radeon/radeon.h +++ b/drivers/video/drm/radeon/radeon.h @@ -94,6 +94,13 @@ extern int radeon_testing; extern int radeon_connector_table; extern int radeon_tv; +typedef struct +{ + int width; + int height; + int bpp; + int freq; +}mode_t; static inline uint8_t __raw_readb(const volatile void __iomem *addr) { @@ -1125,12 +1132,6 @@ extern int r600_gpu_reset(struct radeon_device *rdev); - - - - - - #define DRM_UDELAY(d) udelay(d) resource_size_t diff --git a/drivers/video/drm/radeon/radeon_asic.h b/drivers/video/drm/radeon/radeon_asic.h index c4911dafe1..60f858a4dc 100644 --- a/drivers/video/drm/radeon/radeon_asic.h +++ b/drivers/video/drm/radeon/radeon_asic.h @@ -416,5 +416,90 @@ void r600_cp_commit(struct radeon_device *rdev); void r600_pcie_gart_tlb_flush(struct radeon_device *rdev); uint32_t r600_pciep_rreg(struct radeon_device *rdev, uint32_t reg); void r600_pciep_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); +int r600_cs_parse(struct radeon_cs_parser *p); +void r600_fence_ring_emit(struct radeon_device *rdev, + struct radeon_fence *fence); +int r600_copy_dma(struct radeon_device *rdev, + uint64_t src_offset, + uint64_t dst_offset, + unsigned num_pages, + struct radeon_fence *fence); +int r600_irq_process(struct radeon_device *rdev); +int r600_irq_set(struct radeon_device *rdev); +int r600_gpu_reset(struct radeon_device *rdev); +int r600_set_surface_reg(struct radeon_device *rdev, int reg, + uint32_t tiling_flags, uint32_t pitch, + uint32_t offset, uint32_t obj_size); +int r600_clear_surface_reg(struct radeon_device *rdev, int reg); +void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); +int r600_ring_test(struct radeon_device *rdev); +int r600_copy_blit(struct radeon_device *rdev, + uint64_t src_offset, uint64_t dst_offset, + unsigned num_pages, struct radeon_fence *fence); + +static struct radeon_asic r600_asic = { + .init = &r600_init, +// .fini = &r600_fini, +// .suspend = &r600_suspend, +// .resume = &r600_resume, +// .cp_commit = &r600_cp_commit, + .vga_set_state = &r600_vga_set_state, + .gpu_reset = &r600_gpu_reset, + .gart_tlb_flush = &r600_pcie_gart_tlb_flush, + .gart_set_page = &rs600_gart_set_page, +// .ring_test = &r600_ring_test, +// .ring_ib_execute = &r600_ring_ib_execute, +// .irq_set = &r600_irq_set, +// .irq_process = &r600_irq_process, +// .fence_ring_emit = &r600_fence_ring_emit, +// .cs_parse = &r600_cs_parse, +// .copy_blit = &r600_copy_blit, +// .copy_dma = &r600_copy_blit, +// .copy = &r600_copy_blit, + .set_engine_clock = &radeon_atom_set_engine_clock, + .set_memory_clock = &radeon_atom_set_memory_clock, + .set_pcie_lanes = NULL, + .set_clock_gating = &radeon_atom_set_clock_gating, + .set_surface_reg = r600_set_surface_reg, + .clear_surface_reg = r600_clear_surface_reg, + .bandwidth_update = &rv515_bandwidth_update, +}; + +/* + * rv770,rv730,rv710,rv740 + */ +int rv770_init(struct radeon_device *rdev); +void rv770_fini(struct radeon_device *rdev); +int rv770_suspend(struct radeon_device *rdev); +int rv770_resume(struct radeon_device *rdev); +int rv770_gpu_reset(struct radeon_device *rdev); + +static struct radeon_asic rv770_asic = { + .init = &rv770_init, +// .fini = &rv770_fini, +// .suspend = &rv770_suspend, +// .resume = &rv770_resume, +// .cp_commit = &r600_cp_commit, + .gpu_reset = &rv770_gpu_reset, + .vga_set_state = &r600_vga_set_state, + .gart_tlb_flush = &r600_pcie_gart_tlb_flush, + .gart_set_page = &rs600_gart_set_page, +// .ring_test = &r600_ring_test, +// .ring_ib_execute = &r600_ring_ib_execute, +// .irq_set = &r600_irq_set, +// .irq_process = &r600_irq_process, +// .fence_ring_emit = &r600_fence_ring_emit, +// .cs_parse = &r600_cs_parse, +// .copy_blit = &r600_copy_blit, +// .copy_dma = &r600_copy_blit, +// .copy = &r600_copy_blit, + .set_engine_clock = &radeon_atom_set_engine_clock, + .set_memory_clock = &radeon_atom_set_memory_clock, + .set_pcie_lanes = NULL, + .set_clock_gating = &radeon_atom_set_clock_gating, + .set_surface_reg = r600_set_surface_reg, + .clear_surface_reg = r600_clear_surface_reg, + .bandwidth_update = &rv515_bandwidth_update, +}; #endif diff --git a/drivers/video/drm/radeon/radeon_bios.c b/drivers/video/drm/radeon/radeon_bios.c index 3b3f30c568..3f3f0b33cd 100644 --- a/drivers/video/drm/radeon/radeon_bios.c +++ b/drivers/video/drm/radeon/radeon_bios.c @@ -33,6 +33,43 @@ /* * BIOS. */ + +/* If you boot an IGP board with a discrete card as the primary, + * the IGP rom is not accessible via the rom bar as the IGP rom is + * part of the system bios. On boot, the system bios puts a + * copy of the igp rom at the start of vram if a discrete card is + * present. + */ +static bool igp_read_bios_from_vram(struct radeon_device *rdev) +{ + uint8_t __iomem *bios; + resource_size_t vram_base; + resource_size_t size = 256 * 1024; /* ??? */ + + rdev->bios = NULL; + vram_base = drm_get_resource_start(rdev->ddev, 0); + bios = ioremap(vram_base, size); + if (!bios) { + DRM_ERROR("Unable to mmap vram\n"); + return false; + } + + if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { + iounmap(bios); + DRM_ERROR("bad rom signature\n"); + return false; + } + rdev->bios = kmalloc(size, GFP_KERNEL); + if (rdev->bios == NULL) { + iounmap(bios); + DRM_ERROR("kmalloc failed\n"); + return false; + } + memcpy(rdev->bios, bios, size); + iounmap(bios); + return true; +} + static bool radeon_read_bios(struct radeon_device *rdev) { uint8_t __iomem *bios; @@ -342,7 +379,9 @@ static bool legacy_read_disabled_bios(struct radeon_device *rdev) static bool radeon_read_disabled_bios(struct radeon_device *rdev) { - if (rdev->family >= CHIP_RV770) + if (rdev->flags & RADEON_IS_IGP) + return igp_read_bios_from_vram(rdev); + else if (rdev->family >= CHIP_RV770) return r700_read_disabled_bios(rdev); else if (rdev->family >= CHIP_R600) return r600_read_disabled_bios(rdev); @@ -357,6 +396,11 @@ bool radeon_get_bios(struct radeon_device *rdev) bool r; uint16_t tmp; + if (rdev->flags & RADEON_IS_IGP) { + r = igp_read_bios_from_vram(rdev); + if (r == false) + r = radeon_read_bios(rdev); + } else r = radeon_read_bios(rdev); if (r == false) { r = radeon_read_disabled_bios(rdev); diff --git a/drivers/video/drm/radeon/radeon_connectors.c b/drivers/video/drm/radeon/radeon_connectors.c index 2275b73b5c..327da76b95 100644 --- a/drivers/video/drm/radeon/radeon_connectors.c +++ b/drivers/video/drm/radeon/radeon_connectors.c @@ -428,7 +428,7 @@ static void radeon_connector_destroy(struct drm_connector *connector) if (radeon_connector->ddc_bus) radeon_i2c_destroy(radeon_connector->ddc_bus); kfree(radeon_connector->con_priv); - // drm_sysfs_connector_remove(connector); + drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); kfree(connector); } @@ -941,7 +941,7 @@ radeon_add_atom_connector(struct drm_device *dev, } connector->display_info.subpixel_order = subpixel_order; - // drm_sysfs_connector_add(connector); + drm_sysfs_connector_add(connector); return; failed: @@ -1065,7 +1065,7 @@ radeon_add_legacy_connector(struct drm_device *dev, } connector->display_info.subpixel_order = subpixel_order; - // drm_sysfs_connector_add(connector); + drm_sysfs_connector_add(connector); return; failed: diff --git a/drivers/video/drm/radeon/radeon_device.c b/drivers/video/drm/radeon/radeon_device.c index 1eaebffbfb..1eb6cd72fe 100644 --- a/drivers/video/drm/radeon/radeon_device.c +++ b/drivers/video/drm/radeon/radeon_device.c @@ -37,7 +37,6 @@ #include -#include int radeon_dynclks = -1; int radeon_r4xx_atom = 0; @@ -47,8 +46,19 @@ int radeon_benchmarking = 0; int radeon_connector_table = 0; int radeon_tv = 0; -int pre_init_display(struct radeon_device *rdev); -int post_init_display(struct radeon_device *rdev); +void parse_cmdline(char *cmdline, mode_t *mode, char *log); +int init_display(struct radeon_device *rdev, mode_t *mode); + + /* Legacy VGA regions */ +#define VGA_RSRC_NONE 0x00 +#define VGA_RSRC_LEGACY_IO 0x01 +#define VGA_RSRC_LEGACY_MEM 0x02 +#define VGA_RSRC_LEGACY_MASK (VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM) +/* Non-legacy access */ +#define VGA_RSRC_NORMAL_IO 0x04 +#define VGA_RSRC_NORMAL_MEM 0x08 + + /* * Clear GPU surface registers. @@ -227,6 +237,28 @@ bool radeon_card_posted(struct radeon_device *rdev) } +int radeon_dummy_page_init(struct radeon_device *rdev) +{ + rdev->dummy_page.page = AllocPage(); + if (rdev->dummy_page.page == NULL) + return -ENOMEM; + rdev->dummy_page.addr = MapIoMem(rdev->dummy_page.page, 4096, 5); + if (!rdev->dummy_page.addr) { +// __free_page(rdev->dummy_page.page); + rdev->dummy_page.page = NULL; + return -ENOMEM; + } + return 0; +} + +void radeon_dummy_page_fini(struct radeon_device *rdev) +{ + if (rdev->dummy_page.page == NULL) + return; + KernelFree(rdev->dummy_page.addr); + rdev->dummy_page.page = NULL; +} + /* * Registers accessors functions. @@ -285,10 +317,10 @@ void radeon_register_accessor_init(struct radeon_device *rdev) rdev->mc_rreg = &rs600_mc_rreg; rdev->mc_wreg = &rs600_mc_wreg; } -// if (rdev->family >= CHIP_R600) { -// rdev->pciep_rreg = &r600_pciep_rreg; -// rdev->pciep_wreg = &r600_pciep_wreg; -// } + if (rdev->family >= CHIP_R600) { + rdev->pciep_rreg = &r600_pciep_rreg; + rdev->pciep_wreg = &r600_pciep_wreg; + } } @@ -354,13 +386,13 @@ int radeon_asic_init(struct radeon_device *rdev) case CHIP_RV670: case CHIP_RS780: case CHIP_RS880: -// rdev->asic = &r600_asic; + rdev->asic = &r600_asic; break; case CHIP_RV770: case CHIP_RV730: case CHIP_RV710: case CHIP_RV740: -// rdev->asic = &rv770_asic; + rdev->asic = &rv770_asic; break; default: /* FIXME: not supported yet */ @@ -475,8 +507,17 @@ void radeon_combios_fini(struct radeon_device *rdev) { } -int radeon_modeset_init(struct radeon_device *rdev); -void radeon_modeset_fini(struct radeon_device *rdev); +/* if we get transitioned to only one device, tak VGA back */ +static unsigned int radeon_vga_set_decode(void *cookie, bool state) +{ + struct radeon_device *rdev = cookie; + radeon_vga_set_state(rdev, state); + if (state) + return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM | + VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; + else + return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; +} void radeon_agp_disable(struct radeon_device *rdev) { @@ -609,6 +650,8 @@ static struct pci_device_id pciidlist[] = { radeon_PCI_IDS }; +mode_t usermode; +char log[256]; u32_t drvEntry(int action, char *cmdline) { @@ -621,14 +664,19 @@ u32_t drvEntry(int action, char *cmdline) if(action != 1) return 0; - if(!dbg_open("/hd0/2/atikms.log")) - { - printf("Can't open /hd0/2/atikms.log\nExit\n"); - return 0; - } + if( cmdline && *cmdline ) + parse_cmdline(cmdline, &usermode, log); - if(cmdline) - dbgprintf("cmdline: %s\n", cmdline); + if(!dbg_open(log)) + { + strcpy(log, "/rd/1/drivers/atikms.log"); + + if(!dbg_open(log)) + { + printf("Can't open %s\nExit\n", log); + return 0; + }; + } enum_pci_devices(); @@ -725,22 +773,6 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent) dev->pci_device = pdev->device; dev->pci_vendor = pdev->vendor; - // if (drm_core_check_feature(dev, DRIVER_MODESET)) { - // pci_set_drvdata(pdev, dev); - // ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); - // if (ret) - // goto err_g2; - // } - - // if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY))) - // goto err_g3; - - // if (dev->driver->load) { - // ret = dev->driver->load(dev, ent->driver_data); - // if (ret) - // goto err_g4; - // } - ret = radeon_driver_load_kms(dev, ent->driver_data ); if (ret) goto err_g4; @@ -751,9 +783,7 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent) // driver->name, driver->major, driver->minor, driver->patchlevel, // driver->date, pci_name(pdev), dev->primary->index); - pre_init_display(dev->dev_private); - set_mode(dev, 1280, 1024); - post_init_display(dev->dev_private); + init_display(dev->dev_private, &usermode); LEAVE(); diff --git a/drivers/video/drm/radeon/radeon_fb.c b/drivers/video/drm/radeon/radeon_fb.c index 6c06b51821..e56da0446f 100644 --- a/drivers/video/drm/radeon/radeon_fb.c +++ b/drivers/video/drm/radeon/radeon_fb.c @@ -42,6 +42,7 @@ #include #include "radeon_object.h" + struct fb_info *framebuffer_alloc(size_t size, void *dev); struct radeon_fb_device { @@ -103,7 +104,7 @@ int radeonfb_resize(struct drm_device *dev, struct drm_crtc *crtc) } EXPORT_SYMBOL(radeonfb_resize); -static int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled) +int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled) { int aligned = width; int align_large = (ASIC_IS_AVIVO(rdev)) || tiled; @@ -436,106 +437,6 @@ struct fb_info *framebuffer_alloc(size_t size, void *dev) #undef BYTES_PER_LONG } -static char *manufacturer_name(unsigned char *x) -{ - static char name[4]; - - name[0] = ((x[0] & 0x7C) >> 2) + '@'; - name[1] = ((x[0] & 0x03) << 3) + ((x[1] & 0xE0) >> 5) + '@'; - name[2] = (x[1] & 0x1F) + '@'; - name[3] = 0; - - return name; -} - -void set_crtc(struct drm_crtc *crtc); - -bool set_mode(struct drm_device *dev, int width, int height) -{ - struct drm_connector *connector; - - bool ret = false; - - ENTER(); - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) - { - struct drm_display_mode *mode; - - struct drm_encoder *encoder; - struct drm_crtc *crtc; - - if( connector->status != connector_status_connected) - continue; - - encoder = connector->encoder; - if( encoder == NULL) - continue; - - crtc = encoder->crtc; - - if(crtc == NULL) - continue; - - list_for_each_entry(mode, &connector->modes, head) - { - char *con_name, *enc_name; - - struct drm_framebuffer *fb; - - if (drm_mode_width(mode) == width && - drm_mode_height(mode) == height) - { - char con_edid[128]; - - fb = list_first_entry(&dev->mode_config.fb_kernel_list, - struct drm_framebuffer, filp_head); - - memcpy(con_edid, connector->edid_blob_ptr->data, 128); - - dbgprintf("Manufacturer: %s Model %x Serial Number %u\n", - manufacturer_name(con_edid + 0x08), - (unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)), - (unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8) - + (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24))); - con_name = drm_get_connector_name(connector); - enc_name = drm_get_encoder_name(encoder); - - dbgprintf("set mode %d %d connector %s encoder %s\n", - width, height, con_name, enc_name); - - fb->width = width; - fb->height = height; - fb->pitch = radeon_align_pitch(dev->dev_private, width, 32, false) * ((32 + 1) / 8); - - crtc->fb = fb; - crtc->enabled = true; - set_crtc(crtc); - - ret = drm_crtc_helper_set_mode(crtc, mode, 0, 0, fb); - - sysSetScreen(fb->width, fb->height, fb->pitch); - - if (ret == true) - { - dbgprintf("new mode %d %d pitch %d\n",fb->width, fb->height, fb->pitch); - } - else - { - DRM_ERROR("failed to set mode %d_%d on crtc %p\n", - fb->width, fb->height, crtc); - }; - - LEAVE(); - - return ret; - }; - } - }; - LEAVE(); - return ret; -}; - diff --git a/drivers/video/drm/radeon/rdisplay.c b/drivers/video/drm/radeon/rdisplay.c index 48a761ce05..ee4b7d716a 100644 --- a/drivers/video/drm/radeon/rdisplay.c +++ b/drivers/video/drm/radeon/rdisplay.c @@ -64,6 +64,7 @@ struct tag_display }; +int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled); static display_t *rdisplay; @@ -147,46 +148,6 @@ static void radeon_show_cursor(struct drm_crtc *crtc) } } -int pre_init_display(struct radeon_device *rdev) -{ - cursor_t *cursor; - - ENTER(); - - rdisplay = GetDisplay(); - - rdisplay->ddev = rdev->ddev; - - list_for_each_entry(cursor, &rdisplay->cursors, list) - { - init_cursor(cursor); - }; - - LEAVE(); - - return 1; -}; - -int post_init_display(struct radeon_device *rdev) -{ - cursor_t *cursor; - - ENTER(); - - select_cursor(rdisplay->cursor); - - radeon_show_cursor(rdisplay->crtc); - - rdisplay->init_cursor = init_cursor; - rdisplay->select_cursor = select_cursor; - rdisplay->show_cursor = NULL; - rdisplay->move_cursor = move_cursor; - rdisplay->restore_cursor = restore_cursor; - - LEAVE(); - - return 1; -}; static void radeon_lock_cursor(struct drm_crtc *crtc, bool lock) { @@ -311,3 +272,221 @@ void __stdcall restore_cursor(int x, int y) { }; +static char *manufacturer_name(unsigned char *x) +{ + static char name[4]; + + name[0] = ((x[0] & 0x7C) >> 2) + '@'; + name[1] = ((x[0] & 0x03) << 3) + ((x[1] & 0xE0) >> 5) + '@'; + name[2] = (x[1] & 0x1F) + '@'; + name[3] = 0; + + return name; +} + +bool set_mode(struct drm_device *dev, int width, int height) +{ + struct drm_connector *connector; + + bool ret = false; + + ENTER(); + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) + { + struct drm_display_mode *mode; + + struct drm_encoder *encoder; + struct drm_crtc *crtc; + + if( connector->status != connector_status_connected) + continue; + + encoder = connector->encoder; + if( encoder == NULL) + continue; + + crtc = encoder->crtc; + + if(crtc == NULL) + continue; + + list_for_each_entry(mode, &connector->modes, head) + { + char *con_name, *enc_name; + + struct drm_framebuffer *fb; + + if (drm_mode_width(mode) == width && + drm_mode_height(mode) == height) + { + char con_edid[128]; + + fb = list_first_entry(&dev->mode_config.fb_kernel_list, + struct drm_framebuffer, filp_head); + + memcpy(con_edid, connector->edid_blob_ptr->data, 128); + + dbgprintf("Manufacturer: %s Model %x Serial Number %u\n", + manufacturer_name(con_edid + 0x08), + (unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)), + (unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8) + + (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24))); + + + con_name = drm_get_connector_name(connector); + enc_name = drm_get_encoder_name(encoder); + + dbgprintf("set mode %d %d connector %s encoder %s\n", + width, height, con_name, enc_name); + + fb->width = width; + fb->height = height; + fb->pitch = radeon_align_pitch(dev->dev_private, width, 32, false) * ((32 + 1) / 8); + + crtc->fb = fb; + crtc->enabled = true; + rdisplay->crtc = crtc; + + ret = drm_crtc_helper_set_mode(crtc, mode, 0, 0, fb); + + rdisplay->width = fb->width; + rdisplay->height = fb->height; + rdisplay->pitch = fb->pitch; + + sysSetScreen(fb->width, fb->height, fb->pitch); + + if (ret == true) + { + dbgprintf("new mode %d %d pitch %d\n",fb->width, fb->height, fb->pitch); + } + else + { + DRM_ERROR("failed to set mode %d_%d on crtc %p\n", + fb->width, fb->height, crtc); + }; + + LEAVE(); + + return ret; + }; + } + }; + LEAVE(); + return ret; +}; + + +int init_display(struct radeon_device *rdev, mode_t *usermode) +{ + cursor_t *cursor; + + ENTER(); + + rdisplay = GetDisplay(); + + rdisplay->ddev = rdev->ddev; + + list_for_each_entry(cursor, &rdisplay->cursors, list) + { + init_cursor(cursor); + }; + + if( (usermode->width != 0) && + (usermode->height != 0) ) + { + set_mode(rdev->ddev, usermode->width, usermode->height); + } + else + set_mode(rdev->ddev, 800, 600); + + select_cursor(rdisplay->cursor); + radeon_show_cursor(rdisplay->crtc); + + rdisplay->init_cursor = init_cursor; + rdisplay->select_cursor = select_cursor; + rdisplay->show_cursor = NULL; + rdisplay->move_cursor = move_cursor; + rdisplay->restore_cursor = restore_cursor; + + LEAVE(); + + return 1; +}; + +static int my_atoi(char **cmd) +{ + char* p = *cmd; + int val = 0; + + for (;; *p++) { + switch (*p) { + case '0' ... '9': + val = 10*val+(*p-'0'); + break; + default: + *cmd = p; + return val; + } + } +} + +char* parse_mode(char *p, mode_t *mode) +{ + char c; + + while( (c = *p++) == ' '); + + if( c ) + { + p--; + + mode->width = my_atoi(&p); + p++; + + mode->height = my_atoi(&p); + p++; + + mode->freq = my_atoi(&p); + } + + return p; +}; + +char* parse_path(char *p, char *log) +{ + char c; + + while( (c = *p++) == ' '); + p--; + while( (c = *log++ = *p++) && (c != ' ')); + *log = 0; + + return p; +}; + +void parse_cmdline(char *cmdline, mode_t *mode, char *log) +{ + char *p = cmdline; + + char c = *p++; + + while( c ) + { + if( c == '-') + { + switch(*p++) + { + case 'm': + p = parse_mode(p, mode); + break; + + case 'l': + p = parse_path(p, log); + break; + }; + }; + c = *p++; + }; +}; +