forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 cde9070d9970eef1f7ec2360586c802a16230ad8
kernel/drivers/video/fbdev/pvr2fb.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * drivers/video/pvr2fb.c
34 *
....@@ -139,7 +140,7 @@
139140 unsigned char is_doublescan; /* Are scanlines output twice? (doublescan) */
140141 unsigned char is_lowres; /* Is horizontal pixel-doubling enabled? */
141142
142
- unsigned long mmio_base; /* MMIO base */
143
+ void __iomem *mmio_base; /* MMIO base */
143144 u32 palette[16];
144145 } *currentpar;
145146
....@@ -192,39 +193,6 @@
192193 static unsigned int shdma = PVR2_CASCADE_CHAN;
193194 static unsigned int pvr2dma = ONCHIP_NR_DMA_CHANNELS;
194195 #endif
195
-
196
-static int pvr2fb_setcolreg(unsigned int regno, unsigned int red, unsigned int green, unsigned int blue,
197
- unsigned int transp, struct fb_info *info);
198
-static int pvr2fb_blank(int blank, struct fb_info *info);
199
-static unsigned long get_line_length(int xres_virtual, int bpp);
200
-static void set_color_bitfields(struct fb_var_screeninfo *var);
201
-static int pvr2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info);
202
-static int pvr2fb_set_par(struct fb_info *info);
203
-static void pvr2_update_display(struct fb_info *info);
204
-static void pvr2_init_display(struct fb_info *info);
205
-static void pvr2_do_blank(void);
206
-static irqreturn_t pvr2fb_interrupt(int irq, void *dev_id);
207
-static int pvr2_init_cable(void);
208
-static int pvr2_get_param(const struct pvr2_params *p, const char *s,
209
- int val, int size);
210
-#ifdef CONFIG_PVR2_DMA
211
-static ssize_t pvr2fb_write(struct fb_info *info, const char *buf,
212
- size_t count, loff_t *ppos);
213
-#endif
214
-
215
-static struct fb_ops pvr2fb_ops = {
216
- .owner = THIS_MODULE,
217
- .fb_setcolreg = pvr2fb_setcolreg,
218
- .fb_blank = pvr2fb_blank,
219
- .fb_check_var = pvr2fb_check_var,
220
- .fb_set_par = pvr2fb_set_par,
221
-#ifdef CONFIG_PVR2_DMA
222
- .fb_write = pvr2fb_write,
223
-#endif
224
- .fb_fillrect = cfb_fillrect,
225
- .fb_copyarea = cfb_copyarea,
226
- .fb_imageblit = cfb_imageblit,
227
-};
228196
229197 static struct fb_videomode pvr2_modedb[] = {
230198 /*
....@@ -353,6 +321,36 @@
353321 return 0;
354322 }
355323
324
+/*
325
+ * Determine the cable type and initialize the cable output format. Don't do
326
+ * anything if the cable type has been overidden (via "cable:XX").
327
+ */
328
+
329
+#define PCTRA ((void __iomem *)0xff80002c)
330
+#define PDTRA ((void __iomem *)0xff800030)
331
+#define VOUTC ((void __iomem *)0xa0702c00)
332
+
333
+static int pvr2_init_cable(void)
334
+{
335
+ if (cable_type < 0) {
336
+ fb_writel((fb_readl(PCTRA) & 0xfff0ffff) | 0x000a0000,
337
+ PCTRA);
338
+ cable_type = (fb_readw(PDTRA) >> 8) & 3;
339
+ }
340
+
341
+ /* Now select the output format (either composite or other) */
342
+ /* XXX: Save the previous val first, as this reg is also AICA
343
+ related */
344
+ if (cable_type == CT_COMPOSITE)
345
+ fb_writel(3 << 8, VOUTC);
346
+ else if (cable_type == CT_RGB)
347
+ fb_writel(1 << 9, VOUTC);
348
+ else
349
+ fb_writel(0, VOUTC);
350
+
351
+ return cable_type;
352
+}
353
+
356354 static int pvr2fb_set_par(struct fb_info *info)
357355 {
358356 struct pvr2fb_par *par = (struct pvr2fb_par *)info->par;
....@@ -460,13 +458,11 @@
460458 set_color_bitfields(var);
461459
462460 if (var->vmode & FB_VMODE_YWRAP) {
463
- if (var->xoffset || var->yoffset < 0 ||
464
- var->yoffset >= var->yres_virtual) {
461
+ if (var->xoffset || var->yoffset >= var->yres_virtual) {
465462 var->xoffset = var->yoffset = 0;
466463 } else {
467464 if (var->xoffset > var->xres_virtual - var->xres ||
468
- var->yoffset > var->yres_virtual - var->yres ||
469
- var->xoffset < 0 || var->yoffset < 0)
465
+ var->yoffset > var->yres_virtual - var->yres)
470466 var->xoffset = var->yoffset = 0;
471467 }
472468 } else {
....@@ -622,7 +618,7 @@
622618 is_blanked = do_blank > 0 ? do_blank : 0;
623619 }
624620
625
-static irqreturn_t pvr2fb_interrupt(int irq, void *dev_id)
621
+static irqreturn_t __maybe_unused pvr2fb_interrupt(int irq, void *dev_id)
626622 {
627623 struct fb_info *info = dev_id;
628624
....@@ -641,36 +637,6 @@
641637 return IRQ_HANDLED;
642638 }
643639
644
-/*
645
- * Determine the cable type and initialize the cable output format. Don't do
646
- * anything if the cable type has been overidden (via "cable:XX").
647
- */
648
-
649
-#define PCTRA 0xff80002c
650
-#define PDTRA 0xff800030
651
-#define VOUTC 0xa0702c00
652
-
653
-static int pvr2_init_cable(void)
654
-{
655
- if (cable_type < 0) {
656
- fb_writel((fb_readl(PCTRA) & 0xfff0ffff) | 0x000a0000,
657
- PCTRA);
658
- cable_type = (fb_readw(PDTRA) >> 8) & 3;
659
- }
660
-
661
- /* Now select the output format (either composite or other) */
662
- /* XXX: Save the previous val first, as this reg is also AICA
663
- related */
664
- if (cable_type == CT_COMPOSITE)
665
- fb_writel(3 << 8, VOUTC);
666
- else if (cable_type == CT_RGB)
667
- fb_writel(1 << 9, VOUTC);
668
- else
669
- fb_writel(0, VOUTC);
670
-
671
- return cable_type;
672
-}
673
-
674640 #ifdef CONFIG_PVR2_DMA
675641 static ssize_t pvr2fb_write(struct fb_info *info, const char *buf,
676642 size_t count, loff_t *ppos)
....@@ -686,10 +652,24 @@
686652 if (!pages)
687653 return -ENOMEM;
688654
689
- ret = get_user_pages_fast((unsigned long)buf, nr_pages, true, pages);
655
+ ret = pin_user_pages_fast((unsigned long)buf, nr_pages, FOLL_WRITE, pages);
690656 if (ret < nr_pages) {
691
- nr_pages = ret;
692
- ret = -EINVAL;
657
+ if (ret < 0) {
658
+ /*
659
+ * Clamp the unsigned nr_pages to zero so that the
660
+ * error handling works. And leave ret at whatever
661
+ * -errno value was returned from GUP.
662
+ */
663
+ nr_pages = 0;
664
+ } else {
665
+ nr_pages = ret;
666
+ /*
667
+ * Use -EINVAL to represent a mildly desperate guess at
668
+ * why we got fewer pages (maybe even zero pages) than
669
+ * requested.
670
+ */
671
+ ret = -EINVAL;
672
+ }
693673 goto out_unmap;
694674 }
695675
....@@ -732,14 +712,52 @@
732712 ret = count;
733713
734714 out_unmap:
735
- for (i = 0; i < nr_pages; i++)
736
- put_page(pages[i]);
737
-
715
+ unpin_user_pages(pages, nr_pages);
738716 kfree(pages);
739717
740718 return ret;
741719 }
742720 #endif /* CONFIG_PVR2_DMA */
721
+
722
+static const struct fb_ops pvr2fb_ops = {
723
+ .owner = THIS_MODULE,
724
+ .fb_setcolreg = pvr2fb_setcolreg,
725
+ .fb_blank = pvr2fb_blank,
726
+ .fb_check_var = pvr2fb_check_var,
727
+ .fb_set_par = pvr2fb_set_par,
728
+#ifdef CONFIG_PVR2_DMA
729
+ .fb_write = pvr2fb_write,
730
+#endif
731
+ .fb_fillrect = cfb_fillrect,
732
+ .fb_copyarea = cfb_copyarea,
733
+ .fb_imageblit = cfb_imageblit,
734
+};
735
+
736
+#ifndef MODULE
737
+static int pvr2_get_param_val(const struct pvr2_params *p, const char *s,
738
+ int size)
739
+{
740
+ int i;
741
+
742
+ for (i = 0; i < size; i++) {
743
+ if (!strncasecmp(p[i].name, s, strlen(s)))
744
+ return p[i].val;
745
+ }
746
+ return -1;
747
+}
748
+#endif
749
+
750
+static char *pvr2_get_param_name(const struct pvr2_params *p, int val,
751
+ int size)
752
+{
753
+ int i;
754
+
755
+ for (i = 0; i < size; i++) {
756
+ if (p[i].val == val)
757
+ return p[i].name;
758
+ }
759
+ return NULL;
760
+}
743761
744762 /**
745763 * pvr2fb_common_init
....@@ -759,12 +777,12 @@
759777 * in for flexibility anyways. Who knows, maybe someone has tv-out on a
760778 * PCI-based version of these things ;-)
761779 */
762
-static int pvr2fb_common_init(void)
780
+static int __maybe_unused pvr2fb_common_init(void)
763781 {
764782 struct pvr2fb_par *par = currentpar;
765783 unsigned long modememused, rev;
766784
767
- fb_info->screen_base = ioremap_nocache(pvr2_fix.smem_start,
785
+ fb_info->screen_base = ioremap(pvr2_fix.smem_start,
768786 pvr2_fix.smem_len);
769787
770788 if (!fb_info->screen_base) {
....@@ -772,8 +790,8 @@
772790 goto out_err;
773791 }
774792
775
- par->mmio_base = (unsigned long)ioremap_nocache(pvr2_fix.mmio_start,
776
- pvr2_fix.mmio_len);
793
+ par->mmio_base = ioremap(pvr2_fix.mmio_start,
794
+ pvr2_fix.mmio_len);
777795 if (!par->mmio_base) {
778796 printk(KERN_ERR "pvr2fb: Failed to remap mmio space\n");
779797 goto out_err;
....@@ -821,8 +839,8 @@
821839 fb_info->var.xres, fb_info->var.yres,
822840 fb_info->var.bits_per_pixel,
823841 get_line_length(fb_info->var.xres, fb_info->var.bits_per_pixel),
824
- (char *)pvr2_get_param(cables, NULL, cable_type, 3),
825
- (char *)pvr2_get_param(outputs, NULL, video_output, 3));
842
+ pvr2_get_param_name(cables, cable_type, 3),
843
+ pvr2_get_param_name(outputs, video_output, 3));
826844
827845 #ifdef CONFIG_SH_STORE_QUEUES
828846 fb_notice(fb_info, "registering with SQ API\n");
....@@ -840,7 +858,7 @@
840858 if (fb_info->screen_base)
841859 iounmap(fb_info->screen_base);
842860 if (par->mmio_base)
843
- iounmap((void *)par->mmio_base);
861
+ iounmap(par->mmio_base);
844862
845863 return -ENXIO;
846864 }
....@@ -900,15 +918,15 @@
900918 return pvr2fb_common_init();
901919 }
902920
903
-static void __exit pvr2fb_dc_exit(void)
921
+static void pvr2fb_dc_exit(void)
904922 {
905923 if (fb_info->screen_base) {
906924 iounmap(fb_info->screen_base);
907925 fb_info->screen_base = NULL;
908926 }
909927 if (currentpar->mmio_base) {
910
- iounmap((void *)currentpar->mmio_base);
911
- currentpar->mmio_base = 0;
928
+ iounmap(currentpar->mmio_base);
929
+ currentpar->mmio_base = NULL;
912930 }
913931
914932 free_irq(HW_EVENT_VSYNC, fb_info);
....@@ -957,8 +975,8 @@
957975 fb_info->screen_base = NULL;
958976 }
959977 if (currentpar->mmio_base) {
960
- iounmap((void *)currentpar->mmio_base);
961
- currentpar->mmio_base = 0;
978
+ iounmap(currentpar->mmio_base);
979
+ currentpar->mmio_base = NULL;
962980 }
963981
964982 pci_release_regions(pdev);
....@@ -984,28 +1002,11 @@
9841002 return pci_register_driver(&pvr2fb_pci_driver);
9851003 }
9861004
987
-static void __exit pvr2fb_pci_exit(void)
1005
+static void pvr2fb_pci_exit(void)
9881006 {
9891007 pci_unregister_driver(&pvr2fb_pci_driver);
9901008 }
9911009 #endif /* CONFIG_PCI */
992
-
993
-static int pvr2_get_param(const struct pvr2_params *p, const char *s, int val,
994
- int size)
995
-{
996
- int i;
997
-
998
- for (i = 0 ; i < size ; i++ ) {
999
- if (s != NULL) {
1000
- if (!strncasecmp(p[i].name, s, strlen(s)))
1001
- return p[i].val;
1002
- } else {
1003
- if (p[i].val == val)
1004
- return (int)p[i].name;
1005
- }
1006
- }
1007
- return -1;
1008
-}
10091010
10101011 /*
10111012 * Parse command arguments. Supported arguments are:
....@@ -1048,9 +1049,9 @@
10481049 }
10491050
10501051 if (*cable_arg)
1051
- cable_type = pvr2_get_param(cables, cable_arg, 0, 3);
1052
+ cable_type = pvr2_get_param_val(cables, cable_arg, 3);
10521053 if (*output_arg)
1053
- video_output = pvr2_get_param(outputs, output_arg, 0, 3);
1054
+ video_output = pvr2_get_param_val(outputs, output_arg, 3);
10541055
10551056 return 0;
10561057 }
....@@ -1073,7 +1074,6 @@
10731074 static int __init pvr2fb_init(void)
10741075 {
10751076 int i, ret = -ENODEV;
1076
- int size;
10771077
10781078 #ifndef MODULE
10791079 char *option = NULL;
....@@ -1082,15 +1082,10 @@
10821082 return -ENODEV;
10831083 pvr2fb_setup(option);
10841084 #endif
1085
- size = sizeof(struct fb_info) + sizeof(struct pvr2fb_par) + 16 * sizeof(u32);
10861085
10871086 fb_info = framebuffer_alloc(sizeof(struct pvr2fb_par), NULL);
1088
-
1089
- if (!fb_info) {
1090
- printk(KERN_ERR "Failed to allocate memory for fb_info\n");
1087
+ if (!fb_info)
10911088 return -ENOMEM;
1092
- }
1093
-
10941089
10951090 currentpar = fb_info->par;
10961091