Running 2.6.36 kernels on SmartQ5

With the release of 2.6.35 kernel, basic support for SmartDevices SmartQ series MIDs has now been officially merged into mainline linux source trees ([1]).

‘Series’ here is certainly an overstatement, as there have only been two: SmartQ5 and SmartQ7. These S3C6410-based devices were released in China around last April and have been since exported abroad, sometimes with distributor branding. Stock firmwares, from the original ones to the few ‘updates’ that were made available later, were all based on a patched kernel from 2.6.24 series, presumably provided by Samsung in the BSP to HHTech, who is the real manufacturer of these devices.

Getting stuck on 2.6.24 most certainly is not something desirable for anyone familiar with progresses mainline kernels have been making in the meantime. Unfortunately, as has happened numerous times before and as will happen numerous times in future, the manufacturer, HHTech, showed no apparent interest in pushing support for their products into mainline and it was up to the user community to do their job. It took quite some months, but finally, mainly thanks to the hard work of Maurus Cuelenaere, you can now boot an up-to-date mainline linux kernel on SmartQs.

Well, not quite. Not unless you are using an up-to-date bootloader that can pass correct machine type ID numbers to the linux kernel. The bootloader in stock firmwares passes the ID number for smdk6410 machine type (1626) on both SmartQ5 and SmartQ7, whereas 2.6.35 and later kernels expect 2534 for SmartQ5 and 2479 for SmartQ7. This will cause the kernel to recognize the device as a different machine and either fail to load proper drivers or refuse to boot altogether.

The easiest but not quite right way to go around this, is to patch the kernel sources ([2]) so that the built kernel will think the ID number passed in by the bootloader is correct. The main issue with this solution is that you will have to build different kernels for SmartQ5 and SmartQ7, because mainline kernel will not have any idea which one it was being booted on. The more difficult but correct solution is to use an updated bootloader. However, such a bootloader will probably render kernels in stock firmwares unbootable.

Another problem with booting bleeding edge kernels seems to be caused by a bug in the framebuffer driver, which upon initialization will simply lock up the machine. A simple patch ([3]) apparently fixes this and voila, there is good old Tux.

As of this writing, a majority of SmartQ’s devices are already supported by mainline and seem to be working mostly. Media-related extensions in S3C6410, such as JPEG, Post Processor, Rotator, 2D, 3D, MFC etc. are not yet supported.


[2] machine type patch for linux 2.6.36-rc4:

diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 55590a4..ce9a496 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -2463,7 +2463,7 @@ acm500x   MACH_ACM500X  ACM500X   2475
km9260			MACH_KM9260		KM9260			2476
nideflexg1		MACH_NIDEFLEXG1		NIDEFLEXG1		2477
ctera_plug_io		MACH_CTERA_PLUG_IO	CTERA_PLUG_IO		2478
-smartq7			MACH_SMARTQ7		SMARTQ7			2479
+smartq7			MACH_SMARTQ7		SMARTQ7			1626
at91sam9g10ek2		MACH_AT91SAM9G10EK2	AT91SAM9G10EK2		2480
asusp527		MACH_ASUSP527		ASUSP527		2481
at91sam9g20mpm2		MACH_AT91SAM9G20MPM2	AT91SAM9G20MPM2		2482
@@ -2518,7 +2518,7 @@ dolby_cat1021  MACH_DOLBY_CAT1021 DOLBY_CAT1021  2530
mx28evk			MACH_MX28EVK		MX28EVK			2531
phoenix260		MACH_PHOENIX260		PHOENIX260		2532
-smartq5			MACH_SMARTQ5		SMARTQ5			2534
+smartq5			MACH_SMARTQ5		SMARTQ5			1626
all3078			MACH_ALL3078		ALL3078			2535
ctera_2bay_ds		MACH_CTERA_2BAY_DS	CTERA_2BAY_DS		2536
siogentoo3		MACH_SIOGENTOO3		SIOGENTOO3		2537

[3] framebuffer patch for linux 2.6.36-rc4

diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index f9aca9d..980ad04 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -1160,8 +1160,6 @@ static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no,

dev_dbg(sfb->dev, "probing window %d, variant %p\n", win_no, variant);

-	init_waitqueue_head(&sfb->vsync_info.wait);
palette_size = variant->palette_sz * 4;

fbinfo = framebuffer_alloc(sizeof(struct s3c_fb_win) +
@@ -1351,6 +1349,9 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
goto err_ioremap;
sfb->irq_no = res->start;
+	init_waitqueue_head(&sfb->vsync_info.wait);
ret = request_irq(sfb->irq_no, s3c_fb_irq,
0, "s3c_fb", sfb);
if (ret) {
This entry was posted in Linux, SmartQ and tagged , , , . Bookmark the permalink.