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;
|
||||
|
||||
@ -113,7 +113,7 @@ extern inline int GetScreenSize()
|
||||
return retval;
|
||||
}
|
||||
|
||||
extern inline int GetScreenBpp()
|
||||
static inline int GetScreenBpp()
|
||||
{
|
||||
int retval;
|
||||
|
||||
@ -123,7 +123,7 @@ extern inline int GetScreenBpp()
|
||||
return retval;
|
||||
}
|
||||
|
||||
extern inline int GetScreenPitch()
|
||||
static inline int GetScreenPitch()
|
||||
{
|
||||
int retval;
|
||||
|
||||
@ -133,7 +133,7 @@ extern inline int GetScreenPitch()
|
||||
return retval;
|
||||
}
|
||||
|
||||
extern inline u32_t GetPgAddr(void *mem)
|
||||
static inline u32_t GetPgAddr(void *mem)
|
||||
{
|
||||
u32_t retval;
|
||||
|
||||
@ -144,7 +144,7 @@ extern inline u32_t GetPgAddr(void *mem)
|
||||
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;
|
||||
__asm__ __volatile__ (
|
||||
@ -154,7 +154,7 @@ extern inline void CommitPages(void *mem, u32_t page, u32_t size)
|
||||
__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;
|
||||
__asm__ __volatile__ (
|
||||
@ -164,7 +164,7 @@ extern inline void UnmapPages(void *mem, size_t size)
|
||||
__asm__ __volatile__ ("":::"eax","ecx");
|
||||
};
|
||||
|
||||
extern inline void usleep(u32_t delay)
|
||||
static inline void usleep(u32_t delay)
|
||||
{
|
||||
if( !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)
|
||||
{
|
||||
u32_t ifl;
|
||||
|
@ -7,23 +7,40 @@ dd start
|
||||
dd i_end
|
||||
dd mem
|
||||
dd mem
|
||||
dd 0
|
||||
dd 0
|
||||
dd cmdline
|
||||
dd path
|
||||
|
||||
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 ebx, 21
|
||||
mov ecx, sz_kms
|
||||
mov edx, sz_mode
|
||||
mov ecx, path
|
||||
mov edx, cmdline
|
||||
int 0x40
|
||||
|
||||
.done:
|
||||
mov eax, -1
|
||||
int 0x40
|
||||
|
||||
sz_kms db '/rd/1/drivers/atikms.dll',0
|
||||
sz_mode db '-m 1024x768 -l/hd0/2/atikms.log',0
|
||||
sz_display db 'DISPLAY',0
|
||||
|
||||
align 4
|
||||
i_end:
|
||||
rb 16
|
||||
cmdline rb 256
|
||||
path rb 1024
|
||||
rb 16 ; stack
|
||||
mem:
|
||||
|
@ -445,6 +445,71 @@ int enum_pci_devices()
|
||||
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
|
||||
/**
|
||||
* 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
|
||||
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
|
||||
|
@ -48,6 +48,9 @@ int radeon_tv = 0;
|
||||
|
||||
void parse_cmdline(char *cmdline, mode_t *mode, char *log);
|
||||
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 */
|
||||
#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
|
||||
*/
|
||||
@ -716,13 +667,13 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
|
||||
dev->dev_private = (void *)rdev;
|
||||
|
||||
/* update BUS flag */
|
||||
// if (drm_device_is_agp(dev)) {
|
||||
if (drm_device_is_agp(dev)) {
|
||||
flags |= RADEON_IS_AGP;
|
||||
// } else if (drm_device_is_pcie(dev)) {
|
||||
// flags |= RADEON_IS_PCIE;
|
||||
// } else {
|
||||
// flags |= RADEON_IS_PCI;
|
||||
// }
|
||||
} else if (drm_device_is_pcie(dev)) {
|
||||
flags |= RADEON_IS_PCIE;
|
||||
} else {
|
||||
flags |= RADEON_IS_PCI;
|
||||
}
|
||||
|
||||
/* radeon_device_init should report only fatal error
|
||||
* 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;
|
||||
}
|
||||
|
||||
mode_t usermode;
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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 lfb;
|
||||
|
||||
int supported_modes;
|
||||
struct drm_device *ddev;
|
||||
struct drm_connector *connector;
|
||||
struct drm_crtc *crtc;
|
||||
|
||||
struct list_head cursors;
|
||||
@ -284,44 +286,52 @@ static char *manufacturer_name(unsigned char *x)
|
||||
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;
|
||||
|
||||
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_crtc *crtc;
|
||||
|
||||
if( connector->status != connector_status_connected)
|
||||
continue;
|
||||
char con_edid[128];
|
||||
char *con_name;
|
||||
char *enc_name;
|
||||
|
||||
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);
|
||||
|
||||
@ -338,11 +348,11 @@ bool set_mode(struct drm_device *dev, int width, int height)
|
||||
enc_name = drm_get_encoder_name(encoder);
|
||||
|
||||
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->height = height;
|
||||
fb->pitch = radeon_align_pitch(dev->dev_private, width, 32, false) * ((32 + 1) / 8);
|
||||
fb->width = reqmode->width;
|
||||
fb->height = reqmode->height;
|
||||
fb->pitch = radeon_align_pitch(dev->dev_private, reqmode->width, 32, false) * ((32 + 1) / 8);
|
||||
|
||||
crtc->fb = fb;
|
||||
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);
|
||||
|
||||
if (ret == true)
|
||||
{
|
||||
rdisplay->width = fb->width;
|
||||
rdisplay->height = fb->height;
|
||||
rdisplay->pitch = fb->pitch;
|
||||
rdisplay->vrefresh = drm_mode_vrefresh(mode);
|
||||
|
||||
sysSetScreen(fb->width, fb->height, fb->pitch);
|
||||
|
||||
if (ret == true)
|
||||
{
|
||||
dbgprintf("new mode %d %d pitch %d\n",fb->width, fb->height, fb->pitch);
|
||||
dbgprintf("new mode %d x %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)
|
||||
static int count_connector_modes(struct drm_connector* connector)
|
||||
{
|
||||
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;
|
||||
bool retval = false;
|
||||
|
||||
ENTER();
|
||||
|
||||
rdisplay = GetDisplay();
|
||||
|
||||
rdisplay->ddev = rdev->ddev;
|
||||
dev = rdisplay->ddev = rdev->ddev;
|
||||
|
||||
list_for_each_entry(cursor, &rdisplay->cursors, list)
|
||||
{
|
||||
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) &&
|
||||
(usermode->height != 0) )
|
||||
{
|
||||
set_mode(rdev->ddev, usermode->width, usermode->height);
|
||||
retval = set_mode(dev, rdisplay->connector, usermode, false);
|
||||
}
|
||||
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);
|
||||
radeon_show_cursor(rdisplay->crtc);
|
||||
@ -411,7 +480,7 @@ int init_display(struct radeon_device *rdev, mode_t *usermode)
|
||||
|
||||
LEAVE();
|
||||
|
||||
return 1;
|
||||
return retval;
|
||||
};
|
||||
|
||||
static int my_atoi(char **cmd)
|
||||
@ -442,12 +511,17 @@ char* parse_mode(char *p, mode_t *mode)
|
||||
p--;
|
||||
|
||||
mode->width = my_atoi(&p);
|
||||
p++;
|
||||
if(*p == 'x') p++;
|
||||
|
||||
mode->height = my_atoi(&p);
|
||||
p++;
|
||||
if(*p == 'x') p++;
|
||||
|
||||
mode->bpp = 32;
|
||||
|
||||
mode->freq = my_atoi(&p);
|
||||
|
||||
if( mode->freq == 0 )
|
||||
mode->freq = 60;
|
||||
}
|
||||
|
||||
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