linux-console.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Stefan Biereigel <stefan@biereigel.de>
To: "linux-kernel@vger.kernel org" <linux-kernel@vger.kernel.org>
Cc: linux-fbdev@vger.kernel.org, linux-console@vger.kernel.org,
	brian <brian.fonfara@gmx.de>
Subject: console / fbdev: fbcon support for bits_per_pixel = 1?
Date: Sat, 14 Jun 2014 11:55:43 +0200	[thread overview]
Message-ID: <539C1C1F.5060904@biereigel.de> (raw)

CC: linux-console, linux-fbdev

Hello Kernel Developers,
for a university assignment we are developing a frame buffer driver for a monochrome
display. We succeeded so far in making a simple "RAM frame buffer" module, which is needed
as the basis (we don't have read access to the RAM in the LCD).
We are using the system-default fb_ops (fb_sys_{read,write},
sys_{fillrect,copyarea,imageblit), and all is well when we use bits_per_pixel = 8. When we
map a console to the RAM frame buffer (con2fbmap 1 1), do strg-alt-F1, type some
characters there, we can then 'cat /dev/fb1' and plot the ram contents in Matlab
(reshaping the data to be our display geometry first), where our typed characters and the
console appear.

If we however change bits_per_pixel to 1, and divide line_length by 8 (as it should
represent the line length in bytes), this suddenly stops working: echo and cat to fb1 work
as intended: We change our Matlab-Script to interpret every byte as 8 pixels, bytes
written into /dev/fb1 can be read out correctly. If we however map the console to fb1, no
console output can be seen in RAM - it is (seemingly) filled with garbage.

We're using fbcon as the console driver, and the first frame buffer for me is intelfb. I
see, that the bitblitting-calls for every typed character are depth 1 and have correct
geometry, but the whole bitblitting-builtin seems not to work for bits_per_pixel = 1, i
tried it with a simple test image after the initialisation...

Is this behavior intended or are we triggering a bug here (that no one noticed, because
who in the world uses monochrome framebuffers these days..). I can't see any comments that
monochrome consoles should not work with 1 bit per pixel. See the code below if you spot
some errors (ignore some missing error handling and mediocre style for now, please).

Thank you for any help and input.
Best regards,
Stefan Biereigel

8<--- testfb.c

#include <linux/init.h>
#include <linux/module.h>

#include <linux/fb.h>
#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/errno.h>
#include <linux/platform_device.h>

#define DISPLAY_WIDTH	240
#define DISPLAY_HEIGHT	64
#define FB_MEM_SIZE 	(DISPLAY_WIDTH * DISPLAY_HEIGHT)/8

static struct platform_device *testfb_device;

static struct fb_ops fbops = {
	.owner		= THIS_MODULE,
	.fb_fillrect	= sys_fillrect,
	.fb_copyarea	= sys_copyarea,
	.fb_imageblit	= sys_imageblit,
	.fb_read	= fb_sys_read,
	.fb_write	= fb_sys_write,
	.fb_sync	= NULL,
};

static int __init testfb_probe (struct platform_device *pdev) {
	void *fb_mem = NULL;
	struct fb_info *fbinfo = NULL;

	fb_mem = kzalloc(FB_MEM_SIZE, GFP_KERNEL);

	if (!fb_mem) {
		pr_err("testfb: memory allocation for framebuffer failed\n");
		return(-ENOMEM);
	}
	else
		pr_debug("testfb: allocated framebuffer memory successfully\n");

	fbinfo = framebuffer_alloc(0, &pdev->dev);

	if (!fbinfo) {
		pr_err("testfb: framebuffer_alloc() failed\n");
		kfree(fb_mem);
		return(-1);
	}
	else
		pr_debug("testfb: framebuffer_alloc was successful\n");

	fbinfo->fix.smem_start = (unsigned long) fb_mem;
	fbinfo->screen_base = (char __iomem *) fb_mem;
	fbinfo->fix.smem_len = FB_MEM_SIZE;
	fbinfo->fbops = &fbops;

	fbinfo->node			= 0;				/* ?int */
	fbinfo->device			= &pdev->dev;
	fbinfo->flags			= FBINFO_DEFAULT;		/*  */
	fbinfo->var.xres		= DISPLAY_WIDTH;		/* visible resolution */
	fbinfo->var.yres		= DISPLAY_HEIGHT;		/* visible resolution */
	fbinfo->var.xres_virtual	= DISPLAY_WIDTH;		/* virtual resolution */
	fbinfo->var.yres_virtual	= DISPLAY_HEIGHT;		/* virtual resolution */
	fbinfo->var.bits_per_pixel	= 1;				/* bits per pixel */
	fbinfo->var.activate		= FB_ACTIVATE_NOW;		/* set values immediately (or vbl) */
	fbinfo->var.sync		= 0;				/* ?see FB_SYNC_* */
	fbinfo->var.vmode		= FB_VMODE_NONINTERLACED;	/* non interlaced, see FB_VMODE_* */
	fbinfo->var.left_margin 	= 0;
	fbinfo->var.right_margin 	= 0;
	fbinfo->var.upper_margin 	= 0;
	fbinfo->var.lower_margin 	= 0;
	fbinfo->var.red.offset 		= 0;
	fbinfo->var.red.length 		= fbinfo->var.bits_per_pixel;
	fbinfo->var.green 		= fbinfo->var.red;
	fbinfo->var.blue  		= fbinfo->var.red;
	fbinfo->var.grayscale		= 1;
	strcpy(fbinfo->fix.id, "testfb");				/* identifier, 16 byte */
	fbinfo->fix.type		= FB_TYPE_PACKED_PIXELS;	/* pack pixels to avoid overhead */
	fbinfo->fix.visual		= FB_VISUAL_MONO10;		/* Monochr. 1=Black 0=White */
	fbinfo->fix.line_length		= DISPLAY_WIDTH/8;		/* length of a line in bytes */
	fbinfo->fix.accel		= FB_ACCEL_NONE;		/* no hardware accelerator */
	fbinfo->fix.xpanstep 		= 0;
	fbinfo->fix.ypanstep		= 0;
	fbinfo->fix.ywrapstep 		= 0;

	if (register_framebuffer(fbinfo) < 0) {
		pr_err("testfb: registering framebuffer failed\n");
		kfree((void *) fbinfo->fix.smem_start);
		framebuffer_release(fbinfo);
		return(-1);
	}
	else
		pr_debug("testfb: registered framebuffer\n");

	platform_set_drvdata(pdev, fbinfo);

	return 0;
}

static int testfb_remove(struct platform_device *pdev) {
	struct fb_info *fbinfo = NULL;

	fbinfo = platform_get_drvdata(pdev);

	if (!fbinfo) {
		pr_err("testfb: unable to get fbinfo from pdev\n");
		return(-1);
	}

	if (unregister_framebuffer(fbinfo) < 0)
		pr_err("testfb: unregistering framebuffer failed\n");
	else
		pr_debug("testfb: unregistered framebuffer\n");

	kfree((void *) fbinfo->fix.smem_start);

	framebuffer_release(fbinfo);

	return 0;
}

static struct platform_driver testfb_driver = {
	.probe = testfb_probe,
	.remove = testfb_remove,
	.driver = {
		.name = "testfb",
	},
};

static int __init testfb_init(void)
{
	int ret;

	ret = platform_driver_register(&testfb_driver);
	if (!ret) {
		testfb_device = platform_device_register_simple("testfb", 0,
								NULL, 0);

		if (IS_ERR(testfb_device)) {
			platform_driver_unregister(&testfb_driver);
			ret = PTR_ERR(testfb_device);
		} else {
			pr_info("testfb: platform_device registered\n");
		}

	}

	pr_info("testfb: module loaded\n");
	
	return 0;
}

static void __exit testfb_exit(void)
{
	platform_device_unregister(testfb_device);
	platform_driver_unregister(&testfb_driver);

	pr_info("testfb: module unloaded\n");
}

module_init(testfb_init);
module_exit(testfb_exit);

MODULE_LICENSE("GPL v2");
MODULE_ALIAS("testfb");
MODULE_AUTHOR("Brian Fonfara");
MODULE_DESCRIPTION("Ein Modul zum Test der Linux Framebuffer-Programmierung");
MODULE_DESCRIPTION("version 0.1");

             reply	other threads:[~2014-06-14  9:55 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-14  9:55 Stefan Biereigel [this message]
2014-06-14 12:35 ` console / fbdev: fbcon support for bits_per_pixel = 1? Bruno Prémont
2014-06-15  7:47   ` Stefan Biereigel
2014-06-15  8:57   ` Geert Uytterhoeven

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=539C1C1F.5060904@biereigel.de \
    --to=stefan@biereigel.de \
    --cc=brian.fonfara@gmx.de \
    --cc=linux-console@vger.kernel.org \
    --cc=linux-fbdev@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).