aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/ffb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/ffb.c')
-rw-r--r--drivers/video/ffb.c170
1 files changed, 79 insertions, 91 deletions
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 3f6c98fad437..4b520b573911 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -371,6 +371,8 @@ struct ffb_par {
371 unsigned long fbsize; 371 unsigned long fbsize;
372 372
373 int board_type; 373 int board_type;
374
375 u32 pseudo_palette[16];
374}; 376};
375 377
376static void FFBFifo(struct ffb_par *par, int n) 378static void FFBFifo(struct ffb_par *par, int n)
@@ -900,75 +902,67 @@ ffb_init_fix(struct fb_info *info)
900 info->fix.accel = FB_ACCEL_SUN_CREATOR; 902 info->fix.accel = FB_ACCEL_SUN_CREATOR;
901} 903}
902 904
903struct all_info { 905static int __devinit ffb_probe(struct of_device *op, const struct of_device_id *match)
904 struct fb_info info;
905 struct ffb_par par;
906 u32 pseudo_palette[16];
907};
908
909static int ffb_init_one(struct of_device *op)
910{ 906{
911 struct device_node *dp = op->node; 907 struct device_node *dp = op->node;
912 struct ffb_fbc __iomem *fbc; 908 struct ffb_fbc __iomem *fbc;
913 struct ffb_dac __iomem *dac; 909 struct ffb_dac __iomem *dac;
914 struct all_info *all; 910 struct fb_info *info;
915 int err; 911 struct ffb_par *par;
916 u32 dac_pnum, dac_rev, dac_mrev; 912 u32 dac_pnum, dac_rev, dac_mrev;
913 int err;
917 914
918 all = kzalloc(sizeof(*all), GFP_KERNEL); 915 info = framebuffer_alloc(sizeof(struct ffb_par), &op->dev);
919 if (!all)
920 return -ENOMEM;
921 916
922 spin_lock_init(&all->par.lock); 917 err = -ENOMEM;
923 all->par.fbc = of_ioremap(&op->resource[2], 0, 918 if (!info)
924 sizeof(struct ffb_fbc), "ffb fbc"); 919 goto out_err;
925 if (!all->par.fbc) {
926 kfree(all);
927 return -ENOMEM;
928 }
929 920
930 all->par.dac = of_ioremap(&op->resource[1], 0, 921 par = info->par;
931 sizeof(struct ffb_dac), "ffb dac"); 922
932 if (!all->par.dac) { 923 spin_lock_init(&par->lock);
933 of_iounmap(&op->resource[2], 924 par->fbc = of_ioremap(&op->resource[2], 0,
934 all->par.fbc, sizeof(struct ffb_fbc)); 925 sizeof(struct ffb_fbc), "ffb fbc");
935 kfree(all); 926 if (!par->fbc)
936 return -ENOMEM; 927 goto out_release_fb;
937 } 928
929 par->dac = of_ioremap(&op->resource[1], 0,
930 sizeof(struct ffb_dac), "ffb dac");
931 if (!par->dac)
932 goto out_unmap_fbc;
938 933
939 all->par.rop_cache = FFB_ROP_NEW; 934 par->rop_cache = FFB_ROP_NEW;
940 all->par.physbase = op->resource[0].start; 935 par->physbase = op->resource[0].start;
941 936
942 /* Don't mention copyarea, so SCROLL_REDRAW is always 937 /* Don't mention copyarea, so SCROLL_REDRAW is always
943 * used. It is the fastest on this chip. 938 * used. It is the fastest on this chip.
944 */ 939 */
945 all->info.flags = (FBINFO_DEFAULT | 940 info->flags = (FBINFO_DEFAULT |
946 /* FBINFO_HWACCEL_COPYAREA | */ 941 /* FBINFO_HWACCEL_COPYAREA | */
947 FBINFO_HWACCEL_FILLRECT | 942 FBINFO_HWACCEL_FILLRECT |
948 FBINFO_HWACCEL_IMAGEBLIT); 943 FBINFO_HWACCEL_IMAGEBLIT);
949 all->info.fbops = &ffb_ops; 944
950 all->info.screen_base = (char *) all->par.physbase + FFB_DFB24_POFF; 945 info->fbops = &ffb_ops;
951 all->info.par = &all->par; 946
952 all->info.pseudo_palette = all->pseudo_palette; 947 info->screen_base = (char *) par->physbase + FFB_DFB24_POFF;
953 948 info->pseudo_palette = par->pseudo_palette;
954 sbusfb_fill_var(&all->info.var, dp->node, 32); 949
955 all->par.fbsize = PAGE_ALIGN(all->info.var.xres * 950 sbusfb_fill_var(&info->var, dp->node, 32);
956 all->info.var.yres * 951 par->fbsize = PAGE_ALIGN(info->var.xres * info->var.yres * 4);
957 4); 952 ffb_fixup_var_rgb(&info->var);
958 ffb_fixup_var_rgb(&all->info.var); 953
959 954 info->var.accel_flags = FB_ACCELF_TEXT;
960 all->info.var.accel_flags = FB_ACCELF_TEXT;
961 955
962 if (!strcmp(dp->name, "SUNW,afb")) 956 if (!strcmp(dp->name, "SUNW,afb"))
963 all->par.flags |= FFB_FLAG_AFB; 957 par->flags |= FFB_FLAG_AFB;
964 958
965 all->par.board_type = of_getintprop_default(dp, "board_type", 0); 959 par->board_type = of_getintprop_default(dp, "board_type", 0);
966 960
967 fbc = all->par.fbc; 961 fbc = par->fbc;
968 if ((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0) 962 if ((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0)
969 upa_writel(FFB_UCSR_ALL_ERRORS, &fbc->ucsr); 963 upa_writel(FFB_UCSR_ALL_ERRORS, &fbc->ucsr);
970 964
971 dac = all->par.dac; 965 dac = par->dac;
972 upa_writel(FFB_DAC_DID, &dac->type); 966 upa_writel(FFB_DAC_DID, &dac->type);
973 dac_pnum = upa_readl(&dac->value); 967 dac_pnum = upa_readl(&dac->value);
974 dac_rev = (dac_pnum & FFB_DAC_DID_REV) >> FFB_DAC_DID_REV_SHIFT; 968 dac_rev = (dac_pnum & FFB_DAC_DID_REV) >> FFB_DAC_DID_REV_SHIFT;
@@ -985,76 +979,70 @@ static int ffb_init_one(struct of_device *op)
985 * cursor logic. We identify Pacifica 1 as not Pacifica 2, the 979 * cursor logic. We identify Pacifica 1 as not Pacifica 2, the
986 * latter having a part number value of 0x236e. 980 * latter having a part number value of 0x236e.
987 */ 981 */
988 if ((all->par.flags & FFB_FLAG_AFB) || dac_pnum == 0x236e) { 982 if ((par->flags & FFB_FLAG_AFB) || dac_pnum == 0x236e) {
989 all->par.flags &= ~FFB_FLAG_INVCURSOR; 983 par->flags &= ~FFB_FLAG_INVCURSOR;
990 } else { 984 } else {
991 if (dac_mrev < 3) 985 if (dac_mrev < 3)
992 all->par.flags |= FFB_FLAG_INVCURSOR; 986 par->flags |= FFB_FLAG_INVCURSOR;
993 } 987 }
994 988
995 ffb_switch_from_graph(&all->par); 989 ffb_switch_from_graph(par);
996 990
997 /* Unblank it just to be sure. When there are multiple 991 /* Unblank it just to be sure. When there are multiple
998 * FFB/AFB cards in the system, or it is not the OBP 992 * FFB/AFB cards in the system, or it is not the OBP
999 * chosen console, it will have video outputs off in 993 * chosen console, it will have video outputs off in
1000 * the DAC. 994 * the DAC.
1001 */ 995 */
1002 ffb_blank(0, &all->info); 996 ffb_blank(0, info);
1003
1004 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
1005 printk(KERN_ERR "ffb: Could not allocate color map.\n");
1006 of_iounmap(&op->resource[2],
1007 all->par.fbc, sizeof(struct ffb_fbc));
1008 of_iounmap(&op->resource[1],
1009 all->par.dac, sizeof(struct ffb_dac));
1010 kfree(all);
1011 return -ENOMEM;
1012 }
1013 997
1014 ffb_init_fix(&all->info); 998 if (fb_alloc_cmap(&info->cmap, 256, 0))
1015 999 goto out_unmap_dac;
1016 err = register_framebuffer(&all->info); 1000
1017 if (err < 0) { 1001 ffb_init_fix(info);
1018 printk(KERN_ERR "ffb: Could not register framebuffer.\n");
1019 fb_dealloc_cmap(&all->info.cmap);
1020 of_iounmap(&op->resource[2],
1021 all->par.fbc, sizeof(struct ffb_fbc));
1022 of_iounmap(&op->resource[1],
1023 all->par.dac, sizeof(struct ffb_dac));
1024 kfree(all);
1025 return err;
1026 }
1027 1002
1028 dev_set_drvdata(&op->dev, all); 1003 err = register_framebuffer(info);
1004 if (err < 0)
1005 goto out_dealloc_cmap;
1006
1007 dev_set_drvdata(&op->dev, info);
1029 1008
1030 printk("%s: %s at %016lx, type %d, " 1009 printk("%s: %s at %016lx, type %d, "
1031 "DAC pnum[%x] rev[%d] manuf_rev[%d]\n", 1010 "DAC pnum[%x] rev[%d] manuf_rev[%d]\n",
1032 dp->full_name, 1011 dp->full_name,
1033 ((all->par.flags & FFB_FLAG_AFB) ? "AFB" : "FFB"), 1012 ((par->flags & FFB_FLAG_AFB) ? "AFB" : "FFB"),
1034 all->par.physbase, all->par.board_type, 1013 par->physbase, par->board_type,
1035 dac_pnum, dac_rev, dac_mrev); 1014 dac_pnum, dac_rev, dac_mrev);
1036 1015
1037 return 0; 1016 return 0;
1038}
1039 1017
1040static int __devinit ffb_probe(struct of_device *dev, const struct of_device_id *match) 1018out_dealloc_cmap:
1041{ 1019 fb_dealloc_cmap(&info->cmap);
1042 struct of_device *op = to_of_device(&dev->dev); 1020
1021out_unmap_dac:
1022 of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc));
1023
1024out_unmap_fbc:
1025 of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc));
1026
1027out_release_fb:
1028 framebuffer_release(info);
1043 1029
1044 return ffb_init_one(op); 1030out_err:
1031 return err;
1045} 1032}
1046 1033
1047static int __devexit ffb_remove(struct of_device *op) 1034static int __devexit ffb_remove(struct of_device *op)
1048{ 1035{
1049 struct all_info *all = dev_get_drvdata(&op->dev); 1036 struct fb_info *info = dev_get_drvdata(&op->dev);
1037 struct ffb_par *par = info->par;
1050 1038
1051 unregister_framebuffer(&all->info); 1039 unregister_framebuffer(info);
1052 fb_dealloc_cmap(&all->info.cmap); 1040 fb_dealloc_cmap(&info->cmap);
1053 1041
1054 of_iounmap(&op->resource[2], all->par.fbc, sizeof(struct ffb_fbc)); 1042 of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc));
1055 of_iounmap(&op->resource[1], all->par.dac, sizeof(struct ffb_dac)); 1043 of_iounmap(&op->resource[1], par->dac, sizeof(struct ffb_dac));
1056 1044
1057 kfree(all); 1045 framebuffer_release(info);
1058 1046
1059 dev_set_drvdata(&op->dev, NULL); 1047 dev_set_drvdata(&op->dev, NULL);
1060 1048