You can subscribe to this list here.
| 2001 |
Jan
|
Feb
|
Mar
(1) |
Apr
(104) |
May
(81) |
Jun
(248) |
Jul
(133) |
Aug
(33) |
Sep
(53) |
Oct
(82) |
Nov
(166) |
Dec
(71) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2002 |
Jan
(121) |
Feb
(42) |
Mar
(39) |
Apr
(84) |
May
(87) |
Jun
(58) |
Jul
(97) |
Aug
(130) |
Sep
(32) |
Oct
(139) |
Nov
(108) |
Dec
(216) |
| 2003 |
Jan
(299) |
Feb
(136) |
Mar
(392) |
Apr
(141) |
May
(137) |
Jun
(107) |
Jul
(94) |
Aug
(262) |
Sep
(300) |
Oct
(216) |
Nov
(72) |
Dec
(94) |
| 2004 |
Jan
(174) |
Feb
(192) |
Mar
(215) |
Apr
(314) |
May
(319) |
Jun
(293) |
Jul
(205) |
Aug
(161) |
Sep
(192) |
Oct
(226) |
Nov
(308) |
Dec
(89) |
| 2005 |
Jan
(127) |
Feb
(269) |
Mar
(588) |
Apr
(106) |
May
(77) |
Jun
(77) |
Jul
(161) |
Aug
(239) |
Sep
(86) |
Oct
(112) |
Nov
(153) |
Dec
(145) |
| 2006 |
Jan
(87) |
Feb
(57) |
Mar
(129) |
Apr
(109) |
May
(102) |
Jun
(232) |
Jul
(97) |
Aug
(69) |
Sep
(67) |
Oct
(69) |
Nov
(214) |
Dec
(82) |
| 2007 |
Jan
(133) |
Feb
(307) |
Mar
(121) |
Apr
(171) |
May
(229) |
Jun
(156) |
Jul
(185) |
Aug
(160) |
Sep
(122) |
Oct
(130) |
Nov
(78) |
Dec
(27) |
| 2008 |
Jan
(105) |
Feb
(137) |
Mar
(146) |
Apr
(148) |
May
(239) |
Jun
(208) |
Jul
(157) |
Aug
(244) |
Sep
(119) |
Oct
(125) |
Nov
(189) |
Dec
(225) |
| 2009 |
Jan
(157) |
Feb
(139) |
Mar
(106) |
Apr
(130) |
May
(246) |
Jun
(189) |
Jul
(128) |
Aug
(127) |
Sep
(88) |
Oct
(86) |
Nov
(216) |
Dec
(9) |
| 2010 |
Jan
(5) |
Feb
|
Mar
(11) |
Apr
(31) |
May
(3) |
Jun
|
Jul
(7) |
Aug
|
Sep
(1) |
Oct
|
Nov
(1) |
Dec
|
| 2012 |
Jan
|
Feb
|
Mar
(3) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2013 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: Geert U. <ge...@li...> - 2001-11-29 07:53:21
|
On Wed, 28 Nov 2001, James Simmons wrote:
> +struct fb_copyarea {
> + __u32 sx; /* screen-relative */
> + __u32 sy;
> + __u32 width;
> + __u32 height;
> + __u32 dx;
> + __u32 dy;
> +};
> +
> +struct fb_fillrect {
> + __u32 x1; /* screen-relative */
> + __u32 y1;
Why call them x1 and y1 here?
> + __u32 width;
> + __u32 height;
> + __u32 color;
> + __u32 rop;
> +};
> +
> +struct fb_image {
> + __u32 width; /* Size of image */
> + __u32 height;
> + __u16 x; /* Where to place image */
> + __u16 y;
And x and y here?
I'd vote for either x/y or dx/dy (destinatation x/y).
> + __u32 fg_color; /* Only used when a mono bitmap */
> + __u32 bg_color;
> + __u8 depth; /* Dpeth of the image */
Depth
> + char *data; /* Pointer to image data */
> +};
> +
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@li...
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
|
|
From: Geert U. <ge...@li...> - 2001-11-29 07:52:20
|
On Wed, 28 Nov 2001, James Simmons wrote:
> > > +struct fbcursor {
> > > + __u16 set; /* what to set */
> > > + __u16 enable;/* cursor on/off */
> > > + struct fbcurpos pos;/* cursor position */
> > > + struct fbcurpos hot;/* cursor hot spot */
> > > + struct fb_cmap cmap;/* color map info */
> > > + struct fbcurpos size;/* cursor bit map size */
> > > + char *image;/* cursor image bits */
> > > + char *mask;/* cursor mask bits */
> > > +};
> >
> > Any details about contents of image and mask?
>
> Depends on what color depth you use for the cursor.
>
> > Or is it just monochromatic
> > 1bpp image? There is hardware which can do 16color hardware cursors (+
> > transparent+inverse).
>
> I know. That is why we have a colormap for the cursor. This allows for
> much more for the cursor than a mono color map.
>
> > And if it is 1bpp image, is it 0/1/transparent/invert (XGA), or
> > transp./transp./0/1 (X)?
>
> Should be able to support that as well. I haven't added any flags for
> that. Hm.
Just add a field to contain the color index for an inverting color (e.g. 3 for
XGA) or -1 if not supported.
For transparency, use the alpha in the cmap.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@li...
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
|
|
From: James S. <jsi...@tr...> - 2001-11-28 21:27:40
|
> > the graphics hardware. Locally we could use enhanced version of mmap, read > > and write. > > "enhanced version of mmap, read and write." :^) Yes. The only problem with kio buffers are they are hard drive specific so they carry alot of extra weight. This is one of the main reasons kio buffers haven't been used in the network layer yet. > unless read and write become special compiler macro type things, i still > fail to see how any amount of enhancing done to read/write will approach > buffer[offset]. The whole point of kio buffers is to avoid a copy_[from/to]_user. You have direct access to kernel memory space. This makes read/write as good if not better than mmap. The only draw back is the offset issue with read/write. Of course we have pread and pwrite to overcome this limitation. |
|
From: James S. <jsi...@tr...> - 2001-11-28 19:55:27
|
> > +struct fbcursor {
> > + __u16 set; /* what to set */
> > + __u16 enable;/* cursor on/off */
> > + struct fbcurpos pos;/* cursor position */
> > + struct fbcurpos hot;/* cursor hot spot */
> > + struct fb_cmap cmap;/* color map info */
> > + struct fbcurpos size;/* cursor bit map size */
> > + char *image;/* cursor image bits */
> > + char *mask;/* cursor mask bits */
> > +};
>
> Any details about contents of image and mask?
Depends on what color depth you use for the cursor.
> Or is it just monochromatic
> 1bpp image? There is hardware which can do 16color hardware cursors (+
> transparent+inverse).
I know. That is why we have a colormap for the cursor. This allows for
much more for the cursor than a mono color map.
> And if it is 1bpp image, is it 0/1/transparent/invert (XGA), or
> transp./transp./0/1 (X)?
Should be able to support that as well. I haven't added any flags for
that. Hm.
|
|
From: Chris W. <cw...@so...> - 2001-11-28 19:52:55
|
> Yes I like mmap to a large degree. In fact one of the things that has
> always excited me was the idea of using kio buffers to manage graphics
> hardware like the disk layer does. Think about the speed improvements
> since we wouldn't be going threw the VM layer. Basically we have raw
> IO instead of for disk for graphcis hardware. Plus we get the bounus of
> not worrying about inheritance issues. IRIX doesn't allow the graphics
so true! when vesa2 came out, with linear framebuffers and everything, i
was estatic. no more bank switching etc. I would assume similar things
for disk access, as well as perhaps sound buffers and nic buffers, but i
have yet to deal directly with them at the hardware level (discovered
linux first).
> the graphics hardware. Locally we could use enhanced version of mmap, read
> and write.
"enhanced version of mmap, read and write." :^)
unless read and write become special compiler macro type things, i still
fail to see how any amount of enhancing done to read/write will approach
buffer[offset]. best case, you could write in blocks or 65536b or more,
and simply flag it's length and have read/write internally to the
buffer[offset] (similar to memmov), but when you only modify a single
pixel/byte, read/write would at least double the execution time.
despite this, much of the graphics world at least seems to be moving to
hardware accleration, so instead of reading/writing a lot of data, you
only read/write 'instructions' to the card. this is still useless when
you _want_ to use fb as is (for some efect that can't be/isn't implimented
in hardware). even this is combated by the new programmable gfx cards,
which makes fb effects done by the cpu seem even more obsolete. but this
would severely limit the older machines that have either no hardware
acceleration or no drivers to run the hardware. (or, the user is aganst
using hardware that uses only closed source drivers)
compared to the above, it would be fairly trivial to add an
if(mmap_failed)
{
read/write to buffer
}
else
{
use mmap'd buffer
}
to any kind of program that would need it, which makes the elimination of
mmap seem counterproductive when network transparency is not needed.
chris
--- moc.lexiptfos@thgirwc ---
|
|
From: Petr V. <VAN...@vc...> - 2001-11-28 19:29:47
|
[trimmed linux-kernel, as it has big traffic even without my stupid
questions...]
On 28 Nov 01 at 10:50, James Simmons wrote:
>
> 1) Universal cursor api. This allows the fbcon layer to not be required
> hooks to program the cursor for every type of card avaliable. This
> allows a seperation of fbdev and fbcon.
> +struct fbcursor {
> + __u16 set; /* what to set */
> + __u16 enable;/* cursor on/off */
> + struct fbcurpos pos;/* cursor position */
> + struct fbcurpos hot;/* cursor hot spot */
> + struct fb_cmap cmap;/* color map info */
> + struct fbcurpos size;/* cursor bit map size */
> + char *image;/* cursor image bits */
> + char *mask;/* cursor mask bits */
> +};
Any details about contents of image and mask? Or is it just monochromatic
1bpp image? There is hardware which can do 16color hardware cursors (+
transparent+inverse).
And if it is 1bpp image, is it 0/1/transparent/invert (XGA), or
transp./transp./0/1 (X)?
Thanks,
Petr Vandrovec
van...@vc...
|
|
From: James S. <jsi...@tr...> - 2001-11-28 18:51:08
|
Hi!
This is my first public release of the new api of the framebuffer
layer. The basic goal is to remove all the excess duplicate code and to
place all the console related code into fbcon.c. The second goal to allow
the framebuffer layer to exist without the console system. On embedded
devices that lack a keyboard it makes no sense plus it takes up valiable
space to have the VT system compiled in. The 3rd and finally goal is to
allow fbdev driver writing to be easy and yet flexiable.
This patch shows 3 basic things I like to change.
1) Universal cursor api. This allows the fbcon layer to not be required
hooks to program the cursor for every type of card avaliable. This
allows a seperation of fbdev and fbcon.
2) Move from framebuffer base to more accel engine base. This allows the
complete removal of console code from the low level framebuffer drivers
and we get ride of those god forsaken fbcon-cfb* files. So we end up
with a huge code reducution and this encourages the driver write to
write much faster fbdev drivers. Note these our the basic accels needed
for the fbcon layer. They are not used by userland in anyway. It also
means you have only 3 basic functions to deal with instead of the 7 of
struct display_switch.
3) Removal of duplicate code. Examples are the fb_cmap functions which are
basically the same in every driver. So you will be seeing soon a
fbgen2 that will have the same code that is duplicated over and over
again in each driver.
--- /usr/src/linux-2.5.0/include/linux/fb.h Tue Nov 27 12:29:52 2001
+++ /usr/src/linux/include/linux/fb.h Wed Nov 28 11:47:29 2001
@@ -241,6 +241,65 @@
__u32 reserved[4]; /* reserved for future compatibility */
};
+/*
+ * hardware cursor control
+ */
+
+#define FB_CUR_SETCUR 0x01
+#define FB_CUR_SETPOS 0x02
+#define FB_CUR_SETHOT 0x04
+#define FB_CUR_SETCMAP 0x08
+#define FB_CUR_SETSHAPE 0x10
+#define FB_CUR_SETALL 0x1F
+
+struct fbcurpos {
+ __u16 x, y;
+};
+
+struct fbcursor {
+ __u16 set; /* what to set */
+ __u16 enable;/* cursor on/off */
+ struct fbcurpos pos;/* cursor position */
+ struct fbcurpos hot;/* cursor hot spot */
+ struct fb_cmap cmap;/* color map info */
+ struct fbcurpos size;/* cursor bit map size */
+ char *image;/* cursor image bits */
+ char *mask;/* cursor mask bits */
+};
+
+/* Internal HW accel */
+#define ROP_COPY 0
+#define ROP_XOR 1
+
+struct fb_copyarea {
+ __u32 sx; /* screen-relative */
+ __u32 sy;
+ __u32 width;
+ __u32 height;
+ __u32 dx;
+ __u32 dy;
+};
+
+struct fb_fillrect {
+ __u32 x1; /* screen-relative */
+ __u32 y1;
+ __u32 width;
+ __u32 height;
+ __u32 color;
+ __u32 rop;
+};
+
+struct fb_image {
+ __u32 width; /* Size of image */
+ __u32 height;
+ __u16 x; /* Where to place image */
+ __u16 y;
+ __u32 fg_color; /* Only used when a mono bitmap */
+ __u32 bg_color;
+ __u8 depth; /* Dpeth of the image */
+ char *data; /* Pointer to image data */
+};
+
#ifdef __KERNEL__
#if 1 /* to go away in 2.5.0 */
@@ -250,10 +309,10 @@
#endif
#include <linux/fs.h>
+#include <linux/poll.h>
#include <linux/init.h>
#include <linux/devfs_fs_kernel.h>
-
struct fb_info;
struct fb_info_gen;
struct vm_area_struct;
@@ -283,9 +342,29 @@
/* set colormap */
int (*fb_set_cmap)(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info);
- /* pan display (optional) */
- int (*fb_pan_display)(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
+ /* checks var and creates a par based on it */
+ int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);
+ /* set the video mode according to par */
+ int (*fb_set_par)(struct fb_info *info);
+ /* cursor control */
+ int (*fb_cursor)(struct fb_info *info, struct fbcursor *cursor);
+ /* set color register */
+ int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,
+ unsigned blue, unsigned transp, struct fb_info *info);
+ /* blank display */
+ int (*fb_blank)(int blank, struct fb_info *info);
+ /* pan display */
+ int (*fb_pan_display)(struct fb_var_screeninfo *var, int con, struct fb_info *info);
+ /* draws a rectangle */
+ void (*fb_fillrect)(struct fb_info *p, int x1, int y1, unsigned int width,
+ unsigned int height, unsigned long color, int rop);
+ /* Copy data from area to another */
+ void (*fb_copyarea)(struct fb_info *p, int sx, int sy, unsigned int width,
+ unsigned int height, int dx, int dy);
+ /* Draws a image to the display */
+ void (*fb_imageblit)(struct fb_info *p, struct fb_image *image);
+ /* perform polling on fb device */
+ int (*fb_poll)(struct fb_info *info, poll_table *wait);
/* perform fb specific ioctl (optional) */
int (*fb_ioctl)(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg, int con, struct fb_info *info);
@@ -309,6 +388,7 @@
char *screen_base; /* Virtual address */
struct display *disp; /* initial display variable */
struct vc_data *display_fg; /* Console visible on this display */
+ int currcon; /* Current VC. */
char fontname[40]; /* default font name */
devfs_handle_t devfs_handle; /* Devfs handle for new name */
devfs_handle_t devfs_lhandle; /* Devfs handle for compat. symlink */
@@ -387,6 +467,11 @@
struct fb_info *info);
extern int fbgen_pan_display(struct fb_var_screeninfo *var, int con,
struct fb_info *info);
+extern void cfb_fillrect(struct fb_info *p, int x1, int y1, unsigned int width,
+ unsigned int rows, unsigned long color, int rop);
+extern void cfb_copyarea(struct fb_info *p, int sx, int sy, unsigned int width,
+ unsigned int rows, int dx, int dy);
+extern void cfb_imageblit(struct fb_info *p, struct fb_image *image);
/*
* Helper functions
@@ -400,6 +485,7 @@
extern int fbgen_switch(int con, struct fb_info *info);
extern void fbgen_blank(int blank, struct fb_info *info);
+extern void fbgen2_set_disp(int con, struct fb_info *info);
/* drivers/video/fbmem.c */
extern int register_framebuffer(struct fb_info *fb_info);
|
|
From: James S. <jsi...@tr...> - 2001-11-28 17:53:55
|
> This is why I advocate that each driver have it's own modes table, I have actually thought about this before. Placing struct fb_videomode into struct fb_info. > which can be built from a standard set, or from the drivers own > needs. In this way the size of the table is minimized to just those > that are being used by the driver. > > so NOT this: > > mode_t my_modes = standard_modes_table; > > but more like this: > > mode_t my_modes = filter_standard_modes(&some_criteria); I like this as well. Especially if we implement EDID. > and then the standard modes table is freed after init. > __initdata takes care of that right? Yes. > In the driver I'm working on I have separated "mode" from "timings". > mode == The framebuffer mode. depth,pitch,size this is the stuff > that alters rendering. Yeap. > timings == Display setup. The display width, height, margins and > offsets. > > Timings can be set independent of the mode without flushing out the > rendering pipeline (physically or virtually speaking), no need to > blank the screen or refresh the data in the framebuffer. > > Modes cannot be set without setting the timings too since it is > likely that the new mode will require a different set of timings. > > Keeping these two separate makes the code clean, and keeps the tables > smaller. i.e. (modes + timings) < (modes * timings) Code a skeleton struct for this ? We can use this internally. I don't want to monkey around with the fbdev userland api since alot of apps depend on it. I rather see /dev/gfx replace it instead. |
|
From: James S. <jsi...@tr...> - 2001-11-27 23:33:03
|
PROC_CONSOLE is defined in fbcon.c. No need for duplicate code. Please
apply.
--- linux-2.5.0/drivers/video/modedb.c Tue Nov 27 16:05:02 2001
+++ linux/drivers/video/modedb.c Tue Nov 27 16:10:04 2001
@@ -14,9 +14,9 @@
#include <linux/module.h>
#include <linux/tty.h>
#include <linux/fb.h>
-#include <linux/console_struct.h>
#include <linux/sched.h>
+#include <video/fbcon.h>
#undef DEBUG
@@ -256,29 +256,6 @@
}
}
}
-
-static int PROC_CONSOLE(const struct fb_info *info)
-{
- int fgc;
-
- if (info->display_fg != NULL)
- fgc = info->display_fg->vc_num;
- else
- return -1;
-
- if (!current->tty)
- return fgc;
-
- if (current->tty->driver.type != TTY_DRIVER_TYPE_CONSOLE)
- /* XXX Should report error here? */
- return fgc;
-
- if (MINOR(current->tty->device) < 1)
- return fgc;
-
- return MINOR(current->tty->device) - 1;
-}
-
/**
* __fb_try_mode - test a video mode
|
|
From: James S. <jsi...@tr...> - 2001-11-27 22:52:26
|
> does there have to be a solution other than the one that exists now? Yes I like mmap to a large degree. In fact one of the things that has always excited me was the idea of using kio buffers to manage graphics hardware like the disk layer does. Think about the speed improvements since we wouldn't be going threw the VM layer. Basically we have raw IO instead of for disk for graphcis hardware. Plus we get the bounus of not worrying about inheritance issues. IRIX doesn't allow the graphics engine resources to be inherted. You could be but would be quite complex to handle. This includes file handles as well as mmapped resources. Some much more as well. Since the networking layer some day is going to go over to kio buffers in theory we could just feed data directly from the network hardware into the graphics hardware. Locally we could use enhanced version of mmap, read and write. Okay enough about my pipe dreams :-) |
|
From: James S. <jsi...@tr...> - 2001-11-27 22:05:58
|
> I've though of several use cases that make the current way of doing > things just unworkable. Okay. We have many cases where this is broken. [snip].. > I think you misinterpreted one of my functions....plus I left one > out. > > fb_put (Set a chunk of the framebuffer from the data provided. The > data comes fro userland or kernelland) > fb_set (The a chunk of the framebuffer to a single value) > fb_get (Get a chunk of data fro the framebuffer to the place > requested. It can be userland or kernelland) > fb_copy (aka blit, screen_to_screen) Okay. I'm warming up to this idea. Actually what I'm thinking is we have header filies for various graphics cards and each graphics card has a #include <linux/fb.h> Now in say each graphics card header we place a inline function that userland can use as well as the kernel for doing the basic functions: fb_put_pixels fb_get_pixels fb_memset fb_rectfill fb_copyarea fb_imageblit Just have the basic functions for the kernel tho. Lets not get crazy here. > This is hard for me to swallow since "what we have" cannot possibly > work for what I'm trying to do. It will only get worse if mmap > goes away. What I mean is the ideas are floating around but I can't keep track of everything. > I am writing up all the concepts I have floating around in my head > and I'll post it when I'm done. I have to believe that fixing all > the major issues is easier than trying to fix small parts. Okay. That would be good. |
|
From: <cw...@so...> - 2001-11-27 21:22:40
|
> I have wrestled with this as well. I haven't thought of a better solution > myself yet. does there have to be a solution other than the one that exists now? as far as i know, mmap can fail, thus indicating more than enough information to the program. (much like a failing malloc foretells of bad things to happen). i don't know posix in and out, but i am sure mmap is part of poxis (quick man page tells me so). it seems to not have a ENETDEV return code though :^). perhaps add something like that (and break posix), or use EACCESS perhaps. I'd like to hear Linus's proposition to this, simply because I do feel that removing mmap will cause nothing but problems in the long run. another possible thing to do would be to break /dev into 2 sub dirs, /dev/local and /dev/network, though that seems really crappy from the start and devfs probably doesnt allow that to work (i use kernel 2.2.16 at the moment, so i havn't dealt with devfs yet, nor usbdevfs). or, extend file flags (nrwxrwxrwx for net devices or something), but i don't know how fileflags really work (or even what their correct name is :^( none really work well, but im sure someone can think of something. chris --- moc.lexiptfos@thgirwc --- |
|
From: Sottek, M. J <mat...@in...> - 2001-11-27 20:12:06
|
>Well at present true. Actually I have been thinking about this
>problem. Plus someone talked about this a few days ago on the list.
>I personally have run inot the the problem of data write size
>restrictions. For me it was the Epson 1385 framebuffer. It only
>allows 16 bit accesses to the framebuffer. So if I do a raw cat
>I get strips down my screen. Lets not forget that use can't use
>memset on PPC on a framebuffer. So I agree we need to have fbdev
>functions for access to the framebuffer and they should
>be made avaliable to userland. The question is where to place
>these macros?
I've though of several use cases that make the current way of doing
things just unworkable.
#1 Banked memory. The whole reason I got involved in this was to
complete a stolen memory driver for the i810. It only has banked
memory in this mode and just can't work with the way things are.
#2 Network console? What happens if you want to write a driver that
is actually a networked console display? There is no framebuffer
locally so you can't access if without driver interfaces.
>So for fb_read and fb_write we need to copy the userland data into
>a temporary buffer and then use fb_memset to actually draw the image.
No, I was thinking that the functions below would be of this type
#define COPY_TO_USER 0x00000001
#define MEMCPY 0x00000002
void *fb_put(u8 *data, u32 srcx, u32 srcy, u32 width, u32 height,
u32 destx, u32 desty, u32 flags)
The driver would check flags and either memcpy or copy_to_user.
We probably need an fb_copy_to_user to handle byte swapping on
multiplatform drivers.
So no intermediate copy. That would be too slow.
>Yes. Remember tho it only does a rectangle of one color. We also
>nedd fb_write functions.
I think you misinterpreted one of my functions....plus I left one
out.
fb_put (Set a chunk of the framebuffer from the data provided. The
data comes fro userland or kernelland)
fb_set (The a chunk of the framebuffer to a single value)
fb_get (Get a chunk of data fro the framebuffer to the place
requested. It can be userland or kernelland)
fb_copy (aka blit, screen_to_screen)
>Oh my. I really have to think about this. For now lets just
>cleanup what we have.
This is hard for me to swallow since "what we have" cannot possibly
work for what I'm trying to do. It will only get worse if mmap
goes away.
I am writing up all the concepts I have floating around in my head
and I'll post it when I'm done. I have to believe that fixing all
the major issues is easier than trying to fix small parts.
-Matt
|
|
From: James S. <jsi...@tr...> - 2001-11-27 19:18:38
|
> >Set the fb_fix fields for mmio and smem to zero. As for internally with > >the new api you don't need to use the screen_base field. > >Just ignore it. > > After further review (correct me If I am wrong James) it seems that > screen base (a kernel virtual address to the framebuffer) is needed > for the fb_read and fb_write functions. It was suggested that > there isn't a way around this. Well at present true. Actually I have been thinking about this problem. Plus someone talked about this a few days ago on the list. I personally have run inot the the problem of data write size restrictions. For me it was the Epson 1385 framebuffer. It only allows 16 bit accesses to the framebuffer. So if I do a raw cat I get strips down my screen. Lets not forget that use can't use memset on PPC on a framebuffer. So I agree we need to have fbdev functions for access to the framebuffer and they should be made avaliable to userland. The question is where to place these macros? So for fb_read and fb_write we need to copy the userland data into a temporary buffer and then use fb_memset to actually draw the image. > fb_put: Put data from somewhere into the framebuffer. This is called > imageblit in the new API. This should have a parameter to tell you > to use copy_from_user() or memcpy() Yeap. > fb_get: Get data from the framebuffer and put it in a provided pointer. > This should have a flag to tell you to use copy_to_user() or > memcpy() See what I said above. We should also consider the endian of the buffers to. > fb_set: Set a region of the frambuffer with the value provided. This > is called fillrect(?) in the new api. Yes. Remember tho it only does a rectangle of one color. We also nedd fb_write functions. > I have thought of a compromise that should be very easy for most > drivers to do, and will allow us to keep the driver private stuff > hidden. [snip]... Oh my. I really have to think about this. For now lets just cleanup what we have. |
|
From: Petr V. <VAN...@vc...> - 2001-11-27 19:03:45
|
On 27 Nov 01 at 10:19, James Simmons wrote:
> > Do not forget that current API is atomic, with doing it in multiple
> > steps you can get nasty surprises (as resolution and resolution_virt
> > depends one on another, either changing one changes also another one,
> > or some modes are not accessible without first modifying resolution_virt),
> > besides not being atomic...
>
> Not really. If you have a accelerated driver and a userland process open
> /dev/fb and changes the video mode the driver could be in the middle of a
> draw operation. So teh fbdev layer lacks any really type of locking. We
> could add a spinlock or a semaphore but it is more complex then that. The
> accel engine could be busy for sometime. So we have to wait until it is
> idle. So a clever way of locking has to be done.
matroxfb uses spinlock around accelerator, and ioctl is serialized by
big kernel lock. But my atomicity requirement is not this. It is that
request for 'xres=1024,yres=768,depth=24,vxres=2048,vyres=100000' should
be refused completely, instead of switching to 1024x768-24 with vxres=2048,
and then realizing that vyres=100000 is incompatible with currently
installed memory.
And when current mode is 512x384-32, and request is for
'xres=1024,yres=768,depth=8', it should switch at once, and not step by
step, saying that there is not enough memory for 1024x768-32 (because
of it went through 1024x384-32, 1024x768-32, 1024x768-8)... But
I think that there is consensus on this one.
Petr Vandrovec
van...@vc...
|
|
From: James S. <jsi...@tr...> - 2001-11-27 18:58:14
|
> perhaps a better way of implimenting this can happen? surely removing mmap is > not the way to go. I have wrestled with this as well. I haven't thought of a better solution myself yet. |
|
From: James S. <jsi...@tr...> - 2001-11-27 18:19:34
|
> Do not forget that current API is atomic, with doing it in multiple > steps you can get nasty surprises (as resolution and resolution_virt > depends one on another, either changing one changes also another one, > or some modes are not accessible without first modifying resolution_virt), > besides not being atomic... Not really. If you have a accelerated driver and a userland process open /dev/fb and changes the video mode the driver could be in the middle of a draw operation. So teh fbdev layer lacks any really type of locking. We could add a spinlock or a semaphore but it is more complex then that. The accel engine could be busy for sometime. So we have to wait until it is idle. So a clever way of locking has to be done. > And AFAIK Al Viro (main ioctl killer) does not require that every current > fb_*_info field should have its own file. From his posts I understand > that he is completely satisfied with just some text-based extensible API, > so > ( > echo "mode=1024x768-16@60,outputfmt=NTSC,vxres=2048,xoffset=141" >&0 > read a > echo $a > ) <> /dev/fb0/control' > would be enough for him... As there is already couple of comma separated > list parsers in the kernel (mount options, kernel cmdline), I think that > it is preferred format - in simplest form you write one line in, and > get one line back... Yeap. That is basically what he wants. |
|
From: Jani M. <ja...@as...> - 2001-11-27 14:11:19
|
Hi
I would appreciate if any of the knowledgable people on this list
could spare a few minutes and look through this fb driver I wrote for
trident blade chips for any stupidities regarding API usage.Especially
the init function (tridentfb_init)
There are a few things (I think not hw related) that are annoying:
* when I insmod it the console is cleared with white(maybe that's OK
I haven't seen other modular fb's?)
* it oopses in fbcon_setup when initial depth=32,because apparently
p->dispsw == NULL in macro fontwidthvalid.Other bpp's work OK and I don't
see what I have done differently...If I switch to 32bpp afterwards all's
well.
* when in Midnight Commander's backgound console (a pty) acceleration is
slow.you can actually see menus redrawn in make menuconfig.Without mc
it's about twice as fast as vesafb
*is hwsitch->detect() needed?
I intend to port this to the new API once it is tested
Thanks in advance
Jani.
Two eyes bad,more eyes good!
/*
* Frame buffer driver for Trident Blade3D series
*
* Copyright 2001 - Jani Monoses <ja...@as...>
*
* $Id: trident.c,v 1.46 2001/11/27 14:47:35 jani Exp $
*
* CREDITS:(in order of appearance)
* skeletonfb.c by Geert Uytterhoeven and other fb code in drivers/video
* Special thanks ;) to Mattia Crivellini <ti...@mc...>
* much inspired by the XFree86 4.1.0 Trident driver sources by Alan Hourihane
* the FreeVGA project
*
* NOTES:
* Only tested on Compaq Presario 12XL300 with CyberBladei1 and Flat Panel or
* external monitor
* with 8bb 16bpp 32bpp 640x480 and 800x600 combinations.
* It should work on Image3D cards as well except acceleration.
* No monitors were harmed during the writing of this driver.
* TODO:
* timing value tweaking so it looks good on every monitor in every mode
* text acceleration for the Image series
* PCI ids
* DPMS stuff
*
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/selection.h>
#include <video/fbcon.h>
#include <video/fbcon-cfb8.h>
#include <video/fbcon-cfb16.h>
#include <video/fbcon-cfb24.h>
#include <video/fbcon-cfb32.h>
#include "trident_regs.h"
#define TRIDENTFB_DEBUG 0
#if TRIDENTFB_DEBUG
#define debug(f,a...) printk("%s:" f, __FUNCTION__ , ## a)
#else
#define debug(f,a...)
#endif
#define Mb (1024*1024)
struct tridentfb_par {
struct fb_var_screeninfo var;
int bpp;
int hres;
int vres;
int multiplex;
int linelength;
int vclk; //in MHz
int vtotal;
int vdispend;
int vsyncstart;
int vsyncend;
int vblankstart;
int vblankend;
int htotal;
int hdispend;
int hsyncstart;
int hsyncend;
int hblankstart;
int hblankend;
};
struct tridentfb_info {
struct fb_info_gen gen;
unsigned int fbmem_virt; //framebuffer virtual memory address
unsigned int fbmem; //framebuffer physical memory address
unsigned int memsize; //size of fbmem
unsigned int io; //io space address
unsigned int io_virt; //iospace virtual memory address
struct tridentfb_par currentmode;
unsigned short cmap_cfb16[16];
unsigned short cmap_cfb15[16];
unsigned int cmap_cfb32[16];
unsigned int frequency;
};
static struct fb_ops tridentfb_ops;
static struct tridentfb_info fb_info;
static struct display disp;
static struct {unsigned char red,green,blue,pad; } palette[256];
static struct fb_var_screeninfo default_var;
static char * tridentfb_name = "Trident";
/* default values for boot/module parameters */
static char * mode = "800x600";
static int depth = 8;
static int noaccel = 0;
static int center = 0;
MODULE_PARM(depth,"i");
MODULE_PARM(center,"i");
MODULE_PARM(noaccel,"i");
MODULE_PARM(mode,"s");
#define CRT 0x3D0 //CRTC registers offset for color display
#ifndef TRIDENT_MMIO
#define TRIDENT_MMIO 1
#endif
#if TRIDENT_MMIO
#define t_outb(val,reg) writeb(val,fb_info.io_virt + reg)
#define t_inb(reg) readb(fb_info.io_virt + reg)
#else
#define t_outb(val,reg) outb(val,reg)
#define t_inb(reg) inb(reg)
#endif
/*
* text acceleration
*/
static struct accel_switch {
void (*init_accel)(int,int);
void (*wait_engine)(void);
void (*fill_rect)(int,int,int,int,int);
void (*copy_rect)(int,int,int,int,int,int);
} *acc;
#define writemmr(r,v) writel(v, fb_info.io_virt + r)
#define readmmr(r) readl(fb_info.io_virt + r)
#define point(x,y) ((y)<<16|(x))
#define STA 0x2120
#define CMD 0x2144
#define ROP 0x2148
#define CLR 0x2160
#define SR1 0x2100
#define SR2 0x2104
#define DR1 0x2108
#define DR2 0x210C
#define REPL(x) x = x | x<<16
#define ROP_S 0xCC
static void blade_init_accel(int pitch,int bpp)
{
int v1 = (pitch>>3)<<20;
int tmp = 0,v2;
switch (bpp) {
case 8:tmp = 0;break;
case 15:tmp = 5;break;
case 16:tmp = 1;break;
case 24:
case 32:tmp = 2;break;
}
v2 = v1 | (tmp<<29);
writemmr(0x21C0,v2);
writemmr(0x21C4,v2);
writemmr(0x21B8,v2);
writemmr(0x21BC,v2);
writemmr(0x21D0,v1);
writemmr(0x21D4,v1);
writemmr(0x21C8,v1);
writemmr(0x21CC,v1);
writemmr(0x216C,0);
}
static void blade_wait_engine(void)
{
while (readmmr(STA) & 0xFA800000)
schedule_timeout(1*HZ/1000); //1.0 msecs
}
static void blade_fill_rect(int x,int y,int w,int h,int c)
{
blade_wait_engine();
writemmr(CLR,c);
writemmr(ROP,ROP_S);
writemmr(CMD,0x20000000|1<<19|1<<4|2<<2);
writemmr(DR1,point(x,y));
writemmr(DR2,point(x+w-1,y+h-1));
blade_wait_engine();
}
static void blade_copy_rect(int x1,int y1,int x2,int y2,int w,int h)
{
int s1,s2,d1,d2;
int direction = 2;
s1 = point(x1,y1);
s2 = point(x1+w-1,y1+h-1);
d1 = point(x2,y2);
d2 = point(x2+w-1,y2+h-1);
if ((y1 > y2) || ((y1 == y2) && (x1 >x2)))
direction = 0;
blade_wait_engine();
writemmr(ROP,ROP_S);
writemmr(CMD,0xE0000000|1<<19|1<<4|1<<2|direction);
writemmr(SR1,direction?s2:s1);
writemmr(SR2,direction?s1:s2);
writemmr(DR1,direction?d2:d1);
writemmr(DR2,direction?d1:d2);
blade_wait_engine();
}
static struct accel_switch accel_blade = {
blade_init_accel,
blade_wait_engine,
blade_fill_rect,
blade_copy_rect,
};
static void image_init_accel(int pitch,int bpp)
{
int tmp = 0;
switch (bpp) {
case 8:tmp = 0;break;
case 15:tmp = 5;break;
case 16:tmp = 1;break;
case 24:
case 32:tmp = 2;break;
}
writemmr(0x2120, 0xF0000000);
writemmr(0x2120, 0x40000000|tmp);
writemmr(0x2120, 0x80000000);
writemmr(0x2144, 0x00000000);
writemmr(0x2148, 0x00000000);
writemmr(0x2150, 0x00000000);
writemmr(0x2154, 0x00000000);
writemmr(0x2120, 0x60000000 |(pitch<<16) |pitch);
writemmr(0x216C, 0x00000000);
writemmr(0x2170, 0x00000000);
writemmr(0x217C, 0x00000000);
writemmr(0x2120, 0x10000000);
writemmr(0x2130, (2047 << 16) | 2047);
}
static void image_wait_engine(void)
{
while (readmmr(0x2164) & 0xF0000000)
schedule_timeout(1*HZ/1000); //1.0 msecs
}
static void image_fill_rect(int x,int y,int w,int h,int c)
{
writemmr(0x2120,0x80000000);
writemmr(0x2120,0x90000000|ROP_S);
writemmr(0x2144,c);
writemmr(DR1,point(x,y));
writemmr(DR2,point(x+w-1,y+h-1));
writemmr(0x2124,0x80000000|3<<22|1<<10|1<<9);
}
static void image_copy_rect(int x1,int y1,int x2,int y2,int w,int h)
{
int s1,s2,d1,d2;
int direction = 2;
s1 = point(x1,y1);
s2 = point(x1+w-1,y1+h-1);
d1 = point(x2,y2);
d2 = point(x2+w-1,y2+h-1);
if ((y1 > y2) || ((y1 == y2) && (x1 >x2)))
direction = 0;
writemmr(0x2120,0x80000000);
writemmr(0x2120,0x90000000|ROP_S);
writemmr(SR1,direction?s2:s1);
writemmr(SR2,direction?s1:s2);
writemmr(DR1,direction?d2:d1);
writemmr(DR2,direction?d1:d2);
writemmr(0x2124,0x80000000|1<<22|1<<10|1<<7|direction);
}
static struct accel_switch accel_image = {
image_init_accel,
image_wait_engine,
image_fill_rect,
image_copy_rect,
};
static void trident_bmove (struct display *p, int sy, int sx,
int dy, int dx, int height, int width)
{
sx *= fontwidth(p);
dx *= fontwidth(p);
width *= fontwidth(p);
sy *= fontheight(p);
dy *= fontheight(p);
height *= fontheight(p);
acc->copy_rect(sx,sy,dx,dy,width,height);
}
#ifdef FBCON_HAS_CFB8
static void trident_8bpp_clear (struct vc_data *conp, struct display *p,
int sy, int sx, int height, int width)
{
int c;
c = attr_bgcol_ec(p,conp) & 0xff;
c |= c<<8;
c |= c<<16;
sx *= fontwidth(p);
sy *= fontheight(p);
width *= fontwidth(p);
height *= fontheight(p);
acc->fill_rect(sx,sy,width,height,c);
}
static struct display_switch trident_8bpp = {
setup: fbcon_cfb8_setup,
bmove: trident_bmove,
clear: trident_8bpp_clear,
putc: fbcon_cfb8_putc,
putcs: fbcon_cfb8_putcs,
revc: fbcon_cfb8_revc,
clear_margins: fbcon_cfb8_clear_margins,
fontwidthmask: FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16)
};
#endif
#ifdef FBCON_HAS_CFB16
static void trident_16bpp_clear (struct vc_data *conp, struct display *p,
int sy, int sx, int height, int width)
{
int c;
c = ((u16*)p->dispsw_data)[attr_bgcol_ec(p,conp)];
c = c | c<<16;
sx *= fontwidth(p);
sy *= fontheight(p);
width *= fontwidth(p);
height *= fontheight(p);
acc->fill_rect(sx,sy,width,height,c);
}
static struct display_switch trident_16bpp = {
setup: fbcon_cfb16_setup,
bmove: trident_bmove,
clear: trident_16bpp_clear,
putc: fbcon_cfb16_putc,
putcs: fbcon_cfb16_putcs,
revc: fbcon_cfb16_revc,
clear_margins: fbcon_cfb16_clear_margins,
fontwidthmask: FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16)
};
#endif
#ifdef FBCON_HAS_CFB32
static void trident_32bpp_clear (struct vc_data *conp, struct display *p,
int sy, int sx, int height, int width)
{
int c;
c = ((u32*)p->dispsw_data)[attr_bgcol_ec(p,conp)];
sx *= fontwidth(p);
sy *= fontheight(p);
width *= fontwidth(p);
height *= fontheight(p);
acc->fill_rect(sx,sy,width,height,c);
}
static struct display_switch trident_32bpp = {
setup: fbcon_cfb32_setup,
bmove: trident_bmove,
clear: trident_32bpp_clear,
putc: fbcon_cfb32_putc,
putcs: fbcon_cfb32_putcs,
revc: fbcon_cfb32_revc,
clear_margins: fbcon_cfb32_clear_margins,
fontwidthmask: FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16)
};
#endif
/* read memory mapped register */
static inline unsigned char read3X4(int reg)
{
writeb(reg, fb_info.io_virt + CRT + 4);
return readb(fb_info.io_virt + CRT + 5);
}
/* write memory mapped register */
static inline void write3X4(int reg, unsigned char val)
{
writeb(reg, fb_info.io_virt + CRT + 4);
writeb(val, fb_info.io_virt + CRT + 5);
}
/* read register */
static inline unsigned char read3C4(int reg)
{
t_outb(reg, 0x3C4);
return t_inb(0x3C5);
}
/* write register */
static inline void write3C4(int reg, unsigned char val)
{
t_outb(reg, 0x3C4);
t_outb(val, 0x3C5);
}
/* read register */
static inline unsigned char read3CE(int reg)
{
t_outb(reg, 0x3CE);
return t_inb(0x3CF);
}
/* write attribute controller register */
static inline void writeAttr(int reg, unsigned char val)
{
readb(fb_info.io_virt + CRT + 0xA); //flip-flop to index
t_outb(reg, 0x3C0);
t_outb(val, 0x3C0);
}
/* read attribute controller register */
static inline unsigned char readAttr(int reg)
{
readb(fb_info.io_virt + CRT + 0xA); //flip-flop to index
t_outb(reg, 0x3C0);
return t_inb(0x3C1);
}
/* write register */
static inline void write3CE(int reg, unsigned char val)
{
t_outb(reg, 0x3CE);
t_outb(val, 0x3CF);
}
#define unprotect_all() write3C4(Protection, 0x92);unprotect()
#define unprotect() write3C4(NewMode1,0xC2)
#define new_mode() read3C4(OldOrNew)
#define bios_mode(mode) write3CE(BiosMode, mode)
#define bios_reg(reg) write3CE(BiosReg, reg)
#define enable_mmio() outb(PCIReg, 0x3D4); \
outb(inb(0x3D5) | 0x01, 0x3D5)
#define disable_mmio() write3X4(PCIReg,read3X4(PCIReg) & ~1)
/* enable/disable writes to CRTC registers */
#define crtc_lock() write3X4(CRTVSyncEnd, read3X4(CRTVSyncEnd) | 0x80)
#define crtc_unlock() write3X4(CRTVSyncEnd, read3X4(CRTVSyncEnd) & 0x7F)
static void set_lwidth(int width)
{
write3X4(Offset, width & 0xFF);
write3X4(AddColReg, (read3X4(AddColReg) & 0xCF) | ((width & 0x300) >>4));
}
/* For resolutions smaller than FP resolution stretch */
static void screen_stretch(void)
{
write3CE(VertStretch,(read3CE(VertStretch) & 0x7C) | 1);
write3CE(HorStretch,(read3CE(HorStretch) & 0x7C) | 1);
}
/* For resolutions smaller than FP resolution center */
static void screen_center(void)
{
bios_reg(0); // no stretch
write3CE(VertStretch,(read3CE(VertStretch) & 0x7C) | 0x80);
write3CE(HorStretch,(read3CE(HorStretch) & 0x7C) | 0x80);
}
/* Address of first shown pixel in display memory */
static void set_screen_start(int base)
{
unprotect_all();
write3X4(StartAddrLow, base & 0xFF);
write3X4(StartAddrHigh, (base & 0xFF00) >>8);
write3X4(CRTCModuleTest, (read3X4(CRTCModuleTest) & 0xDF) | ((base & 0x10000) >>11));
write3X4(CRTHiOrd, (read3X4(CRTHiOrd) & 0xF8) | (base & 0xE0000) >> 17);
}
/* VCLK handling */
#define power(x) (1<<x)
#define calc_freq(n,m,k) ((NTSC * (n+8))/((m+2)*power(k)))
static void set_vclk(int freq)
{
int m,n,k;
int f,fi,d,di;
unsigned char lo=0,hi=0;
d = 20;
for(k = 2;k>=0;k--)
for(m = 0;m<63;m++)
for(n = 0;n<128;n++) {
fi = calc_freq(n,m,k);
if ((di = abs(fi - freq)) < d) {
d = di;
f = fi;
lo = n;
hi = (k<<6) | m;
}
}
write3C4(ClockHigh,hi);
write3C4(ClockLow,lo);
}
static void set_number_of_lines(int lines)
{
int tmp = read3CE(CyberEnhance) & 0x8F;
if (lines > 768)
tmp |= 0x30;
else if (lines > 600)
tmp |= 0x20;
else if (lines > 480)
tmp |= 0x10;
write3CE(CyberEnhance, tmp);
}
static unsigned int get_memsize(void)
{
unsigned char tmp;
tmp = read3X4(SPR) & 0x0F;
switch (tmp) {
case 3:return 1 * Mb;
case 7:return 2 * Mb;
case 15:return 4 * Mb;
case 4:return 8 * Mb;
default:return 0;
}
}
static void trident_detect(void)
{
}
/* Fill in fix */
static int trident_encode_fix(struct fb_fix_screeninfo *fix,
const void *par,
struct fb_info_gen *info)
{
struct tridentfb_info * i = (struct tridentfb_info *)info;
struct tridentfb_par * p = (struct tridentfb_par *)par;
memset(fix, 0, sizeof(struct fb_fix_screeninfo));
strcpy(fix->id,tridentfb_name);
fix->smem_start = i->fbmem;
fix->smem_len = i->memsize;
fix->type = FB_TYPE_PACKED_PIXELS;
fix->type_aux = 0;
fix->visual = p->bpp==8 ? FB_VISUAL_PSEUDOCOLOR:FB_VISUAL_DIRECTCOLOR;
fix->xpanstep = fix->ywrapstep = 0;
fix->ypanstep = 1;
fix->line_length = p->linelength;
fix->mmio_start = 0;
fix->mmio_len = 0;
fix->accel = FB_ACCEL_NONE;
return 0;
}
/* Fill in par from var */
static int trident_decode_var(const struct fb_var_screeninfo *var,
void *par,
struct fb_info_gen *info)
{
struct tridentfb_par * p = (struct tridentfb_par *)par;
// struct tridentfb_info * i = (struct tridentfb_info *)info;
/*
* Get the video params out of 'var'. If a value doesn't fit, round it up,
* if it's too big, return -EINVAL.
*
* Suggestion: Round up in the following order: bits_per_pixel, xres,
* yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale,
* bitfields, horizontal timing, vertical timing.
*/
p->var = *var;
p->bpp = var->bits_per_pixel;
if (p->bpp == 24 )
p->bpp = 32;
p->linelength = var->xres_virtual * p->bpp/8;
switch (p->bpp) {
case 8:
p->var.red.offset = 0;
p->var.green.offset = 0;
p->var.blue.offset = 0;
p->var.red.length = 6;
p->var.green.length = 6;
p->var.blue.length = 6;
break;
case 16:
p->var.red.offset = 11;
p->var.green.offset = 5;
p->var.blue.offset = 0;
p->var.red.length = 5;
p->var.green.length = 6;
p->var.blue.length = 5;
break;
case 32:
p->var.red.offset = 16;
p->var.green.offset = 8;
p->var.blue.offset = 0;
p->var.red.length = 8;
p->var.green.length = 8;
p->var.blue.length = 8;
break;
default:
printk("Wrong bpp\n");
return -EINVAL;
}
/* convert from picoseconds to MHz */
p->vclk = 1000000/var->pixclock;
if (p->bpp == 32)
p->vclk *=2;
p->hres = var->xres;
p->vres = var->yres;
/* Compute horizontal and vertical VGA CRTC timing values */
p->htotal = (p->hres + var->left_margin + var->right_margin + var->hsync_len)/8 - 10;
p->hdispend = p->hres/8 - 1;
p->hsyncstart = (p->hres + var->right_margin)/8;
p->hsyncend = var->hsync_len/8;
p->hblankstart = p->hdispend + 1;
p->hblankend = p->htotal + 5;
p->vtotal = p->vres + var->upper_margin + var->lower_margin + var->vsync_len - 2;
p->vdispend = p->vres - 1;
p->vsyncstart = p->vres + var->lower_margin;
p->vsyncend = var->vsync_len;
p->vblankstart = p->vres;
p->vblankend = p->vtotal +2;
return 0;
}
/* Fill in var from info */
static int trident_encode_var(struct fb_var_screeninfo *var,
const void *par,
struct fb_info_gen *info)
{
struct tridentfb_par * p = (struct tridentfb_par *)par;
*var = p->var;
var->bits_per_pixel = p->bpp;
return 0;
}
/* Fill in par from hardware */
static void trident_get_par(void *par, struct fb_info_gen *info)
{
struct tridentfb_par * p = (struct tridentfb_par *)par;
struct tridentfb_info * i = (struct tridentfb_info *)info;
*p = i->currentmode;
}
static int trident_pan_display(const struct fb_var_screeninfo *,
struct fb_info_gen *);
/* Set the hardware from par */
static void trident_set_par(const void *par, struct fb_info_gen *info)
{
struct tridentfb_par * p = (struct tridentfb_par *)par;
struct tridentfb_info * i = (struct tridentfb_info *)info;
unsigned char tmp;
i->currentmode = *p;
unprotect_all();
crtc_unlock();
enable_mmio();
if (p->hres < 800) {
t_outb(0xEB,0x3C2); //misc output reg
write3CE(CyberControl,0x81);
if (center || p->bpp==32)
// if (center)
screen_center();
else
screen_stretch();
}
else {
t_outb(0x2B,0x3C2); //misc output reg
write3CE(CyberControl,8); //disable H and V shadow regs (X and BIOS value)
}
#if 0
if (p->hres == 800)
write3CE(CyberControl,8); //disable H and V shadow regs (X and BIOS value)
else
//write3CE(CyberControl,0x87); //
write3CE(CyberControl,0x81); //
#endif
/* vertical timing values */
write3X4(CRTVTotal, p->vtotal & 0xFF);
write3X4(CRTVDispEnd, p->vdispend & 0xFF);
write3X4(CRTVSyncStart, p->vsyncstart & 0xFF);
write3X4(CRTVSyncEnd, (p->vsyncend & 0x0F));
write3X4(CRTVBlankStart, p->vblankstart & 0xFF);
write3X4(CRTVBlankEnd, 0/*p->vblankend & 0xFF*/);
/* horizontal timing values */
write3X4(CRTHTotal, p->htotal & 0xFF);
write3X4(CRTHDispEnd, p->hdispend & 0xFF);
write3X4(CRTHSyncStart, p->hsyncstart & 0xFF);
write3X4(CRTHSyncEnd, (p->hsyncend & 0x1F) | ((p->hblankend & 0x20)<<2));
write3X4(CRTHBlankStart, p->hblankstart & 0xFF);
write3X4(CRTHBlankEnd, 0/*(p->hblankend & 0x1F)*/);
/* higher bits of vertical timing values */
tmp = 0x10;
if (p->vtotal & 0x100) tmp |= 0x01;
if (p->vdispend & 0x100) tmp |= 0x02;
if (p->vsyncstart & 0x100) tmp |= 0x04;
if (p->vblankstart & 0x100) tmp |= 0x08;
if (p->vtotal & 0x200) tmp |= 0x20;
if (p->vdispend & 0x200) tmp |= 0x40;
if (p->vsyncstart & 0x200) tmp |= 0x80;
write3X4(CRTOverflow, tmp);
tmp = read3X4(CRTHiOrd) | 0x08; //line compare bit 10
if (p->vtotal & 0x400) tmp |= 0x80;
if (p->vblankstart & 0x400) tmp |= 0x40;
if (p->vsyncstart & 0x400) tmp |= 0x20;
if (p->vdispend & 0x400) tmp |= 0x10;
write3X4(CRTHiOrd, tmp);
write3X4(HorizOverflow, 0); //no such great xres yet to need bit 9
//cursor stuff
for (tmp = 0xA;tmp<0x10;tmp++)
write3X4(tmp,0);
tmp = 0x40;
if (p->vblankstart & 0x200) tmp |= 0x20;
write3X4(CRTMaxScanLine, tmp);
write3X4(CRTLineCompare,0xff);
write3X4(CRTPRowScan,0);
write3X4(CRTModeControl,0xc3);
write3X4(LinearAddReg,0x20); //enable linear addressing
write3X4(CRTCModuleTest,0x80); //enable access extended memory
write3X4(GraphEngReg, 0x80); //enable GE for text acceleration
acc->init_accel(p->hres,p->bpp);
switch (p->bpp) {
case 8:tmp=0;break;
case 15:
case 16:tmp=5;break;
case 24:
/* tmp=0x29;break; */
/* seems like 24bpp is same as 32bpp when using vesafb */
case 32:tmp=9;break;
}
write3X4(PixelBusReg, tmp);
write3X4(InterfaceSel, 0x5B); //32bit internal data path
write3X4(DRAMControl, 0x30); //both IO,linear enable
write3X4(Performance, 0xBF); //
write3X4(PCIReg,0x7); //MMIO & PCI read and write burst enable
set_vclk(p->vclk);
write3C4(0,3);
write3C4(1,1); //set char clock 8 dots wide
write3C4(2,0x0f); //enable 4 maps because needed in chain4 mode
write3C4(3,0);
write3C4(4,0x0e); //memory mode enable bitmaps ??
//Graphics engine settings
write3CE(MiscExtFunc,(p->bpp==32)?0x1A:0x12); //divide clock by 2 if 32bpp
write3CE(0x5,0x40); //no CGA compat,allow 256 col WTF???
write3CE(0x6,0x05); //graphics mode
write3CE(0x7,0x0f); //planes?
writeAttr(0x10,0x41); //graphics mode and support 256 color modes
writeAttr(0x12,0xf); //planes
writeAttr(0x13,0); //horizontal pel panning
//colors
for(tmp = 0;tmp <0x10;tmp++)
writeAttr(tmp,tmp);
readb(fb_info.io_virt + CRT + 0xA); //flip-flop to index
t_outb(0x20, 0x3C0); //enable attr
switch (p->bpp) {
case 8: tmp = 0;break; //256 colors
case 15: tmp = 0x10;break;
case 16: tmp = 0x30;break; //hicolor
case 24: //truecolor
case 32: tmp = 0xD0;break;
}
t_inb(0x3C8);
t_inb(0x3C6);
t_inb(0x3C6);
t_inb(0x3C6);
t_inb(0x3C6);
t_outb(tmp,0x3C6);
t_inb(0x3C8);
set_number_of_lines(p->vres);
set_lwidth(p->hres*p->bpp/(4*16));
//text_accel = p->var.accel_flags & ACCELF_TEXT;
trident_pan_display(&p->var,info);
}
static int trident_getcolreg(unsigned regno, unsigned *red,
unsigned *green, unsigned *blue,
unsigned *transp, struct fb_info *info)
{
/*
* Read a single color register and split it into colors/transparent.
* The return values must have a 16 bit magnitude.
* Return != 0 for invalid regno.
*/
// struct tridentfb_info * i = (struct tridentfb_info *)info;
if (regno >255 ) {
printk("regno > 255\n");
return -EINVAL;
}
*red = palette[regno].red;
*green = palette[regno].green;
*blue = palette[regno].blue;
*transp = 0;
return 0;
}
static int trident_setcolreg(unsigned regno, unsigned red, unsigned green,
unsigned blue, unsigned transp,
struct fb_info *info)
{
/*
* Set a single color register. The values supplied have a 16 bit
* magnitude.
* Return != 0 for invalid regno.
*/
struct tridentfb_info * i = (struct tridentfb_info *)info;
int bpp = i->currentmode.bpp;
unsigned char r,g,b;
if (bpp==8) {
r = red&0xff;
g = green&0xff;
b = blue&0xff;
t_outb(regno,0x3C8);
t_outb(r,0x3C9);
t_outb(g,0x3C9);
t_outb(b,0x3C9);
}
if (regno < 16) {
palette[regno].red = red;
palette[regno].green = green;
palette[regno].blue = blue;
}
if (bpp == 16) /* RGB 565 */
i->cmap_cfb16[regno] = (red & 0xf800) |
((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
else
if (bpp == 15) /* RGB 555 */
i->cmap_cfb15[regno] = ((red & 0xf800) >> 1) |
((green & 0xf800) >> 6) | ((blue & 0xf800) >> 11);
else
if (bpp == 32) /* ARGB 8888 */
i->cmap_cfb32[regno] = ((transp & 0xFF00) << 16) |
((red & 0xFF00) << 8) |
(green & 0xFF00) | ((blue & 0xff00) >> 8);
return 0;
}
static int trident_pan_display(const struct fb_var_screeninfo *var,
struct fb_info_gen *info)
{
unsigned int offset;
struct tridentfb_info * i = (struct tridentfb_info *)info;
offset = (var->xoffset + (var->yoffset * var->xres))
* var->bits_per_pixel/32;
i->currentmode.var.xoffset = var->xoffset;
i->currentmode.var.yoffset = var->yoffset;
set_screen_start(offset);
return 0;
}
/* Later */
static int trident_blank(int blank_mode, struct fb_info_gen *info)
{
return 0;
}
/* Set display switch used by console */
static void trident_set_disp(const void *par, struct display *disp,
struct fb_info_gen *info)
{
struct tridentfb_info * i = (struct tridentfb_info *)info;
struct tridentfb_par * p = (struct tridentfb_par *)par;
disp->screen_base = (char *)i->fbmem_virt;
#ifdef FBCON_HAS_CFB8
if (p->bpp == 8 ) {
if (p->var.accel_flags & FB_ACCELF_TEXT)
disp->dispsw = &trident_8bpp;
else
disp->dispsw = &fbcon_cfb8;
} else
#endif
#ifdef FBCON_HAS_CFB16
if (p->bpp == 16) {
if (p->var.accel_flags & FB_ACCELF_TEXT)
disp->dispsw = &trident_16bpp;
else
disp->dispsw = &fbcon_cfb16;
disp->dispsw_data =i->cmap_cfb16; /* console palette */
} else
#endif
#ifdef FBCON_HAS_CFB32
if (p->bpp == 32) {
if (p->var.accel_flags & FB_ACCELF_TEXT)
disp->dispsw = &trident_32bpp;
else
disp->dispsw = &fbcon_cfb32;
disp->dispsw_data =i->cmap_cfb32; /* console palette */
} else
#endif
disp->dispsw = &fbcon_dummy;
}
static struct fbgen_hwswitch trident_hwswitch = {
trident_detect,
trident_encode_fix,
trident_decode_var,
trident_encode_var,
trident_get_par,
trident_set_par,
trident_getcolreg,
trident_setcolreg,
trident_pan_display,
trident_blank,
trident_set_disp
};
/* PCI IDS temporarily here */
#define CYBERBLADEi1 0x8520
#define CYBER9397DVD 0x939A
#define CYBER9525DVD 0x9525
#define IMAGE 0
#define BLADE 1
#define is_image() (family == IMAGE)
#define is_blade() (family == BLADE)
static struct almost_supported_board {
int pci_id;
int family;
struct accel_switch * acc;
} asb[] = {
{CYBERBLADEi1,BLADE,&accel_blade},
{CYBER9525DVD,IMAGE,&accel_image},
};
static int asb_count = sizeof(asb)/sizeof(asb[1]);
static int family;
int __init tridentfb_init(void)
{
int i,j;
struct pci_dev * board;
for (i = 0;i<asb_count;i++) {
if ((board = pci_find_device(PCI_VENDOR_ID_TRIDENT, asb[i].pci_id, NULL))) {
family = asb[i].family;
acc = asb[i].acc;
goto on;
}
}
return -1;
on:
fb_info.frequency = NTSC;
/* MMIO */
fb_info.io = pci_resource_start(board,1);
#if 0
if (!request_region(fb_info.io, TRIDENT_IOSIZE, "tridentfb")) {
return -1;
};
#endif
fb_info.io_virt = (unsigned int)ioremap_nocache(fb_info.io, TRIDENT_IOSIZE);
if (!fb_info.io_virt) {
release_region(fb_info.io, TRIDENT_IOSIZE);
return -1;
}
/* Framebuffer memory */
fb_info.fbmem = pci_resource_start(board,0);
fb_info.memsize = get_memsize();
#if 0
if (!request_mem_region(fb_info.fbmem, fb_info.memsize, "tridentfb")) {
return -1;
}
#endif
fb_info.fbmem_virt = (unsigned int)ioremap_nocache(fb_info.fbmem, fb_info.memsize);
if (!fb_info.fbmem_virt) {
release_mem_region(fb_info.fbmem, fb_info.memsize);
return -1;
}
debug("Trident board found : mem = %X,io = %X, mem_v = %X, io_v = %X\n",
fb_info.fbmem, fb_info.io, fb_info.fbmem_virt, fb_info.io_virt);
fb_info.gen.parsize = sizeof (struct tridentfb_par);
fb_info.gen.fbhw = &trident_hwswitch;
strcpy(fb_info.gen.info.modename, "Trident");
fb_info.gen.info.changevar = NULL;
fb_info.gen.info.node = -1;
fb_info.gen.info.fbops = &tridentfb_ops;
fb_info.gen.info.disp = &disp;
fb_info.gen.info.switch_con = &fbgen_switch;
fb_info.gen.info.updatevar = &fbgen_update_var;
fb_info.gen.info.blank = &fbgen_blank;
fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
fb_info.gen.info.fontname[0] = '\0';
/* set palette */
for(i=0;i<16;i++) {
j = color_table[i];
palette[i].red = default_red[j];
palette[i].green = default_grn[j];
palette[i].blue = default_blu[j];
}
unprotect_all();
/* This should give a reasonable default video mode */
//define this until get a modular modedb.Temporary.
#if STANDALONE
#define fb_find_mode tr_find_mode
#endif
i = fb_find_mode(&default_var,&fb_info.gen.info,mode,NULL,0,NULL,depth);
/* Set to 1 to try accel on 9397DVD */
#define IMAGE_ACCEL 0
if (!noaccel
#if !IMAGE_ACCEL
&& is_blade()
#endif
)
default_var.accel_flags |= FB_ACCELF_TEXT;
trident_decode_var(&default_var, &fb_info.currentmode, &fb_info.gen);
fbgen_get_var(&disp.var, -1, &fb_info.gen.info);
default_var.activate |= FB_ACTIVATE_NOW;
fbgen_do_set_var(&default_var, 1, &fb_info.gen);
fbgen_set_disp(-1, &fb_info.gen);
fbgen_install_cmap(0, &fb_info.gen);
if (register_framebuffer(&fb_info.gen.info) < 0) {
printk("Could not register Trident framebuffer\n");
return -EINVAL;
}
printk(KERN_INFO "fb%d: %s frame buffer device %dx%d-%dbpp\n",
GET_FB_IDX(fb_info.gen.info.node), fb_info.gen.info.modename,default_var.xres,
default_var.yres,default_var.bits_per_pixel);
return 0;
}
void __exit tridentfb_exit(void)
{
unregister_framebuffer(&fb_info.gen.info);
iounmap((void *)(fb_info.io_virt));
iounmap((void *)fb_info.fbmem_virt);
}
/*
* Parse user speficied options (`video=tridentfb:')
* example:
* video=tridentfb:800x600,depth=16,noaccel
*/
int __init tridentfb_setup(char *options)
{
char * opt;
if (!options || !*options)
return 0;
printk("trident_setup : %s\n",options);
for(opt = strtok(options,",");opt;opt = strtok(NULL,",")){
if (!opt) continue;
printk("%s\n",opt);
if (!strcmp(opt,"noaccel"))
noaccel = 1;
else if (!strcmp(opt,"depth="))
depth = simple_strtoul(opt+6,NULL,0);
else if (!strcmp(opt,"center"))
center = 1;
else
mode = opt;
}
return 0;
}
#if 0
static int tridentfb_open(struct fb_info *fb,int user)
{
return 1;
}
static int tridentfb_release(struct fb_info *fb,int user)
{
return 0;
}
#endif
static struct fb_ops tridentfb_ops = {
#if 0
owner:THIS_MODULE,
fb_open:tridentfb_open,
fb_release:tridentfb_release,
#endif
fb_get_fix:fbgen_get_fix,
fb_get_var:fbgen_get_var,
fb_set_var:fbgen_set_var,
fb_get_cmap:fbgen_get_cmap,
fb_set_cmap:fbgen_set_cmap,
fb_pan_display:fbgen_pan_display,
};
module_init(tridentfb_init);
module_exit(tridentfb_exit);
MODULE_AUTHOR("Jani Monoses <ja...@as...>");
MODULE_LICENSE("GPL");
|
|
From: <cw...@so...> - 2001-11-27 05:30:44
|
> > Linus dreams of a network transparentancy. I also like that idea. So the > > two things he wants to see go away are mmap and ioctl functionality. In sorry to jump in. i missed this eariler i guess. How can removing something useful like mmap be good? in the name of network transparency perhaps, but it has many uses. I don't know of any other way this type of functionality could be implimented without taking a huge speed hit. (mmapedbuffer[offset] memory write versus read/write/seek wrapper) perhaps a better way of implimenting this can happen? surely removing mmap is not the way to go. I agree that network transparency is a good thing, but perhaps expect applications to check for an mmap failure, and then use read/write fallbacks as necessary. or, (new trend), a local dev fs that indicates devices that are mmap friendly or somethign equally insane. sorry for the rant, i may be completely wrong. chris |
|
From: Sottek, M. J <mat...@in...> - 2001-11-27 01:06:38
|
>Set the fb_fix fields for mmio and smem to zero. As for internally with
>the new api you don't need to use the screen_base field.
>Just ignore it.
After further review (correct me If I am wrong James) it seems that
screen base (a kernel virtual address to the framebuffer) is needed
for the fb_read and fb_write functions. It was suggested that
there isn't a way around this.
I have to differ. It seems that in order to make writing a fb driver
easy, sometimes the fb interface layer pretends it is a driver and
makes direct access to the device. This is another case where this
just isn't the right thing to do for everyone. You have to allow
for a driver to be created that does ALL the driver work itself.
I think the base set of fb interfaces should include:
fb_put: Put data from somewhere into the framebuffer. This is called
imageblit in the new API. This should have a parameter to tell you
to use copy_from_user() or memcpy()
fb_get: Get data from the framebuffer and put it in a provided pointer.
This should have a flag to tell you to use copy_to_user() or
memcpy()
fb_set: Set a region of the frambuffer with the value provided. This
is called fillrect(?) in the new api.
I have thought of a compromise that should be very easy for most
drivers to do, and will allow us to keep the driver private stuff
hidden.
void init_generic_ops(&my_fb_info,fb_base,fb_size,fb_pitch);
void destroy_generic_ops(&my_fb_info);
This stores the base,size,pitch information in a hidden data
structure that is used for all generic function implementations.
This structure could be static to the generic ops code or
could be passed around in some context structure, but shouldn't
be directly accessible by drivers.
Here is some example code:
/* fb_private.h */
struct fb_generic {
u8 *fb_base;
u32 size;
u32 pitch;
anything else?
}
struct fb_context {
struct fb_generic generic;
other stuff?
}
fb_context *fb_get_context(u32 node);
/* fb_private.c */
static struct fb_context[MAX_FRAMEBUFFERS];
fb_context *fb_get_context(u32 node) {
return &fb_context[node];
}
/* fb_generic.c */
#include <fb_private.h>
void init_generic_ops(struct fb_info *info,u8 *fb_base,
u32 size, u32 pitch) {
struct fb_context *context = fb_get_context(fb_info->node);
context->generic.fb_base = fb_base;
context->generic.fb_size = fb_size;
context->generic.fb_pitch = fb_pitch;
}
/* somewhere in fbmem.c */
...
Break down the read into an offset and size.
...
if(!fb->fb_read) {
struct fb_context *context = fb_get_context(info->node);
generic_fb_read(offset, size, &context->generic, COPY_TO_USER);
}
else {
fb->fb_read(offset, size, info->par, COPY_TO_USER);
}
The only thing a driver would have to do is leave the fb_put,fb_set,
fb_get == NULL and call init_generic_ops() whenever their framebuffer
changes size, pitch or location.
Then, once we have a context, we can hide anything in there that should
not be seen by the driver or the kernel (outside the fb interface)
or users.
-Matt
|
|
From: Sottek, M. J <mat...@in...> - 2001-11-26 16:57:49
|
>> With modedb it wouldn't be that much of a big step. >But then we need to keep the mode database in memory. I think that >belongs in userspace. I struggle with this too. On one hand no one wants to put tables in nonswappable kernel memory. On the other hand, if the tables are in user space, you loose the ability of the kernel to provide a "safe" mode setting interface. The only way to guarantee that no user can set an unsafe mode is to negotiate the mode between the driver and the display device at the kernel level and then prohibit any unsafe modes. This is why I advocate that each driver have it's own modes table, which can be built from a standard set, or from the drivers own needs. In this way the size of the table is minimized to just those that are being used by the driver. so NOT this: mode_t my_modes = standard_modes_table; but more like this: mode_t my_modes = filter_standard_modes(&some_criteria); and then the standard modes table is freed after init. __initdata takes care of that right? Of course, drivers needn't use the mode tables at all if they have some better way of coming up with the modes they will support without getting into the "too many permutations to test" scenario. In the driver I'm working on I have separated "mode" from "timings". mode == The framebuffer mode. depth,pitch,size this is the stuff that alters rendering. timings == Display setup. The display width, height, margins and offsets. Timings can be set independent of the mode without flushing out the rendering pipeline (physically or virtually speaking), no need to blank the screen or refresh the data in the framebuffer. Modes cannot be set without setting the timings too since it is likely that the new mode will require a different set of timings. Keeping these two separate makes the code clean, and keeps the tables smaller. i.e. (modes + timings) < (modes * timings) -Matt |
|
From: Geert U. <ge...@li...> - 2001-11-26 10:01:50
|
On Sat, 24 Nov 2001, James Simmons wrote:
> > > Yes. For example floating point support in the kernel. I'd like to know
> > > how you'll persuade driver to know that '640x480-YUV422@59.94i' should be
> > > NTSC 800x525 interlaced picture, and how you'll center picture on screen
> > > then? Where do you specify virtual xres and yres?
> > >
> > Your overthinking it. For one, as long as modes are in a consistent format,
> > it's easy for anyone to parse. And since people are already used to the
> > "640x480-16@70" style format, what's the big deal?
>
> With modedb it wouldn't be that much of a big step.
But then we need to keep the mode database in memory. I think that belongs in
userspace.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@li...
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
|
|
From: Petr V. <van...@vc...> - 2001-11-26 02:31:49
|
On Sat, Nov 24, 2001 at 10:29:36PM -0800, James Simmons wrote: > > As far as virtual xres and yres.. keep in mind this is a virtual filesystem.. > > if your driver or subsystem has additional needs, you can simply register a > > new entry to deal with virtual resolution.. If you want a place for virtual > > resolution.. something like: > > > > /dev/gfx/card0/frame0/resolution_virt > > > > should suffice just fine. (Name pending). > > Okay I see people got confussed over the ASCII thing. Yes Linus wants > ioctls to go away. There have been huge ioctl clashes in the past. Plus > Linus dreams of a network transparentancy. I also like that idea. So the > two things he wants to see go away are mmap and ioctl functionality. In > its place you create a file to represent the functionality of the device > and that you can read and write data to so its behavior changes. This data > can be binary or ASCII. It just has to be passed in via read and write. Do not forget that current API is atomic, with doing it in multiple steps you can get nasty surprises (as resolution and resolution_virt depends one on another, either changing one changes also another one, or some modes are not accessible without first modifying resolution_virt), besides not being atomic... And AFAIK Al Viro (main ioctl killer) does not require that every current fb_*_info field should have its own file. From his posts I understand that he is completely satisfied with just some text-based extensible API, so ( echo "mode=1024x768-16@60,outputfmt=NTSC,vxres=2048,xoffset=141" >&0 read a echo $a ) <> /dev/fb0/control' would be enough for him... As there is already couple of comma separated list parsers in the kernel (mount options, kernel cmdline), I think that it is preferred format - in simplest form you write one line in, and get one line back... Best regards, Petr Vandrovec van...@vc... |
|
From: Michel <mic...@ii...> - 2001-11-25 12:20:35
|
On Fri, 2001-11-23 at 21:20, Carl Perry wrote: > video=3Dvesafb:800x600 > video=3Dvesafb:800x600-24@60 > video=3Dvesafb:800x600-16@60 vesafb doesn't work like that, see linux/Documentation/fb/vesafb.txt. --=20 Earthling Michel D=E4nzer (MrCooper)/ Debian GNU/Linux (powerpc) developer XFree86 and DRI project member / CS student, Free Software enthusiast |
|
From: James S. <jsi...@tr...> - 2001-11-25 06:29:50
|
> > Yes. For example floating point support in the kernel. I'd like to know > > how you'll persuade driver to know that '640x480-YUV422@59.94i' should be > > NTSC 800x525 interlaced picture, and how you'll center picture on screen > > then? Where do you specify virtual xres and yres? > > > Your overthinking it. For one, as long as modes are in a consistent format, > it's easy for anyone to parse. And since people are already used to the > "640x480-16@70" style format, what's the big deal? With modedb it wouldn't be that much of a big step. > As far as virtual xres and yres.. keep in mind this is a virtual filesystem.. > if your driver or subsystem has additional needs, you can simply register a > new entry to deal with virtual resolution.. If you want a place for virtual > resolution.. something like: > > /dev/gfx/card0/frame0/resolution_virt > > should suffice just fine. (Name pending). Okay I see people got confussed over the ASCII thing. Yes Linus wants ioctls to go away. There have been huge ioctl clashes in the past. Plus Linus dreams of a network transparentancy. I also like that idea. So the two things he wants to see go away are mmap and ioctl functionality. In its place you create a file to represent the functionality of the device and that you can read and write data to so its behavior changes. This data can be binary or ASCII. It just has to be passed in via read and write. |