forked from KolibriOS/kolibrios
kms: frontend, loader, kms complete
git-svn-id: svn://kolibrios.org@1239 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
3612344bac
commit
fbe5f5e77e
@ -103,7 +103,7 @@ int dbgprintf(const char* format, ...);
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
extern inline int GetScreenSize()
|
static inline int GetScreenSize()
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
@ -113,7 +113,7 @@ extern inline int GetScreenSize()
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern inline int GetScreenBpp()
|
static inline int GetScreenBpp()
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ extern inline int GetScreenBpp()
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern inline int GetScreenPitch()
|
static inline int GetScreenPitch()
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ extern inline int GetScreenPitch()
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern inline u32_t GetPgAddr(void *mem)
|
static inline u32_t GetPgAddr(void *mem)
|
||||||
{
|
{
|
||||||
u32_t retval;
|
u32_t retval;
|
||||||
|
|
||||||
@ -144,7 +144,7 @@ extern inline u32_t GetPgAddr(void *mem)
|
|||||||
return retval;
|
return retval;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern inline void CommitPages(void *mem, u32_t page, u32_t size)
|
static inline void CommitPages(void *mem, u32_t page, u32_t size)
|
||||||
{
|
{
|
||||||
size = (size+4095) & ~4095;
|
size = (size+4095) & ~4095;
|
||||||
__asm__ __volatile__ (
|
__asm__ __volatile__ (
|
||||||
@ -154,7 +154,7 @@ extern inline void CommitPages(void *mem, u32_t page, u32_t size)
|
|||||||
__asm__ __volatile__ ("":::"eax","ebx","ecx");
|
__asm__ __volatile__ ("":::"eax","ebx","ecx");
|
||||||
};
|
};
|
||||||
|
|
||||||
extern inline void UnmapPages(void *mem, size_t size)
|
static inline void UnmapPages(void *mem, size_t size)
|
||||||
{
|
{
|
||||||
size = (size+4095) & ~4095;
|
size = (size+4095) & ~4095;
|
||||||
__asm__ __volatile__ (
|
__asm__ __volatile__ (
|
||||||
@ -164,7 +164,7 @@ extern inline void UnmapPages(void *mem, size_t size)
|
|||||||
__asm__ __volatile__ ("":::"eax","ecx");
|
__asm__ __volatile__ ("":::"eax","ecx");
|
||||||
};
|
};
|
||||||
|
|
||||||
extern inline void usleep(u32_t delay)
|
static inline void usleep(u32_t delay)
|
||||||
{
|
{
|
||||||
if( !delay )
|
if( !delay )
|
||||||
delay++;
|
delay++;
|
||||||
@ -257,6 +257,22 @@ u32 __RegService(char *name, srv_proc_t proc)
|
|||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
static inline u32_t GetService(const char *name)
|
||||||
|
{
|
||||||
|
u32_t handle;
|
||||||
|
|
||||||
|
__asm__ __volatile__
|
||||||
|
(
|
||||||
|
"pushl %%eax \n\t"
|
||||||
|
"call *__imp__GetService"
|
||||||
|
:"=eax" (handle)
|
||||||
|
:"a" (name)
|
||||||
|
:"ebx","ecx","edx","esi", "edi"
|
||||||
|
);
|
||||||
|
return handle;
|
||||||
|
};
|
||||||
|
|
||||||
static inline u32_t safe_cli(void)
|
static inline u32_t safe_cli(void)
|
||||||
{
|
{
|
||||||
u32_t ifl;
|
u32_t ifl;
|
||||||
|
@ -7,23 +7,40 @@ dd start
|
|||||||
dd i_end
|
dd i_end
|
||||||
dd mem
|
dd mem
|
||||||
dd mem
|
dd mem
|
||||||
dd 0
|
dd cmdline
|
||||||
dd 0
|
dd path
|
||||||
|
|
||||||
start:
|
start:
|
||||||
|
mov eax, 68
|
||||||
|
mov ebx, 16
|
||||||
|
mov ecx, sz_display
|
||||||
|
int 0x40
|
||||||
|
test eax, eax
|
||||||
|
jnz .done ; FIXME parse command line and
|
||||||
|
; call service
|
||||||
|
|
||||||
|
xor eax, eax
|
||||||
|
mov ecx, 1024
|
||||||
|
mov edi, path
|
||||||
|
cld
|
||||||
|
repne scasb
|
||||||
|
dec edi
|
||||||
|
mov [edi], dword '.dll'
|
||||||
|
mov [edi+4], al
|
||||||
mov eax, 68
|
mov eax, 68
|
||||||
mov ebx, 21
|
mov ebx, 21
|
||||||
mov ecx, sz_kms
|
mov ecx, path
|
||||||
mov edx, sz_mode
|
mov edx, cmdline
|
||||||
int 0x40
|
int 0x40
|
||||||
|
.done:
|
||||||
mov eax, -1
|
mov eax, -1
|
||||||
int 0x40
|
int 0x40
|
||||||
|
|
||||||
sz_kms db '/rd/1/drivers/atikms.dll',0
|
sz_display db 'DISPLAY',0
|
||||||
sz_mode db '-m 1024x768 -l/hd0/2/atikms.log',0
|
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
i_end:
|
i_end:
|
||||||
rb 16
|
cmdline rb 256
|
||||||
|
path rb 1024
|
||||||
|
rb 16 ; stack
|
||||||
mem:
|
mem:
|
||||||
|
@ -445,6 +445,71 @@ int enum_pci_devices()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define PCI_FIND_CAP_TTL 48
|
||||||
|
|
||||||
|
static int __pci_find_next_cap_ttl(unsigned int bus, unsigned int devfn,
|
||||||
|
u8 pos, int cap, int *ttl)
|
||||||
|
{
|
||||||
|
u8 id;
|
||||||
|
|
||||||
|
while ((*ttl)--) {
|
||||||
|
pos = PciRead8(bus, devfn, pos);
|
||||||
|
if (pos < 0x40)
|
||||||
|
break;
|
||||||
|
pos &= ~3;
|
||||||
|
id = PciRead8(bus, devfn, pos + PCI_CAP_LIST_ID);
|
||||||
|
if (id == 0xff)
|
||||||
|
break;
|
||||||
|
if (id == cap)
|
||||||
|
return pos;
|
||||||
|
pos += PCI_CAP_LIST_NEXT;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __pci_find_next_cap(unsigned int bus, unsigned int devfn,
|
||||||
|
u8 pos, int cap)
|
||||||
|
{
|
||||||
|
int ttl = PCI_FIND_CAP_TTL;
|
||||||
|
|
||||||
|
return __pci_find_next_cap_ttl(bus, devfn, pos, cap, &ttl);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __pci_bus_find_cap_start(unsigned int bus,
|
||||||
|
unsigned int devfn, u8 hdr_type)
|
||||||
|
{
|
||||||
|
u16 status;
|
||||||
|
|
||||||
|
status = PciRead16(bus, devfn, PCI_STATUS);
|
||||||
|
if (!(status & PCI_STATUS_CAP_LIST))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (hdr_type) {
|
||||||
|
case PCI_HEADER_TYPE_NORMAL:
|
||||||
|
case PCI_HEADER_TYPE_BRIDGE:
|
||||||
|
return PCI_CAPABILITY_LIST;
|
||||||
|
case PCI_HEADER_TYPE_CARDBUS:
|
||||||
|
return PCI_CB_CAPABILITY_LIST;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int pci_find_capability(struct pci_dev *dev, int cap)
|
||||||
|
{
|
||||||
|
int pos;
|
||||||
|
|
||||||
|
pos = __pci_bus_find_cap_start(dev->bus, dev->devfn, dev->hdr_type);
|
||||||
|
if (pos)
|
||||||
|
pos = __pci_find_next_cap(dev->bus, dev->devfn, pos, cap);
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/**
|
/**
|
||||||
* pci_set_power_state - Set the power state of a PCI device
|
* pci_set_power_state - Set the power state of a PCI device
|
||||||
|
@ -1139,8 +1139,8 @@ drm_get_resource_start(struct drm_device *dev, unsigned int resource);
|
|||||||
resource_size_t
|
resource_size_t
|
||||||
drm_get_resource_len(struct drm_device *dev, unsigned int resource);
|
drm_get_resource_len(struct drm_device *dev, unsigned int resource);
|
||||||
|
|
||||||
bool set_mode(struct drm_device *dev, int width, int height);
|
bool set_mode(struct drm_device *dev, struct drm_connector *connector,
|
||||||
|
mode_t *mode, bool strict);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -48,6 +48,9 @@ int radeon_tv = 0;
|
|||||||
|
|
||||||
void parse_cmdline(char *cmdline, mode_t *mode, char *log);
|
void parse_cmdline(char *cmdline, mode_t *mode, char *log);
|
||||||
int init_display(struct radeon_device *rdev, mode_t *mode);
|
int init_display(struct radeon_device *rdev, mode_t *mode);
|
||||||
|
int get_modes(mode_t *mode, int *count);
|
||||||
|
int set_user_mode(mode_t *mode);
|
||||||
|
|
||||||
|
|
||||||
/* Legacy VGA regions */
|
/* Legacy VGA regions */
|
||||||
#define VGA_RSRC_NONE 0x00
|
#define VGA_RSRC_NONE 0x00
|
||||||
@ -646,58 +649,6 @@ int radeon_device_init(struct radeon_device *rdev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct pci_device_id pciidlist[] = {
|
|
||||||
radeon_PCI_IDS
|
|
||||||
};
|
|
||||||
|
|
||||||
mode_t usermode;
|
|
||||||
char log[256];
|
|
||||||
|
|
||||||
u32_t drvEntry(int action, char *cmdline)
|
|
||||||
{
|
|
||||||
struct pci_device_id *ent;
|
|
||||||
|
|
||||||
dev_t device;
|
|
||||||
int err;
|
|
||||||
u32_t retval = 0;
|
|
||||||
|
|
||||||
if(action != 1)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if( cmdline && *cmdline )
|
|
||||||
parse_cmdline(cmdline, &usermode, log);
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
ent = find_pci_device(&device, pciidlist);
|
|
||||||
|
|
||||||
if( unlikely(ent == NULL) )
|
|
||||||
{
|
|
||||||
dbgprintf("device not found\n");
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
dbgprintf("device %x:%x\n", device.pci_dev.vendor,
|
|
||||||
device.pci_dev.device);
|
|
||||||
|
|
||||||
err = drm_get_dev(&device.pci_dev, ent);
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Driver load/unload
|
* Driver load/unload
|
||||||
*/
|
*/
|
||||||
@ -716,13 +667,13 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
|
|||||||
dev->dev_private = (void *)rdev;
|
dev->dev_private = (void *)rdev;
|
||||||
|
|
||||||
/* update BUS flag */
|
/* update BUS flag */
|
||||||
// if (drm_device_is_agp(dev)) {
|
if (drm_device_is_agp(dev)) {
|
||||||
flags |= RADEON_IS_AGP;
|
flags |= RADEON_IS_AGP;
|
||||||
// } else if (drm_device_is_pcie(dev)) {
|
} else if (drm_device_is_pcie(dev)) {
|
||||||
// flags |= RADEON_IS_PCIE;
|
flags |= RADEON_IS_PCIE;
|
||||||
// } else {
|
} else {
|
||||||
// flags |= RADEON_IS_PCI;
|
flags |= RADEON_IS_PCI;
|
||||||
// }
|
}
|
||||||
|
|
||||||
/* radeon_device_init should report only fatal error
|
/* radeon_device_init should report only fatal error
|
||||||
* like memory allocation failure or iomapping failure,
|
* like memory allocation failure or iomapping failure,
|
||||||
@ -746,6 +697,8 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mode_t usermode;
|
||||||
|
|
||||||
|
|
||||||
int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent)
|
int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
{
|
{
|
||||||
@ -848,3 +801,106 @@ uint32_t __div64_32(uint64_t *n, uint32_t base)
|
|||||||
return rem;
|
return rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct pci_device_id pciidlist[] = {
|
||||||
|
radeon_PCI_IDS
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define API_VERSION 0x01000100
|
||||||
|
|
||||||
|
#define SRV_GETVERSION 0
|
||||||
|
#define SRV_ENUM_MODES 1
|
||||||
|
#define SRV_SET_MODE 2
|
||||||
|
|
||||||
|
int _stdcall display_handler(ioctl_t *io)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
u32_t *inp;
|
||||||
|
u32_t *outp;
|
||||||
|
|
||||||
|
inp = io->input;
|
||||||
|
outp = io->output;
|
||||||
|
|
||||||
|
switch(io->io_code)
|
||||||
|
{
|
||||||
|
case SRV_GETVERSION:
|
||||||
|
if(io->out_size==4)
|
||||||
|
{
|
||||||
|
*outp = API_VERSION;
|
||||||
|
retval = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SRV_ENUM_MODES:
|
||||||
|
dbgprintf("SRV_ENUM_MODES inp %x inp_size %x out_size %x\n",
|
||||||
|
inp, io->inp_size, io->out_size );
|
||||||
|
|
||||||
|
if( (outp != NULL) && (io->out_size == 4) &&
|
||||||
|
(io->inp_size == *outp * sizeof(mode_t)) )
|
||||||
|
{
|
||||||
|
retval = get_modes((mode_t*)inp, outp);
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SRV_SET_MODE:
|
||||||
|
if( (inp != NULL) &&
|
||||||
|
(io->inp_size == sizeof(mode_t)) )
|
||||||
|
{
|
||||||
|
retval = set_user_mode((mode_t*)inp);
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32_t drvEntry(int action, char *cmdline)
|
||||||
|
{
|
||||||
|
static char log[256];
|
||||||
|
|
||||||
|
struct pci_device_id *ent;
|
||||||
|
|
||||||
|
dev_t device;
|
||||||
|
int err;
|
||||||
|
u32_t retval = 0;
|
||||||
|
|
||||||
|
if(action != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if( GetService("DISPLAY") != 0 )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if( cmdline && *cmdline )
|
||||||
|
parse_cmdline(cmdline, &usermode, log);
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
ent = find_pci_device(&device, pciidlist);
|
||||||
|
|
||||||
|
if( unlikely(ent == NULL) )
|
||||||
|
{
|
||||||
|
dbgprintf("device not found\n");
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
dbgprintf("device %x:%x\n", device.pci_dev.vendor,
|
||||||
|
device.pci_dev.device);
|
||||||
|
|
||||||
|
err = drm_get_dev(&device.pci_dev, ent);
|
||||||
|
|
||||||
|
return RegService("DISPLAY", display_handler);
|
||||||
|
|
||||||
|
};
|
||||||
|
@ -50,7 +50,9 @@ struct tag_display
|
|||||||
int pitch;
|
int pitch;
|
||||||
int lfb;
|
int lfb;
|
||||||
|
|
||||||
|
int supported_modes;
|
||||||
struct drm_device *ddev;
|
struct drm_device *ddev;
|
||||||
|
struct drm_connector *connector;
|
||||||
struct drm_crtc *crtc;
|
struct drm_crtc *crtc;
|
||||||
|
|
||||||
struct list_head cursors;
|
struct list_head cursors;
|
||||||
@ -284,44 +286,52 @@ static char *manufacturer_name(unsigned char *x)
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool set_mode(struct drm_device *dev, int width, int height)
|
bool set_mode(struct drm_device *dev, struct drm_connector *connector,
|
||||||
|
mode_t *reqmode, bool strict)
|
||||||
{
|
{
|
||||||
struct drm_connector *connector;
|
struct drm_display_mode *mode = NULL, *tmpmode;
|
||||||
|
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
ENTER();
|
ENTER();
|
||||||
|
|
||||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head)
|
list_for_each_entry(tmpmode, &connector->modes, head)
|
||||||
{
|
{
|
||||||
struct drm_display_mode *mode;
|
if( (drm_mode_width(tmpmode) == reqmode->width) &&
|
||||||
|
(drm_mode_height(tmpmode) == reqmode->height) &&
|
||||||
|
(drm_mode_vrefresh(tmpmode) == reqmode->freq) )
|
||||||
|
{
|
||||||
|
mode = tmpmode;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if( (mode == NULL) && (strict == false) )
|
||||||
|
{
|
||||||
|
list_for_each_entry(tmpmode, &connector->modes, head)
|
||||||
|
{
|
||||||
|
if( (drm_mode_width(tmpmode) == reqmode->width) &&
|
||||||
|
(drm_mode_height(tmpmode) == reqmode->height) )
|
||||||
|
{
|
||||||
|
mode = tmpmode;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
if( mode != NULL )
|
||||||
|
{
|
||||||
|
struct drm_framebuffer *fb;
|
||||||
struct drm_encoder *encoder;
|
struct drm_encoder *encoder;
|
||||||
struct drm_crtc *crtc;
|
struct drm_crtc *crtc;
|
||||||
|
|
||||||
if( connector->status != connector_status_connected)
|
char con_edid[128];
|
||||||
continue;
|
char *con_name;
|
||||||
|
char *enc_name;
|
||||||
|
|
||||||
encoder = connector->encoder;
|
encoder = connector->encoder;
|
||||||
if( encoder == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
crtc = encoder->crtc;
|
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,
|
fb = list_first_entry(&dev->mode_config.fb_kernel_list,
|
||||||
struct drm_framebuffer, filp_head);
|
struct drm_framebuffer, filp_head);
|
||||||
|
|
||||||
@ -338,11 +348,11 @@ bool set_mode(struct drm_device *dev, int width, int height)
|
|||||||
enc_name = drm_get_encoder_name(encoder);
|
enc_name = drm_get_encoder_name(encoder);
|
||||||
|
|
||||||
dbgprintf("set mode %d %d connector %s encoder %s\n",
|
dbgprintf("set mode %d %d connector %s encoder %s\n",
|
||||||
width, height, con_name, enc_name);
|
reqmode->width, reqmode->height, con_name, enc_name);
|
||||||
|
|
||||||
fb->width = width;
|
fb->width = reqmode->width;
|
||||||
fb->height = height;
|
fb->height = reqmode->height;
|
||||||
fb->pitch = radeon_align_pitch(dev->dev_private, width, 32, false) * ((32 + 1) / 8);
|
fb->pitch = radeon_align_pitch(dev->dev_private, reqmode->width, 32, false) * ((32 + 1) / 8);
|
||||||
|
|
||||||
crtc->fb = fb;
|
crtc->fb = fb;
|
||||||
crtc->enabled = true;
|
crtc->enabled = true;
|
||||||
@ -350,55 +360,114 @@ bool set_mode(struct drm_device *dev, int width, int height)
|
|||||||
|
|
||||||
ret = drm_crtc_helper_set_mode(crtc, mode, 0, 0, fb);
|
ret = drm_crtc_helper_set_mode(crtc, mode, 0, 0, fb);
|
||||||
|
|
||||||
|
if (ret == true)
|
||||||
|
{
|
||||||
rdisplay->width = fb->width;
|
rdisplay->width = fb->width;
|
||||||
rdisplay->height = fb->height;
|
rdisplay->height = fb->height;
|
||||||
rdisplay->pitch = fb->pitch;
|
rdisplay->pitch = fb->pitch;
|
||||||
|
rdisplay->vrefresh = drm_mode_vrefresh(mode);
|
||||||
|
|
||||||
sysSetScreen(fb->width, fb->height, fb->pitch);
|
sysSetScreen(fb->width, fb->height, fb->pitch);
|
||||||
|
|
||||||
if (ret == true)
|
dbgprintf("new mode %d x %d pitch %d\n",
|
||||||
{
|
fb->width, fb->height, fb->pitch);
|
||||||
dbgprintf("new mode %d %d pitch %d\n",fb->width, fb->height, fb->pitch);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
DRM_ERROR("failed to set mode %d_%d on crtc %p\n",
|
DRM_ERROR("failed to set mode %d_%d on crtc %p\n",
|
||||||
fb->width, fb->height, crtc);
|
fb->width, fb->height, crtc);
|
||||||
};
|
}
|
||||||
|
|
||||||
LEAVE();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
LEAVE();
|
LEAVE();
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int count_connector_modes(struct drm_connector* connector)
|
||||||
int init_display(struct radeon_device *rdev, mode_t *usermode)
|
|
||||||
{
|
{
|
||||||
|
struct drm_display_mode *mode;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
list_for_each_entry(mode, &connector->modes, head)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
};
|
||||||
|
return count;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct drm_connector* get_def_connector(struct drm_device *dev)
|
||||||
|
{
|
||||||
|
struct drm_connector *connector;
|
||||||
|
struct drm_connector *def_connector = NULL;
|
||||||
|
|
||||||
|
list_for_each_entry(connector, &dev->mode_config.connector_list, head)
|
||||||
|
{
|
||||||
|
struct drm_encoder *encoder;
|
||||||
|
struct drm_crtc *crtc;
|
||||||
|
|
||||||
|
if( connector->status != connector_status_connected)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
encoder = connector->encoder;
|
||||||
|
if( encoder == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( encoder->encoder_type == DRM_MODE_ENCODER_TVDAC )
|
||||||
|
{
|
||||||
|
dbgprintf("skip tvdac encoder %s connector %s\n",
|
||||||
|
drm_get_encoder_name(encoder),
|
||||||
|
drm_get_connector_name(connector));
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
crtc = encoder->crtc;
|
||||||
|
if(crtc == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
def_connector = connector;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
return def_connector;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool init_display(struct radeon_device *rdev, mode_t *usermode)
|
||||||
|
{
|
||||||
|
struct drm_device *dev;
|
||||||
cursor_t *cursor;
|
cursor_t *cursor;
|
||||||
|
bool retval = false;
|
||||||
|
|
||||||
ENTER();
|
ENTER();
|
||||||
|
|
||||||
rdisplay = GetDisplay();
|
rdisplay = GetDisplay();
|
||||||
|
|
||||||
rdisplay->ddev = rdev->ddev;
|
dev = rdisplay->ddev = rdev->ddev;
|
||||||
|
|
||||||
list_for_each_entry(cursor, &rdisplay->cursors, list)
|
list_for_each_entry(cursor, &rdisplay->cursors, list)
|
||||||
{
|
{
|
||||||
init_cursor(cursor);
|
init_cursor(cursor);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
rdisplay->connector = get_def_connector(dev);
|
||||||
|
|
||||||
|
if( rdisplay->connector == 0 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
rdisplay->supported_modes = count_connector_modes(rdisplay->connector);
|
||||||
|
|
||||||
if( (usermode->width != 0) &&
|
if( (usermode->width != 0) &&
|
||||||
(usermode->height != 0) )
|
(usermode->height != 0) )
|
||||||
{
|
{
|
||||||
set_mode(rdev->ddev, usermode->width, usermode->height);
|
retval = set_mode(dev, rdisplay->connector, usermode, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
set_mode(rdev->ddev, 800, 600);
|
{
|
||||||
|
mode_t mode;
|
||||||
|
mode.width = rdisplay->width;
|
||||||
|
mode.height = rdisplay->height;
|
||||||
|
mode.bpp = 32;
|
||||||
|
mode.freq = 60;
|
||||||
|
|
||||||
|
retval = set_mode(dev, rdisplay->connector, &mode, false);
|
||||||
|
};
|
||||||
|
|
||||||
select_cursor(rdisplay->cursor);
|
select_cursor(rdisplay->cursor);
|
||||||
radeon_show_cursor(rdisplay->crtc);
|
radeon_show_cursor(rdisplay->crtc);
|
||||||
@ -411,7 +480,7 @@ int init_display(struct radeon_device *rdev, mode_t *usermode)
|
|||||||
|
|
||||||
LEAVE();
|
LEAVE();
|
||||||
|
|
||||||
return 1;
|
return retval;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int my_atoi(char **cmd)
|
static int my_atoi(char **cmd)
|
||||||
@ -442,12 +511,17 @@ char* parse_mode(char *p, mode_t *mode)
|
|||||||
p--;
|
p--;
|
||||||
|
|
||||||
mode->width = my_atoi(&p);
|
mode->width = my_atoi(&p);
|
||||||
p++;
|
if(*p == 'x') p++;
|
||||||
|
|
||||||
mode->height = my_atoi(&p);
|
mode->height = my_atoi(&p);
|
||||||
p++;
|
if(*p == 'x') p++;
|
||||||
|
|
||||||
|
mode->bpp = 32;
|
||||||
|
|
||||||
mode->freq = my_atoi(&p);
|
mode->freq = my_atoi(&p);
|
||||||
|
|
||||||
|
if( mode->freq == 0 )
|
||||||
|
mode->freq = 60;
|
||||||
}
|
}
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
@ -490,3 +564,60 @@ void parse_cmdline(char *cmdline, mode_t *mode, char *log)
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int get_modes(mode_t *mode, int *count)
|
||||||
|
{
|
||||||
|
int err = -1;
|
||||||
|
|
||||||
|
ENTER();
|
||||||
|
|
||||||
|
dbgprintf("mode %x count %d\n", mode, *count);
|
||||||
|
|
||||||
|
if( *count == 0 )
|
||||||
|
{
|
||||||
|
*count = rdisplay->supported_modes;
|
||||||
|
err = 0;
|
||||||
|
}
|
||||||
|
else if( mode != NULL )
|
||||||
|
{
|
||||||
|
struct drm_display_mode *drmmode;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
if( *count > rdisplay->supported_modes)
|
||||||
|
*count = rdisplay->supported_modes;
|
||||||
|
|
||||||
|
list_for_each_entry(drmmode, &rdisplay->connector->modes, head)
|
||||||
|
{
|
||||||
|
if( i < *count)
|
||||||
|
{
|
||||||
|
mode->width = drm_mode_width(drmmode);
|
||||||
|
mode->height = drm_mode_height(drmmode);
|
||||||
|
mode->bpp = 32;
|
||||||
|
mode->freq = drm_mode_vrefresh(drmmode);
|
||||||
|
i++;
|
||||||
|
mode++;
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
};
|
||||||
|
*count = i;
|
||||||
|
err = 0;
|
||||||
|
};
|
||||||
|
LEAVE();
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int set_user_mode(mode_t *mode)
|
||||||
|
{
|
||||||
|
int err = -1;
|
||||||
|
|
||||||
|
if( (mode->width != 0) &&
|
||||||
|
(mode->height != 0) &&
|
||||||
|
(mode->freq != 0 ) )
|
||||||
|
{
|
||||||
|
if( set_mode(rdisplay->ddev, rdisplay->connector, mode, true) )
|
||||||
|
err = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
return err;
|
||||||
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user