aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorMarkus Pargmann <mpa@pengutronix.de>2013-05-26 06:35:38 -0400
committerJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>2013-07-08 04:36:49 -0400
commit1b6c79361ba5ce30b40f0f7d6fc2421dc5fcbe0c (patch)
tree835b5dce4d4a29f1c1dc67c17f9d9658e648837c /drivers/video
parent19fd7441e9cc29b6c6d73c5469b3c93aa245fbb5 (diff)
video: imxfb: Add DT support
Add devicetree support for imx framebuffer driver. It uses the generic display bindings and helper functions. Signed-off-by: Markus Pargmann <mpa@pengutronix.de> Cc: Fabio Estevam <festevam@gmail.com> Cc: Mark Rutland <mark.rutland@arm.com> Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/Kconfig2
-rw-r--r--drivers/video/imxfb.c194
2 files changed, 161 insertions, 35 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 2c301f8441e9..4cf1e1dd5621 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -367,6 +367,8 @@ config FB_IMX
367 select FB_CFB_FILLRECT 367 select FB_CFB_FILLRECT
368 select FB_CFB_COPYAREA 368 select FB_CFB_COPYAREA
369 select FB_CFB_IMAGEBLIT 369 select FB_CFB_IMAGEBLIT
370 select FB_MODE_HELPERS
371 select VIDEOMODE_HELPERS
370 372
371config FB_CYBER2000 373config FB_CYBER2000
372 tristate "CyberPro 2000/2010/5000 support" 374 tristate "CyberPro 2000/2010/5000 support"
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 12af22ba4d92..38733ac2b698 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -31,6 +31,12 @@
31#include <linux/dma-mapping.h> 31#include <linux/dma-mapping.h>
32#include <linux/io.h> 32#include <linux/io.h>
33#include <linux/math64.h> 33#include <linux/math64.h>
34#include <linux/of.h>
35#include <linux/of_device.h>
36
37#include <video/of_display_timing.h>
38#include <video/of_videomode.h>
39#include <video/videomode.h>
34 40
35#include <linux/platform_data/video-imxfb.h> 41#include <linux/platform_data/video-imxfb.h>
36 42
@@ -112,10 +118,11 @@
112#define LCDISR_EOF (1<<1) 118#define LCDISR_EOF (1<<1)
113#define LCDISR_BOF (1<<0) 119#define LCDISR_BOF (1<<0)
114 120
121#define IMXFB_LSCR1_DEFAULT 0x00120300
122
115/* Used fb-mode. Can be set on kernel command line, therefore file-static. */ 123/* Used fb-mode. Can be set on kernel command line, therefore file-static. */
116static const char *fb_mode; 124static const char *fb_mode;
117 125
118
119/* 126/*
120 * These are the bitfields for each 127 * These are the bitfields for each
121 * display depth that we support. 128 * display depth that we support.
@@ -187,6 +194,19 @@ static struct platform_device_id imxfb_devtype[] = {
187}; 194};
188MODULE_DEVICE_TABLE(platform, imxfb_devtype); 195MODULE_DEVICE_TABLE(platform, imxfb_devtype);
189 196
197static struct of_device_id imxfb_of_dev_id[] = {
198 {
199 .compatible = "fsl,imx1-fb",
200 .data = &imxfb_devtype[IMX1_FB],
201 }, {
202 .compatible = "fsl,imx21-fb",
203 .data = &imxfb_devtype[IMX21_FB],
204 }, {
205 /* sentinel */
206 }
207};
208MODULE_DEVICE_TABLE(of, imxfb_of_dev_id);
209
190static inline int is_imx1_fb(struct imxfb_info *fbi) 210static inline int is_imx1_fb(struct imxfb_info *fbi)
191{ 211{
192 return fbi->devtype == IMX1_FB; 212 return fbi->devtype == IMX1_FB;
@@ -319,6 +339,9 @@ static const struct imx_fb_videomode *imxfb_find_mode(struct imxfb_info *fbi)
319 struct imx_fb_videomode *m; 339 struct imx_fb_videomode *m;
320 int i; 340 int i;
321 341
342 if (!fb_mode)
343 return &fbi->mode[0];
344
322 for (i = 0, m = &fbi->mode[0]; i < fbi->num_modes; i++, m++) { 345 for (i = 0, m = &fbi->mode[0]; i < fbi->num_modes; i++, m++) {
323 if (!strcmp(m->mode.name, fb_mode)) 346 if (!strcmp(m->mode.name, fb_mode))
324 return m; 347 return m;
@@ -474,6 +497,9 @@ static int imxfb_bl_update_status(struct backlight_device *bl)
474 struct imxfb_info *fbi = bl_get_data(bl); 497 struct imxfb_info *fbi = bl_get_data(bl);
475 int brightness = bl->props.brightness; 498 int brightness = bl->props.brightness;
476 499
500 if (!fbi->pwmr)
501 return 0;
502
477 if (bl->props.power != FB_BLANK_UNBLANK) 503 if (bl->props.power != FB_BLANK_UNBLANK)
478 brightness = 0; 504 brightness = 0;
479 if (bl->props.fb_blank != FB_BLANK_UNBLANK) 505 if (bl->props.fb_blank != FB_BLANK_UNBLANK)
@@ -684,10 +710,14 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
684 710
685 writel(fbi->pcr, fbi->regs + LCDC_PCR); 711 writel(fbi->pcr, fbi->regs + LCDC_PCR);
686#ifndef PWMR_BACKLIGHT_AVAILABLE 712#ifndef PWMR_BACKLIGHT_AVAILABLE
687 writel(fbi->pwmr, fbi->regs + LCDC_PWMR); 713 if (fbi->pwmr)
714 writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
688#endif 715#endif
689 writel(fbi->lscr1, fbi->regs + LCDC_LSCR1); 716 writel(fbi->lscr1, fbi->regs + LCDC_LSCR1);
690 writel(fbi->dmacr, fbi->regs + LCDC_DMACR); 717
718 /* dmacr = 0 is no valid value, as we need DMA control marks. */
719 if (fbi->dmacr)
720 writel(fbi->dmacr, fbi->regs + LCDC_DMACR);
691 721
692 return 0; 722 return 0;
693} 723}
@@ -723,13 +753,12 @@ static int imxfb_resume(struct platform_device *dev)
723#define imxfb_resume NULL 753#define imxfb_resume NULL
724#endif 754#endif
725 755
726static int __init imxfb_init_fbinfo(struct platform_device *pdev) 756static int imxfb_init_fbinfo(struct platform_device *pdev)
727{ 757{
728 struct imx_fb_platform_data *pdata = pdev->dev.platform_data; 758 struct imx_fb_platform_data *pdata = pdev->dev.platform_data;
729 struct fb_info *info = dev_get_drvdata(&pdev->dev); 759 struct fb_info *info = dev_get_drvdata(&pdev->dev);
730 struct imxfb_info *fbi = info->par; 760 struct imxfb_info *fbi = info->par;
731 struct imx_fb_videomode *m; 761 struct device_node *np;
732 int i;
733 762
734 pr_debug("%s\n",__func__); 763 pr_debug("%s\n",__func__);
735 764
@@ -760,41 +789,95 @@ static int __init imxfb_init_fbinfo(struct platform_device *pdev)
760 info->fbops = &imxfb_ops; 789 info->fbops = &imxfb_ops;
761 info->flags = FBINFO_FLAG_DEFAULT | 790 info->flags = FBINFO_FLAG_DEFAULT |
762 FBINFO_READS_FAST; 791 FBINFO_READS_FAST;
763 info->var.grayscale = pdata->cmap_greyscale; 792 if (pdata) {
764 fbi->cmap_inverse = pdata->cmap_inverse; 793 info->var.grayscale = pdata->cmap_greyscale;
765 fbi->cmap_static = pdata->cmap_static; 794 fbi->cmap_inverse = pdata->cmap_inverse;
766 fbi->lscr1 = pdata->lscr1; 795 fbi->cmap_static = pdata->cmap_static;
767 fbi->dmacr = pdata->dmacr; 796 fbi->lscr1 = pdata->lscr1;
768 fbi->pwmr = pdata->pwmr; 797 fbi->dmacr = pdata->dmacr;
769 fbi->lcd_power = pdata->lcd_power; 798 fbi->pwmr = pdata->pwmr;
770 fbi->backlight_power = pdata->backlight_power; 799 fbi->lcd_power = pdata->lcd_power;
771 800 fbi->backlight_power = pdata->backlight_power;
772 for (i = 0, m = &pdata->mode[0]; i < pdata->num_modes; i++, m++) 801 } else {
773 info->fix.smem_len = max_t(size_t, info->fix.smem_len, 802 np = pdev->dev.of_node;
774 m->mode.xres * m->mode.yres * m->bpp / 8); 803 info->var.grayscale = of_property_read_bool(np,
804 "cmap-greyscale");
805 fbi->cmap_inverse = of_property_read_bool(np, "cmap-inverse");
806 fbi->cmap_static = of_property_read_bool(np, "cmap-static");
807
808 fbi->lscr1 = IMXFB_LSCR1_DEFAULT;
809 of_property_read_u32(np, "fsl,lscr1", &fbi->lscr1);
810
811 of_property_read_u32(np, "fsl,dmacr", &fbi->dmacr);
812
813 /* These two function pointers could be used by some specific
814 * platforms. */
815 fbi->lcd_power = NULL;
816 fbi->backlight_power = NULL;
817 }
818
819 return 0;
820}
821
822static int imxfb_of_read_mode(struct device *dev, struct device_node *np,
823 struct imx_fb_videomode *imxfb_mode)
824{
825 int ret;
826 struct fb_videomode *of_mode = &imxfb_mode->mode;
827 u32 bpp;
828 u32 pcr;
829
830 ret = of_property_read_string(np, "model", &of_mode->name);
831 if (ret)
832 of_mode->name = NULL;
833
834 ret = of_get_fb_videomode(np, of_mode, OF_USE_NATIVE_MODE);
835 if (ret) {
836 dev_err(dev, "Failed to get videomode from DT\n");
837 return ret;
838 }
839
840 ret = of_property_read_u32(np, "bits-per-pixel", &bpp);
841 ret |= of_property_read_u32(np, "fsl,pcr", &pcr);
842
843 if (ret) {
844 dev_err(dev, "Failed to read bpp and pcr from DT\n");
845 return -EINVAL;
846 }
847
848 if (bpp < 1 || bpp > 255) {
849 dev_err(dev, "Bits per pixel have to be between 1 and 255\n");
850 return -EINVAL;
851 }
852
853 imxfb_mode->bpp = bpp;
854 imxfb_mode->pcr = pcr;
775 855
776 return 0; 856 return 0;
777} 857}
778 858
779static int __init imxfb_probe(struct platform_device *pdev) 859static int imxfb_probe(struct platform_device *pdev)
780{ 860{
781 struct imxfb_info *fbi; 861 struct imxfb_info *fbi;
782 struct fb_info *info; 862 struct fb_info *info;
783 struct imx_fb_platform_data *pdata; 863 struct imx_fb_platform_data *pdata;
784 struct resource *res; 864 struct resource *res;
865 struct imx_fb_videomode *m;
866 const struct of_device_id *of_id;
785 int ret, i; 867 int ret, i;
868 int bytes_per_pixel;
786 869
787 dev_info(&pdev->dev, "i.MX Framebuffer driver\n"); 870 dev_info(&pdev->dev, "i.MX Framebuffer driver\n");
788 871
872 of_id = of_match_device(imxfb_of_dev_id, &pdev->dev);
873 if (of_id)
874 pdev->id_entry = of_id->data;
875
789 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 876 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
790 if (!res) 877 if (!res)
791 return -ENODEV; 878 return -ENODEV;
792 879
793 pdata = pdev->dev.platform_data; 880 pdata = pdev->dev.platform_data;
794 if (!pdata) {
795 dev_err(&pdev->dev,"No platform_data available\n");
796 return -ENOMEM;
797 }
798 881
799 info = framebuffer_alloc(sizeof(struct imxfb_info), &pdev->dev); 882 info = framebuffer_alloc(sizeof(struct imxfb_info), &pdev->dev);
800 if (!info) 883 if (!info)
@@ -802,15 +885,55 @@ static int __init imxfb_probe(struct platform_device *pdev)
802 885
803 fbi = info->par; 886 fbi = info->par;
804 887
805 if (!fb_mode)
806 fb_mode = pdata->mode[0].mode.name;
807
808 platform_set_drvdata(pdev, info); 888 platform_set_drvdata(pdev, info);
809 889
810 ret = imxfb_init_fbinfo(pdev); 890 ret = imxfb_init_fbinfo(pdev);
811 if (ret < 0) 891 if (ret < 0)
812 goto failed_init; 892 goto failed_init;
813 893
894 if (pdata) {
895 if (!fb_mode)
896 fb_mode = pdata->mode[0].mode.name;
897
898 fbi->mode = pdata->mode;
899 fbi->num_modes = pdata->num_modes;
900 } else {
901 struct device_node *display_np;
902 fb_mode = NULL;
903
904 display_np = of_parse_phandle(pdev->dev.of_node, "display", 0);
905 if (!display_np) {
906 dev_err(&pdev->dev, "No display defined in devicetree\n");
907 ret = -EINVAL;
908 goto failed_of_parse;
909 }
910
911 /*
912 * imxfb does not support more modes, we choose only the native
913 * mode.
914 */
915 fbi->num_modes = 1;
916
917 fbi->mode = devm_kzalloc(&pdev->dev,
918 sizeof(struct imx_fb_videomode), GFP_KERNEL);
919 if (!fbi->mode) {
920 ret = -ENOMEM;
921 goto failed_of_parse;
922 }
923
924 ret = imxfb_of_read_mode(&pdev->dev, display_np, fbi->mode);
925 if (ret)
926 goto failed_of_parse;
927 }
928
929 /* Calculate maximum bytes used per pixel. In most cases this should
930 * be the same as m->bpp/8 */
931 m = &fbi->mode[0];
932 bytes_per_pixel = (m->bpp + 7) / 8;
933 for (i = 0; i < fbi->num_modes; i++, m++)
934 info->fix.smem_len = max_t(size_t, info->fix.smem_len,
935 m->mode.xres * m->mode.yres * bytes_per_pixel);
936
814 res = request_mem_region(res->start, resource_size(res), 937 res = request_mem_region(res->start, resource_size(res),
815 DRIVER_NAME); 938 DRIVER_NAME);
816 if (!res) { 939 if (!res) {
@@ -843,7 +966,8 @@ static int __init imxfb_probe(struct platform_device *pdev)
843 goto failed_ioremap; 966 goto failed_ioremap;
844 } 967 }
845 968
846 if (!pdata->fixed_screen_cpu) { 969 /* Seems not being used by anyone, so no support for oftree */
970 if (!pdata || !pdata->fixed_screen_cpu) {
847 fbi->map_size = PAGE_ALIGN(info->fix.smem_len); 971 fbi->map_size = PAGE_ALIGN(info->fix.smem_len);
848 fbi->map_cpu = dma_alloc_writecombine(&pdev->dev, 972 fbi->map_cpu = dma_alloc_writecombine(&pdev->dev,
849 fbi->map_size, &fbi->map_dma, GFP_KERNEL); 973 fbi->map_size, &fbi->map_dma, GFP_KERNEL);
@@ -868,18 +992,16 @@ static int __init imxfb_probe(struct platform_device *pdev)
868 info->fix.smem_start = fbi->screen_dma; 992 info->fix.smem_start = fbi->screen_dma;
869 } 993 }
870 994
871 if (pdata->init) { 995 if (pdata && pdata->init) {
872 ret = pdata->init(fbi->pdev); 996 ret = pdata->init(fbi->pdev);
873 if (ret) 997 if (ret)
874 goto failed_platform_init; 998 goto failed_platform_init;
875 } 999 }
876 1000
877 fbi->mode = pdata->mode;
878 fbi->num_modes = pdata->num_modes;
879 1001
880 INIT_LIST_HEAD(&info->modelist); 1002 INIT_LIST_HEAD(&info->modelist);
881 for (i = 0; i < pdata->num_modes; i++) 1003 for (i = 0; i < fbi->num_modes; i++)
882 fb_add_videomode(&pdata->mode[i].mode, &info->modelist); 1004 fb_add_videomode(&fbi->mode[i].mode, &info->modelist);
883 1005
884 /* 1006 /*
885 * This makes sure that our colour bitfield 1007 * This makes sure that our colour bitfield
@@ -909,10 +1031,10 @@ static int __init imxfb_probe(struct platform_device *pdev)
909failed_register: 1031failed_register:
910 fb_dealloc_cmap(&info->cmap); 1032 fb_dealloc_cmap(&info->cmap);
911failed_cmap: 1033failed_cmap:
912 if (pdata->exit) 1034 if (pdata && pdata->exit)
913 pdata->exit(fbi->pdev); 1035 pdata->exit(fbi->pdev);
914failed_platform_init: 1036failed_platform_init:
915 if (!pdata->fixed_screen_cpu) 1037 if (pdata && !pdata->fixed_screen_cpu)
916 dma_free_writecombine(&pdev->dev,fbi->map_size,fbi->map_cpu, 1038 dma_free_writecombine(&pdev->dev,fbi->map_size,fbi->map_cpu,
917 fbi->map_dma); 1039 fbi->map_dma);
918failed_map: 1040failed_map:
@@ -921,6 +1043,7 @@ failed_ioremap:
921failed_getclock: 1043failed_getclock:
922 release_mem_region(res->start, resource_size(res)); 1044 release_mem_region(res->start, resource_size(res));
923failed_req: 1045failed_req:
1046failed_of_parse:
924 kfree(info->pseudo_palette); 1047 kfree(info->pseudo_palette);
925failed_init: 1048failed_init:
926 framebuffer_release(info); 1049 framebuffer_release(info);
@@ -944,7 +1067,7 @@ static int imxfb_remove(struct platform_device *pdev)
944 unregister_framebuffer(info); 1067 unregister_framebuffer(info);
945 1068
946 pdata = pdev->dev.platform_data; 1069 pdata = pdev->dev.platform_data;
947 if (pdata->exit) 1070 if (pdata && pdata->exit)
948 pdata->exit(fbi->pdev); 1071 pdata->exit(fbi->pdev);
949 1072
950 fb_dealloc_cmap(&info->cmap); 1073 fb_dealloc_cmap(&info->cmap);
@@ -971,6 +1094,7 @@ static struct platform_driver imxfb_driver = {
971 .shutdown = imxfb_shutdown, 1094 .shutdown = imxfb_shutdown,
972 .driver = { 1095 .driver = {
973 .name = DRIVER_NAME, 1096 .name = DRIVER_NAME,
1097 .of_match_table = imxfb_of_dev_id,
974 }, 1098 },
975 .id_table = imxfb_devtype, 1099 .id_table = imxfb_devtype,
976}; 1100};