Blame view

drivers/video/tcx.c 12.1 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
  /* tcx.c: TCX frame buffer driver
   *
50312ce9d   David S. Miller   [SPARC]: Convert ...
3
   * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4
5
6
7
8
9
10
11
12
13
14
   * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
   * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
   * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
   *
   * Driver layout based loosely on tgafb.c, see that file for credits.
   */
  
  #include <linux/module.h>
  #include <linux/kernel.h>
  #include <linux/errno.h>
  #include <linux/string.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
15
16
17
18
  #include <linux/delay.h>
  #include <linux/init.h>
  #include <linux/fb.h>
  #include <linux/mm.h>
6cd5a86b5   Robert Reif   sparc video: remo...
19
  #include <linux/of_device.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
20
21
  
  #include <asm/io.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
22
23
24
25
26
27
28
29
30
31
32
  #include <asm/fbio.h>
  
  #include "sbuslib.h"
  
  /*
   * Local functions.
   */
  
  static int tcx_setcolreg(unsigned, unsigned, unsigned, unsigned,
  			 unsigned, struct fb_info *);
  static int tcx_blank(int, struct fb_info *);
216d526c8   Christoph Hellwig   [PATCH] fbdev: Sa...
33
  static int tcx_mmap(struct fb_info *, struct vm_area_struct *);
67a6680d6   Christoph Hellwig   [PATCH] fbdev: Sa...
34
  static int tcx_ioctl(struct fb_info *, unsigned int, unsigned long);
