kms: add r600 and r700

read command line

git-svn-id: svn://kolibrios.org@1233 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2009-10-24 21:42:25 +00:00
parent 8a7f4a3cf6
commit f064c3cbc1
13 changed files with 513 additions and 234 deletions

View File

@ -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;

View File

@ -1 +1,3 @@
/* stub */
#include <errno.h>

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -25,7 +25,7 @@
* Alex Deucher
* Jerome Glisse
*/
#include <errno.h>
#include <linux/seq_file.h>
#include <linux/firmware.h>
#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) {

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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:

View File

@ -37,7 +37,6 @@
#include <drm/drm_pciids.h>
#include <syscall.h>
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();

View File

@ -42,6 +42,7 @@
#include <drm_mm.h>
#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;
};

View File

@ -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++;
};
};