aboutsummaryrefslogtreecommitdiffstats
path: root/arch/avr32/mach-at32ap
diff options
context:
space:
mode:
authorHaavard Skinnemoen <hskinnemoen@atmel.com>2007-03-21 13:08:49 -0400
committerHaavard Skinnemoen <hskinnemoen@atmel.com>2007-05-15 08:13:27 -0400
commitd0a2b7af27f6d01a443f3af8252fa0b955bf1913 (patch)
tree2240f60b5e4f5cd4abec83812048962b4b959b88 /arch/avr32/mach-at32ap
parent78c129b949bdee21dd996ac5f5cfc655cd5bd42e (diff)
[AVR32] Implement platform hooks for atmel_lcdfb driver
This modifies and extends the existing lcdc platform code to support the new atmel_lcdfb driver. The ATSTK1000 board code is set up to use the on-board Samsung LTV350QV LCD panel. Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Diffstat (limited to 'arch/avr32/mach-at32ap')
-rw-r--r--arch/avr32/mach-at32ap/at32ap7000.c77
1 files changed, 60 insertions, 17 deletions
diff --git a/arch/avr32/mach-at32ap/at32ap7000.c b/arch/avr32/mach-at32ap/at32ap7000.c
index 56db45b99a0f..1d2bf347a1d6 100644
--- a/arch/avr32/mach-at32ap/at32ap7000.c
+++ b/arch/avr32/mach-at32ap/at32ap7000.c
@@ -6,6 +6,7 @@
6 * published by the Free Software Foundation. 6 * published by the Free Software Foundation.
7 */ 7 */
8#include <linux/clk.h> 8#include <linux/clk.h>
9#include <linux/fb.h>
9#include <linux/init.h> 10#include <linux/init.h>
10#include <linux/platform_device.h> 11#include <linux/platform_device.h>
11#include <linux/spi/spi.h> 12#include <linux/spi/spi.h>
@@ -17,6 +18,8 @@
17#include <asm/arch/portmux.h> 18#include <asm/arch/portmux.h>
18#include <asm/arch/sm.h> 19#include <asm/arch/sm.h>
19 20
21#include <video/atmel_lcdc.h>
22
20#include "clock.h" 23#include "clock.h"
21#include "hmatrix.h" 24#include "hmatrix.h"
22#include "pio.h" 25#include "pio.h"
@@ -881,20 +884,26 @@ at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n)
881/* -------------------------------------------------------------------- 884/* --------------------------------------------------------------------
882 * LCDC 885 * LCDC
883 * -------------------------------------------------------------------- */ 886 * -------------------------------------------------------------------- */
884static struct lcdc_platform_data lcdc0_data; 887static struct atmel_lcdfb_info atmel_lcdfb0_data;
885static struct resource lcdc0_resource[] = { 888static struct resource atmel_lcdfb0_resource[] = {
886 { 889 {
887 .start = 0xff000000, 890 .start = 0xff000000,
888 .end = 0xff000fff, 891 .end = 0xff000fff,
889 .flags = IORESOURCE_MEM, 892 .flags = IORESOURCE_MEM,
890 }, 893 },
891 IRQ(1), 894 IRQ(1),
895 {
896 /* Placeholder for pre-allocated fb memory */
897 .start = 0x00000000,
898 .end = 0x00000000,
899 .flags = 0,
900 },
892}; 901};
893DEFINE_DEV_DATA(lcdc, 0); 902DEFINE_DEV_DATA(atmel_lcdfb, 0);
894DEV_CLK(hclk, lcdc0, hsb, 7); 903DEV_CLK(hck1, atmel_lcdfb0, hsb, 7);
895static struct clk lcdc0_pixclk = { 904static struct clk atmel_lcdfb0_pixclk = {
896 .name = "pixclk", 905 .name = "lcdc_clk",
897 .dev = &lcdc0_device.dev, 906 .dev = &atmel_lcdfb0_device.dev,
898 .mode = genclk_mode, 907 .mode = genclk_mode,
899 .get_rate = genclk_get_rate, 908 .get_rate = genclk_get_rate,
900 .set_rate = genclk_set_rate, 909 .set_rate = genclk_set_rate,
@@ -903,13 +912,34 @@ static struct clk lcdc0_pixclk = {
903}; 912};
904 913
905struct platform_device *__init 914struct platform_device *__init
906at32_add_device_lcdc(unsigned int id, struct lcdc_platform_data *data) 915at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data,
916 unsigned long fbmem_start, unsigned long fbmem_len)
907{ 917{
908 struct platform_device *pdev; 918 struct platform_device *pdev;
919 struct atmel_lcdfb_info *info;
920 struct fb_monspecs *monspecs;
921 struct fb_videomode *modedb;
922 unsigned int modedb_size;
923
924 /*
925 * Do a deep copy of the fb data, monspecs and modedb. Make
926 * sure all allocations are done before setting up the
927 * portmux.
928 */
929 monspecs = kmemdup(data->default_monspecs,
930 sizeof(struct fb_monspecs), GFP_KERNEL);
931 if (!monspecs)
932 return NULL;
933
934 modedb_size = sizeof(struct fb_videomode) * monspecs->modedb_len;
935 modedb = kmemdup(monspecs->modedb, modedb_size, GFP_KERNEL);
936 if (!modedb)
937 goto err_dup_modedb;
938 monspecs->modedb = modedb;
909 939
910 switch (id) { 940 switch (id) {
911 case 0: 941 case 0:
912 pdev = &lcdc0_device; 942 pdev = &atmel_lcdfb0_device;
913 select_peripheral(PC(19), PERIPH_A, 0); /* CC */ 943 select_peripheral(PC(19), PERIPH_A, 0); /* CC */
914 select_peripheral(PC(20), PERIPH_A, 0); /* HSYNC */ 944 select_peripheral(PC(20), PERIPH_A, 0); /* HSYNC */
915 select_peripheral(PC(21), PERIPH_A, 0); /* PCLK */ 945 select_peripheral(PC(21), PERIPH_A, 0); /* PCLK */
@@ -942,19 +972,32 @@ at32_add_device_lcdc(unsigned int id, struct lcdc_platform_data *data)
942 select_peripheral(PD(16), PERIPH_A, 0); /* DATA22 */ 972 select_peripheral(PD(16), PERIPH_A, 0); /* DATA22 */
943 select_peripheral(PD(17), PERIPH_A, 0); /* DATA23 */ 973 select_peripheral(PD(17), PERIPH_A, 0); /* DATA23 */
944 974
945 clk_set_parent(&lcdc0_pixclk, &pll0); 975 clk_set_parent(&atmel_lcdfb0_pixclk, &pll0);
946 clk_set_rate(&lcdc0_pixclk, clk_get_rate(&pll0)); 976 clk_set_rate(&atmel_lcdfb0_pixclk, clk_get_rate(&pll0));
947 break; 977 break;
948 978
949 default: 979 default:
950 return NULL; 980 goto err_invalid_id;
951 } 981 }
952 982
953 memcpy(pdev->dev.platform_data, data, 983 if (fbmem_len) {
954 sizeof(struct lcdc_platform_data)); 984 pdev->resource[2].start = fbmem_start;
985 pdev->resource[2].end = fbmem_start + fbmem_len - 1;
986 pdev->resource[2].flags = IORESOURCE_MEM;
987 }
988
989 info = pdev->dev.platform_data;
990 memcpy(info, data, sizeof(struct atmel_lcdfb_info));
991 info->default_monspecs = monspecs;
955 992
956 platform_device_register(pdev); 993 platform_device_register(pdev);
957 return pdev; 994 return pdev;
995
996err_invalid_id:
997 kfree(modedb);
998err_dup_modedb:
999 kfree(monspecs);
1000 return NULL;
958} 1001}
959 1002
960/* -------------------------------------------------------------------- 1003/* --------------------------------------------------------------------
@@ -1037,8 +1080,8 @@ struct clk *at32_clock_list[] = {
1037 &macb1_pclk, 1080 &macb1_pclk,
1038 &atmel_spi0_spi_clk, 1081 &atmel_spi0_spi_clk,
1039 &atmel_spi1_spi_clk, 1082 &atmel_spi1_spi_clk,
1040 &lcdc0_hclk, 1083 &atmel_lcdfb0_hck1,
1041 &lcdc0_pixclk, 1084 &atmel_lcdfb0_pixclk,
1042 &gclk0, 1085 &gclk0,
1043 &gclk1, 1086 &gclk1,
1044 &gclk2, 1087 &gclk2,
@@ -1077,7 +1120,7 @@ void __init at32_clock_init(void)
1077 genclk_init_parent(&gclk2); 1120 genclk_init_parent(&gclk2);
1078 genclk_init_parent(&gclk3); 1121 genclk_init_parent(&gclk3);
1079 genclk_init_parent(&gclk4); 1122 genclk_init_parent(&gclk4);
1080 genclk_init_parent(&lcdc0_pixclk); 1123 genclk_init_parent(&atmel_lcdfb0_pixclk);
1081 1124
1082 /* 1125 /*
1083 * Turn on all clocks that have at least one user already, and 1126 * Turn on all clocks that have at least one user already, and