6ee7c1529   Tom 'spot' Callaway   [SPARC]: TCX Fram...
35
  static int tcx_pan_display(struct fb_var_screeninfo *, struct fb_info *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36
37
38
39
40
41
42
43
44
  
  /*
   *  Frame buffer operations
   */
  
  static struct fb_ops tcx_ops = {
  	.owner			= THIS_MODULE,
  	.fb_setcolreg		= tcx_setcolreg,
  	.fb_blank		= tcx_blank,
6ee7c1529   Tom 'spot' Callaway   [SPARC]: TCX Fram...
45
  	.fb_pan_display		= tcx_pan_display,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
47
48
49
50
  	.fb_fillrect		= cfb_fillrect,
  	.fb_copyarea		= cfb_copyarea,
  	.fb_imageblit		= cfb_imageblit,
  	.fb_mmap		= tcx_mmap,
  	.fb_ioctl		= tcx_ioctl,
9ffb83bcc   Christoph Hellwig   [SBUSFB]: impleme...
51
52
53
  #ifdef CONFIG_COMPAT
  	.fb_compat_ioctl	= sbusfb_compat_ioctl,
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
  };
  
  /* THC definitions */
  #define TCX_THC_MISC_REV_SHIFT       16
  #define TCX_THC_MISC_REV_MASK        15
  #define TCX_THC_MISC_VSYNC_DIS       (1 << 25)
  #define TCX_THC_MISC_HSYNC_DIS       (1 << 24)
  #define TCX_THC_MISC_RESET           (1 << 12)
  #define TCX_THC_MISC_VIDEO           (1 << 10)
  #define TCX_THC_MISC_SYNC            (1 << 9)
  #define TCX_THC_MISC_VSYNC           (1 << 8)
  #define TCX_THC_MISC_SYNC_ENAB       (1 << 7)
  #define TCX_THC_MISC_CURS_RES        (1 << 6)
  #define TCX_THC_MISC_INT_ENAB        (1 << 5)
  #define TCX_THC_MISC_INT             (1 << 4)
  #define TCX_THC_MISC_INIT            0x9f
  #define TCX_THC_REV_REV_SHIFT        20
  #define TCX_THC_REV_REV_MASK         15
  #define TCX_THC_REV_MINREV_SHIFT     28
  #define TCX_THC_REV_MINREV_MASK      15
  
  /* The contents are unknown */
  struct tcx_tec {
50312ce9d   David S. Miller   [SPARC]: Convert ...
77
78
79
  	u32 tec_matrix;
  	u32 tec_clip;
  	u32 tec_vdc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
80
81
82
  };
  
  struct tcx_thc {
50312ce9d   David S. Miller   [SPARC]: Convert ...
83
  	u32 thc_rev;
5b81d689e   Robert Reif   sparc: tcx.c remo...
84
  	u32 thc_pad0[511];
50312ce9d   David S. Miller   [SPARC]: Convert ...
85
86
87
88
89
90
91
  	u32 thc_hs;		/* hsync timing */
  	u32 thc_hsdvs;
  	u32 thc_hd;
  	u32 thc_vs;		/* vsync timing */
  	u32 thc_vd;
  	u32 thc_refresh;
  	u32 thc_misc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
92
  	u32 thc_pad1[56];
50312ce9d   David S. Miller   [SPARC]: Convert ...
93
94
95
  	u32 thc_cursxy;	/* cursor x,y position (16 bits each) */
  	u32 thc_cursmask[32];	/* cursor mask bits */
  	u32 thc_cursbits[32];	/* what to show where mask enabled */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
96
97
98
  };
  
  struct bt_regs {
50312ce9d   David S. Miller   [SPARC]: Convert ...
99
100
101
102
  	u32 addr;
  	u32 color_map;
  	u32 control;
  	u32 cursor;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
103
104
105
106
107
108
109
110
111
  };
  
  #define TCX_MMAP_ENTRIES 14
  
  struct tcx_par {
  	spinlock_t		lock;
  	struct bt_regs		__iomem *bt;
  	struct tcx_thc		__iomem *thc;
  	struct tcx_tec		__iomem *tec;
50312ce9d   David S. Miller   [SPARC]: Convert ...
112
  	u32			__iomem *cplane;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
113
114
115
  
  	u32			flags;
  #define TCX_FLAG_BLANKED	0x00000001
50312ce9d   David S. Miller   [SPARC]: Convert ...
116
  	unsigned long		which_io;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
117
118
119
  
  	struct sbus_mmap_map	mmap_map[TCX_MMAP_ENTRIES];
  	int			lowdepth;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
120
121
122
  };
  
  /* Reset control plane so that WID is 8-bit plane. */
fe3a1aa23   Krzysztof Helt   tcx: use standard...
123
  static void __tcx_set_control_plane(struct fb_info *info)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
124
  {
fe3a1aa23   Krzysztof Helt   tcx: use standard...
125
  	struct tcx_par *par = info->par;
50312ce9d   David S. Miller   [SPARC]: Convert ...
126
  	u32 __iomem *p, *pend;
5b81d689e   Robert Reif   sparc: tcx.c remo...
127

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
128
129
130
131
132
133
  	if (par->lowdepth)
  		return;
  
  	p = par->cplane;
  	if (p == NULL)
  		return;
fe3a1aa23   Krzysztof Helt   tcx: use standard...
134
  	for (pend = p + info->fix.smem_len; p < pend; p++) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
135
136
137
138
139
140
  		u32 tmp = sbus_readl(p);
  
  		tmp &= 0xffffff;
  		sbus_writel(tmp, p);
  	}
  }
5b81d689e   Robert Reif   sparc: tcx.c remo...
141
142
  
  static void tcx_reset(struct fb_info *info)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
143
144
145
146
147
  {
  	struct tcx_par *par = (struct tcx_par *) info->par;
  	unsigned long flags;
  
  	spin_lock_irqsave(&par->lock, flags);
fe3a1aa23   Krzysztof Helt   tcx: use standard...
148
  	__tcx_set_control_plane(info);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149
150
  	spin_unlock_irqrestore(&par->lock, flags);
  }
