aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2013-03-15 18:08:09 -0400
committerArnd Bergmann <arnd@arndb.de>2013-03-15 18:08:09 -0400
commit1414fbdcb28f7161b9ab6225a68a45f97fece3c1 (patch)
tree180db81b7435edf0d8286dbb77694852c2a1a3a3
parentb7442b6c8b081f1a7433ad34697ce6f8e77f4904 (diff)
parentbbd44f6bd9d1aa735b180b29b5719d63a8e87b55 (diff)
Merge tag 'at91-driversLCD' of git://github.com/at91linux/linux-at91 into next/drivers
From Nicolas Ferre <nicolas.ferre@atmel.com>: Some Atmel framebuffer driver enhancements with modification of configuration data in ARM/AT91 and AVR32/AP7 trees. A merge of these modifications seems easier through arm-soc git tree nowadays. * tag 'at91-driversLCD' of git://github.com/at91linux/linux-at91: ARM: at91/avr32/atmel_lcdfb: add platform device-id table atmel_lcdfb: move lcdcon2 register access to compute_hozval ARM: at91/avr32/atmel_lcdfb: add bus-clock entry ARM: at91: fix LCD-wiring mode atmel_lcdfb: fix 16-bpp modes on older SOCs Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-rw-r--r--arch/arm/mach-at91/at91sam9261.c2
-rw-r--r--arch/arm/mach-at91/at91sam9261_devices.c6
-rw-r--r--arch/arm/mach-at91/at91sam9263.c1
-rw-r--r--arch/arm/mach-at91/at91sam9263_devices.c2
-rw-r--r--arch/arm/mach-at91/at91sam9g45.c2
-rw-r--r--arch/arm/mach-at91/at91sam9g45_devices.c6
-rw-r--r--arch/arm/mach-at91/at91sam9rl.c1
-rw-r--r--arch/arm/mach-at91/at91sam9rl_devices.c2
-rw-r--r--arch/avr32/mach-at32ap/at32ap700x.c6
-rw-r--r--drivers/video/atmel_lcdfb.c130
-rw-r--r--include/video/atmel_lcdc.h4
11 files changed, 126 insertions, 36 deletions
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index 2998a08afc2d..0204f4cc9ebf 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -169,6 +169,8 @@ static struct clk *periph_clocks[] __initdata = {
169}; 169};
170 170
171static struct clk_lookup periph_clocks_lookups[] = { 171static struct clk_lookup periph_clocks_lookups[] = {
172 CLKDEV_CON_DEV_ID("hclk", "at91sam9261-lcdfb.0", &hck1),
173 CLKDEV_CON_DEV_ID("hclk", "at91sam9g10-lcdfb.0", &hck1),
172 CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), 174 CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk),
173 CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), 175 CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),
174 CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), 176 CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk),
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
index 92e0f861084a..629ea5fc95cf 100644
--- a/arch/arm/mach-at91/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -488,7 +488,6 @@ static struct resource lcdc_resources[] = {
488}; 488};
489 489
490static struct platform_device at91_lcdc_device = { 490static struct platform_device at91_lcdc_device = {
491 .name = "atmel_lcdfb",
492 .id = 0, 491 .id = 0,
493 .dev = { 492 .dev = {
494 .dma_mask = &lcdc_dmamask, 493 .dma_mask = &lcdc_dmamask,
@@ -505,6 +504,11 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
505 return; 504 return;
506 } 505 }
507 506
507 if (cpu_is_at91sam9g10())
508 at91_lcdc_device.name = "at91sam9g10-lcdfb";
509 else
510 at91_lcdc_device.name = "at91sam9261-lcdfb";
511
508#if defined(CONFIG_FB_ATMEL_STN) 512#if defined(CONFIG_FB_ATMEL_STN)
509 at91_set_A_periph(AT91_PIN_PB0, 0); /* LCDVSYNC */ 513 at91_set_A_periph(AT91_PIN_PB0, 0); /* LCDVSYNC */
510 at91_set_A_periph(AT91_PIN_PB1, 0); /* LCDHSYNC */ 514 at91_set_A_periph(AT91_PIN_PB1, 0); /* LCDHSYNC */
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index b9fc60d1b33a..2282fd7ad3e3 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -190,6 +190,7 @@ static struct clk_lookup periph_clocks_lookups[] = {
190 CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.1", &ssc1_clk), 190 CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.1", &ssc1_clk),
191 CLKDEV_CON_DEV_ID("pclk", "fff98000.ssc", &ssc0_clk), 191 CLKDEV_CON_DEV_ID("pclk", "fff98000.ssc", &ssc0_clk),
192 CLKDEV_CON_DEV_ID("pclk", "fff9c000.ssc", &ssc1_clk), 192 CLKDEV_CON_DEV_ID("pclk", "fff9c000.ssc", &ssc1_clk),
193 CLKDEV_CON_DEV_ID("hclk", "at91sam9263-lcdfb.0", &lcdc_clk),
193 CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.0", &mmc0_clk), 194 CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.0", &mmc0_clk),
194 CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.1", &mmc1_clk), 195 CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.1", &mmc1_clk),
195 CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), 196 CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk),
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index ed666f5cb01d..858c8aac2daf 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -848,7 +848,7 @@ static struct resource lcdc_resources[] = {
848}; 848};
849 849
850static struct platform_device at91_lcdc_device = { 850static struct platform_device at91_lcdc_device = {
851 .name = "atmel_lcdfb", 851 .name = "at91sam9263-lcdfb",
852 .id = 0, 852 .id = 0,
853 .dev = { 853 .dev = {
854 .dma_mask = &lcdc_dmamask, 854 .dma_mask = &lcdc_dmamask,
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
index d3addee43d8d..c68960d82247 100644
--- a/arch/arm/mach-at91/at91sam9g45.c
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -228,6 +228,8 @@ static struct clk_lookup periph_clocks_lookups[] = {
228 CLKDEV_CON_ID("hclk", &macb_clk), 228 CLKDEV_CON_ID("hclk", &macb_clk),
229 /* One additional fake clock for ohci */ 229 /* One additional fake clock for ohci */
230 CLKDEV_CON_ID("ohci_clk", &uhphs_clk), 230 CLKDEV_CON_ID("ohci_clk", &uhphs_clk),
231 CLKDEV_CON_DEV_ID("hclk", "at91sam9g45-lcdfb.0", &lcdc_clk),
232 CLKDEV_CON_DEV_ID("hclk", "at91sam9g45es-lcdfb.0", &lcdc_clk),
231 CLKDEV_CON_DEV_ID("ehci_clk", "atmel-ehci", &uhphs_clk), 233 CLKDEV_CON_DEV_ID("ehci_clk", "atmel-ehci", &uhphs_clk),
232 CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk), 234 CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk),
233 CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk), 235 CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk),
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
index 827c9f2a70fb..fe626d431b69 100644
--- a/arch/arm/mach-at91/at91sam9g45_devices.c
+++ b/arch/arm/mach-at91/at91sam9g45_devices.c
@@ -981,7 +981,6 @@ static struct resource lcdc_resources[] = {
981}; 981};
982 982
983static struct platform_device at91_lcdc_device = { 983static struct platform_device at91_lcdc_device = {
984 .name = "atmel_lcdfb",
985 .id = 0, 984 .id = 0,
986 .dev = { 985 .dev = {
987 .dma_mask = &lcdc_dmamask, 986 .dma_mask = &lcdc_dmamask,
@@ -997,6 +996,11 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
997 if (!data) 996 if (!data)
998 return; 997 return;
999 998
999 if (cpu_is_at91sam9g45es())
1000 at91_lcdc_device.name = "at91sam9g45es-lcdfb";
1001 else
1002 at91_lcdc_device.name = "at91sam9g45-lcdfb";
1003
1000 at91_set_A_periph(AT91_PIN_PE0, 0); /* LCDDPWR */ 1004 at91_set_A_periph(AT91_PIN_PE0, 0); /* LCDDPWR */
1001 1005
1002 at91_set_A_periph(AT91_PIN_PE2, 0); /* LCDCC */ 1006 at91_set_A_periph(AT91_PIN_PE2, 0); /* LCDCC */
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c
index eb98704db2d9..3de3e04d0f81 100644
--- a/arch/arm/mach-at91/at91sam9rl.c
+++ b/arch/arm/mach-at91/at91sam9rl.c
@@ -179,6 +179,7 @@ static struct clk *periph_clocks[] __initdata = {
179}; 179};
180 180
181static struct clk_lookup periph_clocks_lookups[] = { 181static struct clk_lookup periph_clocks_lookups[] = {
182 CLKDEV_CON_DEV_ID("hclk", "at91sam9rl-lcdfb.0", &lcdc_clk),
182 CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk), 183 CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk),
183 CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk), 184 CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk),
184 CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), 185 CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk),
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
index ddf223ff35c4..352468f265a9 100644
--- a/arch/arm/mach-at91/at91sam9rl_devices.c
+++ b/arch/arm/mach-at91/at91sam9rl_devices.c
@@ -514,7 +514,7 @@ static struct resource lcdc_resources[] = {
514}; 514};
515 515
516static struct platform_device at91_lcdc_device = { 516static struct platform_device at91_lcdc_device = {
517 .name = "atmel_lcdfb", 517 .name = "at91sam9rl-lcdfb",
518 .id = 0, 518 .id = 0,
519 .dev = { 519 .dev = {
520 .dma_mask = &lcdc_dmamask, 520 .dma_mask = &lcdc_dmamask,
diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c
index b323d8d3185b..7c2f6685bf43 100644
--- a/arch/avr32/mach-at32ap/at32ap700x.c
+++ b/arch/avr32/mach-at32ap/at32ap700x.c
@@ -1453,7 +1453,7 @@ static struct resource atmel_lcdfb0_resource[] = {
1453 }, 1453 },
1454}; 1454};
1455DEFINE_DEV_DATA(atmel_lcdfb, 0); 1455DEFINE_DEV_DATA(atmel_lcdfb, 0);
1456DEV_CLK(hck1, atmel_lcdfb0, hsb, 7); 1456DEV_CLK(hclk, atmel_lcdfb0, hsb, 7);
1457static struct clk atmel_lcdfb0_pixclk = { 1457static struct clk atmel_lcdfb0_pixclk = {
1458 .name = "lcdc_clk", 1458 .name = "lcdc_clk",
1459 .dev = &atmel_lcdfb0_device.dev, 1459 .dev = &atmel_lcdfb0_device.dev,
@@ -1530,6 +1530,8 @@ at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data,
1530 memcpy(info, data, sizeof(struct atmel_lcdfb_info)); 1530 memcpy(info, data, sizeof(struct atmel_lcdfb_info));
1531 info->default_monspecs = monspecs; 1531 info->default_monspecs = monspecs;
1532 1532
1533 pdev->name = "at32ap-lcdfb";
1534
1533 platform_device_register(pdev); 1535 platform_device_register(pdev);
1534 return pdev; 1536 return pdev;
1535 1537
@@ -2246,7 +2248,7 @@ static __initdata struct clk *init_clocks[] = {
2246 &atmel_twi0_pclk, 2248 &atmel_twi0_pclk,
2247 &atmel_mci0_pclk, 2249 &atmel_mci0_pclk,
2248#if defined(CONFIG_CPU_AT32AP7000) || defined(CONFIG_CPU_AT32AP7002) 2250#if defined(CONFIG_CPU_AT32AP7000) || defined(CONFIG_CPU_AT32AP7002)
2249 &atmel_lcdfb0_hck1, 2251 &atmel_lcdfb0_hclk,
2250 &atmel_lcdfb0_pixclk, 2252 &atmel_lcdfb0_pixclk,
2251#endif 2253#endif
2252 &ssc0_pclk, 2254 &ssc0_pclk,
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 12cf5f31ee8f..c1a2914447e1 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -34,6 +34,77 @@
34#define ATMEL_LCDC_DMA_BURST_LEN 8 /* words */ 34#define ATMEL_LCDC_DMA_BURST_LEN 8 /* words */
35#define ATMEL_LCDC_FIFO_SIZE 512 /* words */ 35#define ATMEL_LCDC_FIFO_SIZE 512 /* words */
36 36
37struct atmel_lcdfb_config {
38 bool have_alt_pixclock;
39 bool have_hozval;
40 bool have_intensity_bit;
41};
42
43static struct atmel_lcdfb_config at91sam9261_config = {
44 .have_hozval = true,
45 .have_intensity_bit = true,
46};
47
48static struct atmel_lcdfb_config at91sam9263_config = {
49 .have_intensity_bit = true,
50};
51
52static struct atmel_lcdfb_config at91sam9g10_config = {
53 .have_hozval = true,
54};
55
56static struct atmel_lcdfb_config at91sam9g45_config = {
57 .have_alt_pixclock = true,
58};
59
60static struct atmel_lcdfb_config at91sam9g45es_config = {
61};
62
63static struct atmel_lcdfb_config at91sam9rl_config = {
64 .have_intensity_bit = true,
65};
66
67static struct atmel_lcdfb_config at32ap_config = {
68 .have_hozval = true,
69};
70
71static const struct platform_device_id atmel_lcdfb_devtypes[] = {
72 {
73 .name = "at91sam9261-lcdfb",
74 .driver_data = (unsigned long)&at91sam9261_config,
75 }, {
76 .name = "at91sam9263-lcdfb",
77 .driver_data = (unsigned long)&at91sam9263_config,
78 }, {
79 .name = "at91sam9g10-lcdfb",
80 .driver_data = (unsigned long)&at91sam9g10_config,
81 }, {
82 .name = "at91sam9g45-lcdfb",
83 .driver_data = (unsigned long)&at91sam9g45_config,
84 }, {
85 .name = "at91sam9g45es-lcdfb",
86 .driver_data = (unsigned long)&at91sam9g45es_config,
87 }, {
88 .name = "at91sam9rl-lcdfb",
89 .driver_data = (unsigned long)&at91sam9rl_config,
90 }, {
91 .name = "at32ap-lcdfb",
92 .driver_data = (unsigned long)&at32ap_config,
93 }, {
94 /* terminator */
95 }
96};
97
98static struct atmel_lcdfb_config *
99atmel_lcdfb_get_config(struct platform_device *pdev)
100{
101 unsigned long data;
102
103 data = platform_get_device_id(pdev)->driver_data;
104
105 return (struct atmel_lcdfb_config *)data;
106}
107
37#if defined(CONFIG_ARCH_AT91) 108#if defined(CONFIG_ARCH_AT91)
38#define ATMEL_LCDFB_FBINFO_DEFAULT (FBINFO_DEFAULT \ 109#define ATMEL_LCDFB_FBINFO_DEFAULT (FBINFO_DEFAULT \
39 | FBINFO_PARTIAL_PAN_OK \ 110 | FBINFO_PARTIAL_PAN_OK \
@@ -193,14 +264,16 @@ static struct fb_fix_screeninfo atmel_lcdfb_fix __initdata = {
193 .accel = FB_ACCEL_NONE, 264 .accel = FB_ACCEL_NONE,
194}; 265};
195 266
196static unsigned long compute_hozval(unsigned long xres, unsigned long lcdcon2) 267static unsigned long compute_hozval(struct atmel_lcdfb_info *sinfo,
268 unsigned long xres)
197{ 269{
270 unsigned long lcdcon2;
198 unsigned long value; 271 unsigned long value;
199 272
200 if (!(cpu_is_at91sam9261() || cpu_is_at91sam9g10() 273 if (!sinfo->config->have_hozval)
201 || cpu_is_at32ap7000()))
202 return xres; 274 return xres;
203 275
276 lcdcon2 = lcdc_readl(sinfo, ATMEL_LCDC_LCDCON2);
204 value = xres; 277 value = xres;
205 if ((lcdcon2 & ATMEL_LCDC_DISTYPE) != ATMEL_LCDC_DISTYPE_TFT) { 278 if ((lcdcon2 & ATMEL_LCDC_DISTYPE) != ATMEL_LCDC_DISTYPE_TFT) {
206 /* STN display */ 279 /* STN display */
@@ -422,17 +495,22 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var,
422 = var->bits_per_pixel; 495 = var->bits_per_pixel;
423 break; 496 break;
424 case 16: 497 case 16:
498 /* Older SOCs use IBGR:555 rather than BGR:565. */
499 if (sinfo->config->have_intensity_bit)
500 var->green.length = 5;
501 else
502 var->green.length = 6;
503
425 if (sinfo->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB) { 504 if (sinfo->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB) {
426 /* RGB:565 mode */ 505 /* RGB:5X5 mode */
427 var->red.offset = 11; 506 var->red.offset = var->green.length + 5;
428 var->blue.offset = 0; 507 var->blue.offset = 0;
429 } else { 508 } else {
430 /* BGR:565 mode */ 509 /* BGR:5X5 mode */
431 var->red.offset = 0; 510 var->red.offset = 0;
432 var->blue.offset = 11; 511 var->blue.offset = var->green.length + 5;
433 } 512 }
434 var->green.offset = 5; 513 var->green.offset = 5;
435 var->green.length = 6;
436 var->red.length = var->blue.length = 5; 514 var->red.length = var->blue.length = 5;
437 break; 515 break;
438 case 32: 516 case 32:
@@ -526,7 +604,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info)
526 /* Now, the LCDC core... */ 604 /* Now, the LCDC core... */
527 605
528 /* Set pixel clock */ 606 /* Set pixel clock */
529 if (cpu_is_at91sam9g45() && !cpu_is_at91sam9g45es()) 607 if (sinfo->config->have_alt_pixclock)
530 pix_factor = 1; 608 pix_factor = 1;
531 609
532 clk_value_khz = clk_get_rate(sinfo->lcdc_clk) / 1000; 610 clk_value_khz = clk_get_rate(sinfo->lcdc_clk) / 1000;
@@ -586,8 +664,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info)
586 lcdc_writel(sinfo, ATMEL_LCDC_TIM2, value); 664 lcdc_writel(sinfo, ATMEL_LCDC_TIM2, value);
587 665
588 /* Horizontal value (aka line size) */ 666 /* Horizontal value (aka line size) */
589 hozval_linesz = compute_hozval(info->var.xres, 667 hozval_linesz = compute_hozval(sinfo, info->var.xres);
590 lcdc_readl(sinfo, ATMEL_LCDC_LCDCON2));
591 668
592 /* Display size */ 669 /* Display size */
593 value = (hozval_linesz - 1) << ATMEL_LCDC_HOZVAL_OFFSET; 670 value = (hozval_linesz - 1) << ATMEL_LCDC_HOZVAL_OFFSET;
@@ -679,8 +756,7 @@ static int atmel_lcdfb_setcolreg(unsigned int regno, unsigned int red,
679 756
680 case FB_VISUAL_PSEUDOCOLOR: 757 case FB_VISUAL_PSEUDOCOLOR:
681 if (regno < 256) { 758 if (regno < 256) {
682 if (cpu_is_at91sam9261() || cpu_is_at91sam9263() 759 if (sinfo->config->have_intensity_bit) {
683 || cpu_is_at91sam9rl()) {
684 /* old style I+BGR:555 */ 760 /* old style I+BGR:555 */
685 val = ((red >> 11) & 0x001f); 761 val = ((red >> 11) & 0x001f);
686 val |= ((green >> 6) & 0x03e0); 762 val |= ((green >> 6) & 0x03e0);
@@ -817,15 +893,13 @@ static int __init atmel_lcdfb_init_fbinfo(struct atmel_lcdfb_info *sinfo)
817 893
818static void atmel_lcdfb_start_clock(struct atmel_lcdfb_info *sinfo) 894static void atmel_lcdfb_start_clock(struct atmel_lcdfb_info *sinfo)
819{ 895{
820 if (sinfo->bus_clk) 896 clk_enable(sinfo->bus_clk);
821 clk_enable(sinfo->bus_clk);
822 clk_enable(sinfo->lcdc_clk); 897 clk_enable(sinfo->lcdc_clk);
823} 898}
824 899
825static void atmel_lcdfb_stop_clock(struct atmel_lcdfb_info *sinfo) 900static void atmel_lcdfb_stop_clock(struct atmel_lcdfb_info *sinfo)
826{ 901{
827 if (sinfo->bus_clk) 902 clk_disable(sinfo->bus_clk);
828 clk_disable(sinfo->bus_clk);
829 clk_disable(sinfo->lcdc_clk); 903 clk_disable(sinfo->lcdc_clk);
830} 904}
831 905
@@ -870,6 +944,9 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
870 } 944 }
871 sinfo->info = info; 945 sinfo->info = info;
872 sinfo->pdev = pdev; 946 sinfo->pdev = pdev;
947 sinfo->config = atmel_lcdfb_get_config(pdev);
948 if (!sinfo->config)
949 goto free_info;
873 950
874 strcpy(info->fix.id, sinfo->pdev->name); 951 strcpy(info->fix.id, sinfo->pdev->name);
875 info->flags = ATMEL_LCDFB_FBINFO_DEFAULT; 952 info->flags = ATMEL_LCDFB_FBINFO_DEFAULT;
@@ -880,13 +957,10 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
880 info->fix = atmel_lcdfb_fix; 957 info->fix = atmel_lcdfb_fix;
881 958
882 /* Enable LCDC Clocks */ 959 /* Enable LCDC Clocks */
883 if (cpu_is_at91sam9261() || cpu_is_at91sam9g10() 960 sinfo->bus_clk = clk_get(dev, "hclk");
884 || cpu_is_at32ap7000()) { 961 if (IS_ERR(sinfo->bus_clk)) {
885 sinfo->bus_clk = clk_get(dev, "hck1"); 962 ret = PTR_ERR(sinfo->bus_clk);
886 if (IS_ERR(sinfo->bus_clk)) { 963 goto free_info;
887 ret = PTR_ERR(sinfo->bus_clk);
888 goto free_info;
889 }
890 } 964 }
891 sinfo->lcdc_clk = clk_get(dev, "lcdc_clk"); 965 sinfo->lcdc_clk = clk_get(dev, "lcdc_clk");
892 if (IS_ERR(sinfo->lcdc_clk)) { 966 if (IS_ERR(sinfo->lcdc_clk)) {
@@ -1047,8 +1121,7 @@ stop_clk:
1047 atmel_lcdfb_stop_clock(sinfo); 1121 atmel_lcdfb_stop_clock(sinfo);
1048 clk_put(sinfo->lcdc_clk); 1122 clk_put(sinfo->lcdc_clk);
1049put_bus_clk: 1123put_bus_clk:
1050 if (sinfo->bus_clk) 1124 clk_put(sinfo->bus_clk);
1051 clk_put(sinfo->bus_clk);
1052free_info: 1125free_info:
1053 framebuffer_release(info); 1126 framebuffer_release(info);
1054out: 1127out:
@@ -1073,8 +1146,7 @@ static int __exit atmel_lcdfb_remove(struct platform_device *pdev)
1073 unregister_framebuffer(info); 1146 unregister_framebuffer(info);
1074 atmel_lcdfb_stop_clock(sinfo); 1147 atmel_lcdfb_stop_clock(sinfo);
1075 clk_put(sinfo->lcdc_clk); 1148 clk_put(sinfo->lcdc_clk);
1076 if (sinfo->bus_clk) 1149 clk_put(sinfo->bus_clk);
1077 clk_put(sinfo->bus_clk);
1078 fb_dealloc_cmap(&info->cmap); 1150 fb_dealloc_cmap(&info->cmap);
1079 free_irq(sinfo->irq_base, info); 1151 free_irq(sinfo->irq_base, info);
1080 iounmap(sinfo->mmio); 1152 iounmap(sinfo->mmio);
@@ -1143,7 +1215,7 @@ static struct platform_driver atmel_lcdfb_driver = {
1143 .remove = __exit_p(atmel_lcdfb_remove), 1215 .remove = __exit_p(atmel_lcdfb_remove),
1144 .suspend = atmel_lcdfb_suspend, 1216 .suspend = atmel_lcdfb_suspend,
1145 .resume = atmel_lcdfb_resume, 1217 .resume = atmel_lcdfb_resume,
1146 1218 .id_table = atmel_lcdfb_devtypes,
1147 .driver = { 1219 .driver = {
1148 .name = "atmel_lcdfb", 1220 .name = "atmel_lcdfb",
1149 .owner = THIS_MODULE, 1221 .owner = THIS_MODULE,
diff --git a/include/video/atmel_lcdc.h b/include/video/atmel_lcdc.h
index 28447f1594fa..0f5a2fc69af9 100644
--- a/include/video/atmel_lcdc.h
+++ b/include/video/atmel_lcdc.h
@@ -30,8 +30,8 @@
30 */ 30 */
31#define ATMEL_LCDC_WIRING_BGR 0 31#define ATMEL_LCDC_WIRING_BGR 0
32#define ATMEL_LCDC_WIRING_RGB 1 32#define ATMEL_LCDC_WIRING_RGB 1
33#define ATMEL_LCDC_WIRING_RGB555 2
34 33
34struct atmel_lcdfb_config;
35 35
36 /* LCD Controller info data structure, stored in device platform_data */ 36 /* LCD Controller info data structure, stored in device platform_data */
37struct atmel_lcdfb_info { 37struct atmel_lcdfb_info {
@@ -62,6 +62,8 @@ struct atmel_lcdfb_info {
62 void (*atmel_lcdfb_power_control)(int on); 62 void (*atmel_lcdfb_power_control)(int on);
63 struct fb_monspecs *default_monspecs; 63 struct fb_monspecs *default_monspecs;
64 u32 pseudo_palette[16]; 64 u32 pseudo_palette[16];
65
66 struct atmel_lcdfb_config *config;
65}; 67};
66 68
67#define ATMEL_LCDC_DMABADDR1 0x00 69#define ATMEL_LCDC_DMABADDR1 0x00