6ee7c1529   Tom 'spot' Callaway   [SPARC]: TCX Fram...
151
152
153
154
155
  static int tcx_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
  {
  	tcx_reset(info);
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
  /**
   *      tcx_setcolreg - Optional function. Sets a color register.
   *      @regno: boolean, 0 copy local, 1 get_user() function
   *      @red: frame buffer colormap structure
   *      @green: The green value which can be up to 16 bits wide
   *      @blue:  The blue value which can be up to 16 bits wide.
   *      @transp: If supported the alpha value which can be up to 16 bits wide.
   *      @info: frame buffer info structure
   */
  static int tcx_setcolreg(unsigned regno,
  			 unsigned red, unsigned green, unsigned blue,
  			 unsigned transp, struct fb_info *info)
  {
  	struct tcx_par *par = (struct tcx_par *) info->par;
  	struct bt_regs __iomem *bt = par->bt;
  	unsigned long flags;
  
  	if (regno >= 256)
  		return 1;
  
  	red >>= 8;
  	green >>= 8;
  	blue >>= 8;
  
  	spin_lock_irqsave(&par->lock, flags);
  
  	sbus_writel(regno << 24, &bt->addr);
  	sbus_writel(red << 24, &bt->color_map);
  	sbus_writel(green << 24, &bt->color_map);
  	sbus_writel(blue << 24, &bt->color_map);
  
  	spin_unlock_irqrestore(&par->lock, flags);
  
  	return 0;
  }
  
  /**
   *      tcx_blank - Optional function.  Blanks the display.
   *      @blank_mode: the blank mode we want.
   *      @info: frame buffer structure that represents a single frame buffer
   */
  static int
  tcx_blank(int blank, struct fb_info *info)
  {
  	struct tcx_par *par = (struct tcx_par *) info->par;
  	struct tcx_thc __iomem *thc = par->thc;
  	unsigned long flags;
  	u32 val;
  
  	spin_lock_irqsave(&par->lock, flags);
  
  	val = sbus_readl(&thc->thc_misc);
  
  	switch (blank) {
  	case FB_BLANK_UNBLANK: /* Unblanking */
  		val &= ~(TCX_THC_MISC_VSYNC_DIS |
  			 TCX_THC_MISC_HSYNC_DIS);
  		val |= TCX_THC_MISC_VIDEO;
  		par->flags &= ~TCX_FLAG_BLANKED;
  		break;
  
  	case FB_BLANK_NORMAL: /* Normal blanking */
  		val &= ~TCX_THC_MISC_VIDEO;
  		par->flags |= TCX_FLAG_BLANKED;
  		break;
  
  	case FB_BLANK_VSYNC_SUSPEND: /* VESA blank (vsync off) */
  		val |= TCX_THC_MISC_VSYNC_DIS;
  		break;
  	case FB_BLANK_HSYNC_SUSPEND: /* VESA blank (hsync off) */
  		val |= TCX_THC_MISC_HSYNC_DIS;
  		break;
  
  	case FB_BLANK_POWERDOWN: /* Poweroff */
  		break;
  	};
  
  	sbus_writel(val, &thc->thc_misc);
  
  	spin_unlock_irqrestore(&par->lock, flags);
  
  	return 0;
  }
  
  static struct sbus_mmap_map __tcx_mmap_map[TCX_MMAP_ENTRIES] = {
  	{
  		.voff	= TCX_RAM8BIT,
  		.size	= SBUS_MMAP_FBSIZE(1)
  	},
  	{
  		.voff	= TCX_RAM24BIT,
  		.size	= SBUS_MMAP_FBSIZE(4)
  	},
  	{
  		.voff	= TCX_UNK3,
  		.size	= SBUS_MMAP_FBSIZE(8)
  	},
  	{
  		.voff	= TCX_UNK4,
  		.size	= SBUS_MMAP_FBSIZE(8)
  	},
  	{
  		.voff	= TCX_CONTROLPLANE,
  		.size	= SBUS_MMAP_FBSIZE(4)
  	},
  	{
  		.voff	= TCX_UNK6,
  		.size	= SBUS_MMAP_FBSIZE(8)
  	},
  	{
  		.voff	= TCX_UNK7,
  		.size	= SBUS_MMAP_FBSIZE(8)
  	},
  	{
  		.voff	= TCX_TEC,
  		.size	= PAGE_SIZE
  	},
  	{
  		.voff	= TCX_BTREGS,
  		.size	= PAGE_SIZE
  	},
  	{
  		.voff	= TCX_THC,
  		.size	= PAGE_SIZE
  	},
  	{
  		.voff	= TCX_DHC,
  		.size	= PAGE_SIZE
  	},
  	{
  		.voff	= TCX_ALT,
  		.size	= PAGE_SIZE
  	},
  	{
  		.voff	= TCX_UNK2,
  		.size	= 0x20000
  	},
  	{ .size = 0 }
  };
216d526c8   Christoph Hellwig   [PATCH] fbdev: Sa...
295
  static int tcx_mmap(struct fb_info *info, struct vm_area_struct *vma)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
296
297
298
299
  {
  	struct tcx_par *par = (struct tcx_par *)info->par;
  
  	return sbusfb_mmap_helper(par->mmap_map,
fe3a1aa23   Krzysztof Helt   tcx: use standard...
300
  				  info->fix.smem_start, info->fix.smem_len,
50312ce9d   David S. Miller   [SPARC]: Convert ...
301
  				  par->which_io, vma);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
302
  }
67a6680d6   Christoph Hellwig   [PATCH] fbdev: Sa...
303
304
  static int tcx_ioctl(struct fb_info *info, unsigned int cmd,
  		     unsigned long arg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
305
306
307
308
309
310
  {
  	struct tcx_par *par = (struct tcx_par *) info->par;
  
  	return sbusfb_ioctl_helper(cmd, arg, info,
  				   FBTYPE_TCXCOLOR,
  				   (par->lowdepth ? 8 : 24),
fe3a1aa23   Krzysztof Helt   tcx: use standard...
311
  				   info->fix.smem_len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
  }
  
  /*
   *  Initialisation
   */
  
  static void
  tcx_init_fix(struct fb_info *info, int linebytes)
  {
  	struct tcx_par *par = (struct tcx_par *)info->par;
  	const char *tcx_name;
  
  	if (par->lowdepth)
  		tcx_name = "TCX8";
  	else
  		tcx_name = "TCX24";
  
  	strlcpy(info->fix.id, tcx_name, sizeof(info->fix.id));
  
  	info->fix.type = FB_TYPE_PACKED_PIXELS;
  	info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
  
  	info->fix.line_length = linebytes;
  
  	info->fix.accel = FB_ACCEL_SUN_TCX;
  }
2dc115813   Grant Likely   of/device: Replac...
338
  static void tcx_unmap_regs(struct platform_device *op, struct fb_info *info,
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
339
  			   struct tcx_par *par)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
340
  {
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
341
  	if (par->tec)
e3a411a3d   David S. Miller   [SPARC64]: Fix of...
342
  		of_iounmap(&op->resource[7],
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
343
344
  			   par->tec, sizeof(struct tcx_tec));
  	if (par->thc)
e3a411a3d   David S. Miller   [SPARC64]: Fix of...
345
  		of_iounmap(&op->resource[9],
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
346
347
  			   par->thc, sizeof(struct tcx_thc));
  	if (par->bt)
e3a411a3d   David S. Miller   [SPARC64]: Fix of...
348
  		of_iounmap(&op->resource[8],
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
349
350
  			   par->bt, sizeof(struct bt_regs));
  	if (par->cplane)
e3a411a3d   David S. Miller   [SPARC64]: Fix of...
351
  		of_iounmap(&op->resource[4],
fe3a1aa23   Krzysztof Helt   tcx: use standard...
352
  			   par->cplane, info->fix.smem_len * sizeof(u32));
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
353
  	if (info->screen_base)
e3a411a3d   David S. Miller   [SPARC64]: Fix of...
354
  		of_iounmap(&op->resource[0],
fe3a1aa23   Krzysztof Helt   tcx: use standard...
355
  			   info->screen_base, info->fix.smem_len);
50312ce9d   David S. Miller   [SPARC]: Convert ...
356
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
357

28541d0f1   Grant Likely   dt/video: Elimina...
358
  static int __devinit tcx_probe(struct platform_device *op)
50312ce9d   David S. Miller   [SPARC]: Convert ...
359
  {
d4b8b2c2c   Anatolij Gustschin   of/video: fix bui...
360
  	struct device_node *dp = op->dev.of_node;
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
361
362
  	struct fb_info *info;
  	struct tcx_par *par;
50312ce9d   David S. Miller   [SPARC]: Convert ...
363
  	int linebytes, i, err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
364

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
365
  	info = framebuffer_alloc(sizeof(struct tcx_par), &op->dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
366

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
367
368
369
370
  	err = -ENOMEM;
  	if (!info)
  		goto out_err;
  	par = info->par;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
371

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
372
373
374
  	spin_lock_init(&par->lock);
  
  	par->lowdepth =
50312ce9d   David S. Miller   [SPARC]: Convert ...
375
  		(of_find_property(dp, "tcx-8-bit", NULL) != NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
376

6cd5a86b5   Robert Reif   sparc video: remo...
377
  	sbusfb_fill_var(&info->var, dp, 8);
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
378
379
380
  	info->var.red.length = 8;
  	info->var.green.length = 8;
  	info->var.blue.length = 8;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
381

50312ce9d   David S. Miller   [SPARC]: Convert ...
382
  	linebytes = of_getintprop_default(dp, "linebytes",
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
383
  					  info->var.xres);
fe3a1aa23   Krzysztof Helt   tcx: use standard...
384
  	info->fix.smem_len = PAGE_ALIGN(linebytes * info->var.yres);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
385

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
386
  	par->tec = of_ioremap(&op->resource[7], 0,
50312ce9d   David S. Miller   [SPARC]: Convert ...
387
  				  sizeof(struct tcx_tec), "tcx tec");
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
388
  	par->thc = of_ioremap(&op->resource[9], 0,
50312ce9d   David S. Miller   [SPARC]: Convert ...
389
  				  sizeof(struct tcx_thc), "tcx thc");
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
390
  	par->bt = of_ioremap(&op->resource[8], 0,
50312ce9d   David S. Miller   [SPARC]: Convert ...
391
  				 sizeof(struct bt_regs), "tcx dac");
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
392
  	info->screen_base = of_ioremap(&op->resource[0], 0,
fe3a1aa23   Krzysztof Helt   tcx: use standard...
393
  					   info->fix.smem_len, "tcx ram");
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
394
395
396
397
398
399
400
  	if (!par->tec || !par->thc ||
  	    !par->bt || !info->screen_base)
  		goto out_unmap_regs;
  
  	memcpy(&par->mmap_map, &__tcx_mmap_map, sizeof(par->mmap_map));
  	if (!par->lowdepth) {
  		par->cplane = of_ioremap(&op->resource[4], 0,
fe3a1aa23   Krzysztof Helt   tcx: use standard...
401
  					     info->fix.smem_len * sizeof(u32),
50312ce9d   David S. Miller   [SPARC]: Convert ...
402
  					     "tcx cplane");
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
403
404
  		if (!par->cplane)
  			goto out_unmap_regs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
405
  	} else {
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
406
407
408
409
  		par->mmap_map[1].size = SBUS_MMAP_EMPTY;
  		par->mmap_map[4].size = SBUS_MMAP_EMPTY;
  		par->mmap_map[5].size = SBUS_MMAP_EMPTY;
  		par->mmap_map[6].size = SBUS_MMAP_EMPTY;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
410
  	}
fe3a1aa23   Krzysztof Helt   tcx: use standard...
411
  	info->fix.smem_start = op->resource[0].start;
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
412
  	par->which_io = op->resource[0].flags & IORESOURCE_BITS;
50312ce9d   David S. Miller   [SPARC]: Convert ...
413

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
  	for (i = 0; i < TCX_MMAP_ENTRIES; i++) {
  		int j;
  
  		switch (i) {
  		case 10:
  			j = 12;
  			break;
  
  		case 11: case 12:
  			j = i - 1;
  			break;
  
  		default:
  			j = i;
  			break;
  		};
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
430
  		par->mmap_map[i].poff = op->resource[j].start;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
431
  	}
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
432
433
  	info->flags = FBINFO_DEFAULT;
  	info->fbops = &tcx_ops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
434
435
  
  	/* Initialize brooktree DAC. */
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
436
437
438
439
440
441
442
443
444
445
  	sbus_writel(0x04 << 24, &par->bt->addr);         /* color planes */
  	sbus_writel(0xff << 24, &par->bt->control);
  	sbus_writel(0x05 << 24, &par->bt->addr);
  	sbus_writel(0x00 << 24, &par->bt->control);
  	sbus_writel(0x06 << 24, &par->bt->addr);         /* overlay plane */
  	sbus_writel(0x73 << 24, &par->bt->control);
  	sbus_writel(0x07 << 24, &par->bt->addr);
  	sbus_writel(0x00 << 24, &par->bt->control);
  
  	tcx_reset(info);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
446

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
447
  	tcx_blank(FB_BLANK_UNBLANK, info);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
448

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
449
450
451
452
453
454
455
456
457
  	if (fb_alloc_cmap(&info->cmap, 256, 0))
  		goto out_unmap_regs;
  
  	fb_set_cmap(&info->cmap, info);
  	tcx_init_fix(info, linebytes);
  
  	err = register_framebuffer(info);
  	if (err < 0)
  		goto out_dealloc_cmap;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
458

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
459
  	dev_set_drvdata(&op->dev, info);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
460

194f1a68b   Robert Reif   sparc: video driv...
461
462
  	printk(KERN_INFO "%s: TCX at %lx:%lx, %s
  ",
50312ce9d   David S. Miller   [SPARC]: Convert ...
463
  	       dp->full_name,
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
464
  	       par->which_io,
fe3a1aa23   Krzysztof Helt   tcx: use standard...
465
  	       info->fix.smem_start,
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
466
  	       par->lowdepth ? "8-bit only" : "24-bit depth");
50312ce9d   David S. Miller   [SPARC]: Convert ...
467
468
  
  	return 0;
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
469
470
471
472
473
474
  
  out_dealloc_cmap:
  	fb_dealloc_cmap(&info->cmap);
  
  out_unmap_regs:
  	tcx_unmap_regs(op, info, par);
6359691d7   Axel Lin   video: add missin...
475
  	framebuffer_release(info);
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
476
477
478
  
  out_err:
  	return err;
50312ce9d   David S. Miller   [SPARC]: Convert ...
479
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
480

2dc115813   Grant Likely   of/device: Replac...
481
  static int __devexit tcx_remove(struct platform_device *op)
50312ce9d   David S. Miller   [SPARC]: Convert ...
482
  {
c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
483
484
  	struct fb_info *info = dev_get_drvdata(&op->dev);
  	struct tcx_par *par = info->par;
50312ce9d   David S. Miller   [SPARC]: Convert ...
485

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
486
487
  	unregister_framebuffer(info);
  	fb_dealloc_cmap(&info->cmap);
50312ce9d   David S. Miller   [SPARC]: Convert ...
488

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
489
  	tcx_unmap_regs(op, info, par);
50312ce9d   David S. Miller   [SPARC]: Convert ...
490

c7f439b99   David S. Miller   [VIDEO]: Fix OOPS...
491
  	framebuffer_release(info);
50312ce9d   David S. Miller   [SPARC]: Convert ...
492

e3a411a3d   David S. Miller   [SPARC64]: Fix of...
493
  	dev_set_drvdata(&op->dev, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
494
495
496
  
  	return 0;
  }
fd098316e   David S. Miller   sparc: Annotate o...
497
  static const struct of_device_id tcx_match[] = {
50312ce9d   David S. Miller   [SPARC]: Convert ...
498
499
500
501
502
503
  	{
  		.name = "SUNW,tcx",
  	},
  	{},
  };
  MODULE_DEVICE_TABLE(of, tcx_match);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
504

28541d0f1   Grant Likely   dt/video: Elimina...
505
  static struct platform_driver tcx_driver = {
4018294b5   Grant Likely   of: Remove duplic...
506
507
508
509
510
  	.driver = {
  		.name = "tcx",
  		.owner = THIS_MODULE,
  		.of_match_table = tcx_match,
  	},
50312ce9d   David S. Miller   [SPARC]: Convert ...
511
512
513
  	.probe		= tcx_probe,
  	.remove		= __devexit_p(tcx_remove),
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
514

f36861d55   Robert Reif   sparc: tcx.c make...
515
  static int __init tcx_init(void)
50312ce9d   David S. Miller   [SPARC]: Convert ...
516
517
518
  {
  	if (fb_get_options("tcxfb", NULL))
  		return -ENODEV;
28541d0f1   Grant Likely   dt/video: Elimina...
519
  	return platform_driver_register(&tcx_driver);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
520
  }
f36861d55   Robert Reif   sparc: tcx.c make...
521
  static void __exit tcx_exit(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
522
  {
28541d0f1   Grant Likely   dt/video: Elimina...
523
  	platform_driver_unregister(&tcx_driver);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
524
525
526
  }
  
  module_init(tcx_init);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
527
  module_exit(tcx_exit);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
528
529
  
  MODULE_DESCRIPTION("framebuffer driver for TCX chipsets");
50312ce9d   David S. Miller   [SPARC]: Convert ...
530
531
  MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
  MODULE_VERSION("2.0");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
532
  MODULE_LICENSE("GPL");