make oldconfig will rebuild these...
[linux-2.4.21-pre4.git] / drivers / video / epson1356fb.h
1 /*
2  *      epson1356fb.h  --  Epson SED1356 Framebuffer Driver
3  *
4  * Copyright 2001 MontaVista Software Inc.
5  * Author: MontaVista Software, Inc.
6  *              stevel@mvista.com or source@mvista.com
7  *
8  *  This program is free software; you can redistribute  it and/or modify it
9  *  under  the terms of  the GNU General  Public License as published by the
10  *  Free Software Foundation;  either version 2 of the  License, or (at your
11  *  option) any later version.
12  *
13  *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
14  *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
15  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
16  *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
17  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18  *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
19  *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
21  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  *  You should have received a copy of the  GNU General Public License along
25  *  with this program; if not, write  to the Free Software Foundation, Inc.,
26  *  675 Mass Ave, Cambridge, MA 02139, USA.
27  */
28
29 #ifdef E1356FB_DEBUG
30 #define DPRINTK(a,b...) printk(KERN_DEBUG "e1356fb: %s: " a, __FUNCTION__ , ## b)
31 #else
32 #define DPRINTK(a,b...)
33 #endif 
34
35 #define E1356_REG_SIZE  0x200000
36
37 #define PICOS2KHZ(a) (1000000000UL/(a))
38 #define KHZ2PICOS(a) (1000000000UL/(a))
39
40 #define MAX_PIXCLOCK  40000 // KHz
41 #define NTSC_PIXCLOCK 14318 // KHz
42 #define PAL_PIXCLOCK  17734 // KHz
43
44 /*
45  * Maximum percent errors between desired pixel clock and
46  * supported pixel clock. Lower-than and higher-than desired
47  * clock percent errors.
48  */
49 #define MAX_PCLK_ERROR_LOWER  10
50 #define MAX_PCLK_ERROR_HIGHER -1
51
52 #define fontwidth_x8(p) (((fontwidth(p) + 7) >> 3) << 3)
53
54 /*
55  * Register Structures
56  */
57
58 // Basic
59 #define REG_BASE_BASIC     0x00
60 typedef struct {
61         u8 rev_code;           // 00
62         u8 misc;               // 01
63 } reg_basic_t;
64
65 // General IO Pins
66 #define REG_BASE_GENIO     0x04
67 typedef struct {
68         u8 gpio_cfg;           // 04
69         u8 gpio_cfg2;          // 05 SED13806
70         u8 spacer[2];          // 06
71         u8 gpio_ctrl;          // 08
72         u8 gpio_ctrl2;         // 09 SED13806
73 } reg_genio_t;
74
75 // MD Config Readback
76 #define REG_BASE_MDCFG     0x0c
77 typedef struct {
78         u8 md_cfg_stat0;       // 0C
79         u8 md_cfg_stat1;       // 0D
80 } reg_mdcfg_t;
81
82 // Clock Config
83 #define REG_BASE_CLKCFG    0x10
84 typedef struct {
85         u8 mem_clk_cfg;        // 10
86         u8 spacer1[3];         // 11
87         u8 lcd_pclk_cfg;       // 14
88         u8 spacer2[3];         // 15
89         u8 crttv_pclk_cfg;     // 18
90         u8 spacer3[3];         // 19
91         u8 mpclk_cfg;          // 1C
92         u8 spacer4;            // 1D
93         u8 cpu2mem_wait_sel;   // 1E
94 } reg_clkcfg_t;
95
96 // Memory Config
97 #define REG_BASE_MEMCFG    0x20
98 typedef struct {
99         u8 mem_cfg;            // 20
100         u8 dram_refresh;       // 21
101         u8 spacer[8];          // 22
102         u8 dram_timings_ctrl0; // 2A
103         u8 dram_timings_ctrl1; // 2B
104 } reg_memcfg_t;
105
106 // Panel Config
107 #define REG_BASE_PANELCFG  0x30
108 typedef struct {
109         u8 panel_type;         // 30
110         u8 mod_rate;           // 31
111 } reg_panelcfg_t;
112
113 // LCD and CRTTV Display Config
114 #define REG_BASE_LCD_DISPCFG   0x32
115 #define REG_BASE_CRTTV_DISPCFG 0x50
116 typedef struct {
117         u8 hdw;                // 32 or 50
118         u8 spacer1;            // 33 or 51
119         u8 hndp;               // 34 or 52
120         u8 hsync_start;        // 35 or 53
121         u8 hsync_pulse;        // 36 or 54
122         u8 spacer2;            // 37 or 55
123         u8 vdh0;               // 38 or 56
124         u8 vdh1;               // 39 or 57
125         u8 vndp;               // 3A or 58
126         u8 vsync_start;        // 3B or 59
127         u8 vsync_pulse;        // 3C or 5A
128         u8 tv_output_ctrl;     // 5B (TV only)
129 } reg_dispcfg_t;
130
131 // LCD and CRTTV Display Mode
132 #define REG_BASE_LCD_DISPMODE   0x40
133 #define REG_BASE_CRTTV_DISPMODE 0x60
134 typedef struct {
135         u8 disp_mode;          // 40 or 60
136         u8 lcd_misc;           // 41 (LCD only)
137         u8 start_addr0;        // 42 or 62
138         u8 start_addr1;        // 43 or 63
139         u8 start_addr2;        // 44 or 64
140         u8 spacer1;            // 45 or 65
141         u8 mem_addr_offset0;   // 46 or 66
142         u8 mem_addr_offset1;   // 47 or 67
143         u8 pixel_panning;      // 48 or 68
144         u8 spacer2;            // 49 or 69
145         u8 fifo_high_thresh;   // 4A or 6A
146         u8 fifo_low_thresh;    // 4B or 6B
147 } reg_dispmode_t;
148
149 // LCD and CRTTV Ink/Cursor
150 #define REG_BASE_LCD_INKCURS   0x70
151 #define REG_BASE_CRTTV_INKCURS 0x80
152 typedef struct {
153         u8 ctrl;               // 70 or 80
154         u8 start_addr;         // 71 or 81
155         u8 x_pos0;             // 72 or 82
156         u8 x_pos1;             // 73 or 83
157         u8 y_pos0;             // 74 or 84
158         u8 y_pos1;             // 75 or 85
159         u8 blue0;              // 76 or 86
160         u8 green0;             // 77 or 87
161         u8 red0;               // 78 or 88
162         u8 spacer1;            // 79 or 89
163         u8 blue1;              // 7A or 8A
164         u8 green1;             // 7B or 8B
165         u8 red1;               // 7C or 8C
166         u8 spacer2;            // 7D or 8D
167         u8 fifo;               // 7E or 8E
168 } reg_inkcurs_t;
169
170 // BitBlt Config
171 #define REG_BASE_BITBLT        0x100
172 typedef struct {
173         u8 ctrl0;              // 100
174         u8 ctrl1;              // 101
175         u8 rop_code;           // 102
176         u8 operation;          // 103
177         u8 src_start_addr0;    // 104
178         u8 src_start_addr1;    // 105
179         u8 src_start_addr2;    // 106
180         u8 spacer1;            // 107
181         u8 dest_start_addr0;   // 108
182         u8 dest_start_addr1;   // 109
183         u8 dest_start_addr2;   // 10A
184         u8 spacer2;            // 10B
185         u8 mem_addr_offset0;   // 10C
186         u8 mem_addr_offset1;   // 10D
187         u8 spacer3[2];         // 10E
188         u8 width0;             // 110
189         u8 width1;             // 111
190         u8 height0;            // 112
191         u8 height1;            // 113
192         u8 bg_color0;          // 114
193         u8 bg_color1;          // 115
194         u8 spacer4[2];         // 116
195         u8 fg_color0;          // 118
196         u8 fg_color1;          // 119
197 } reg_bitblt_t;
198
199 // LUT
200 #define REG_BASE_LUT           0x1e0
201 typedef struct {
202         u8 mode;               // 1E0
203         u8 spacer1;            // 1E1
204         u8 addr;               // 1E2
205         u8 spacer2;            // 1E3
206         u8 data;               // 1E4
207 } reg_lut_t;
208
209 // Power Save Config
210 #define REG_BASE_PWRSAVE       0x1f0
211 typedef struct {
212         u8 cfg;                // 1F0
213         u8 status;             // 1F1
214 } reg_pwrsave_t;
215
216 // Misc
217 #define REG_BASE_MISC          0x1f4
218 typedef struct {
219         u8 cpu2mem_watchdog;   // 1F4
220         u8 spacer[7];          // 1F5
221         u8 disp_mode;          // 1FC
222 } reg_misc_t;
223
224 // MediaPlug
225 #define REG_BASE_MEDIAPLUG     0x1000
226 typedef struct {
227         u8 lcmd;               // 1000
228         u8 spacer1;            // 1001
229         u8 reserved_lcmd;      // 1002
230         u8 spacer2;            // 1003
231         u8 cmd;                // 1004
232         u8 spacer3;            // 1005
233         u8 reserved_cmd;       // 1006
234         u8 spacer4;            // 1007
235         u8 data;               // 1008
236 } reg_mediaplug_t;
237
238 // BitBlt data register. 16-bit access only
239 #define REG_BASE_BITBLT_DATA   0x100000
240
241 typedef struct {
242         reg_basic_t* basic;
243         reg_genio_t* genio;
244         reg_mdcfg_t* md_cfg;
245         reg_clkcfg_t* clk_cfg;
246         reg_memcfg_t* mem_cfg;
247         reg_panelcfg_t* panel_cfg;
248         reg_dispcfg_t* lcd_cfg;
249         reg_dispcfg_t* crttv_cfg;
250         reg_dispmode_t* lcd_mode;
251         reg_dispmode_t* crttv_mode;
252         reg_inkcurs_t* lcd_inkcurs;
253         reg_inkcurs_t* crttv_inkcurs;
254         reg_bitblt_t* bitblt;
255         reg_lut_t* lut;
256         reg_pwrsave_t* pwr_save;
257         reg_misc_t* misc;
258         reg_mediaplug_t* mediaplug;
259         u16* bitblt_data;
260 } e1356_reg_t;
261
262
263 /*--------------------------------------------------------*/
264
265 enum mem_type_t {
266         MEM_TYPE_EDO_2CAS = 0,
267         MEM_TYPE_FPM_2CAS,
268         MEM_TYPE_EDO_2WE,
269         MEM_TYPE_FPM_2WE,
270         MEM_TYPE_EMBEDDED_SDRAM = 0x80
271 };
272
273 enum mem_smr_t {
274         MEM_SMR_CBR = 0,
275         MEM_SMR_SELF,
276         MEM_SMR_NONE
277 };
278
279 enum disp_type_t {
280         DISP_TYPE_LCD = 0,
281         DISP_TYPE_TFT,
282         DISP_TYPE_CRT,
283         DISP_TYPE_PAL,
284         DISP_TYPE_NTSC
285 };
286
287 /*
288  * Maximum timing values, as determined by the SED1356 register
289  * field sizes. All are indexed by display type, except
290  * max_hsync_start which is first indexed by color depth,
291  * then by display type.
292  */
293 static const int max_hndp[5] = {256, 256, 512, 511, 510};
294 static const int max_hsync_start[2][5] = {
295         {0, 252, 507, 505, 505}, // 8 bpp
296         {0, 254, 509, 507, 507}  // 16 bpp
297 };
298 static const int max_hsync_width[5] = {0, 128, 128, 0, 0};
299 static const int max_vndp[5] = {64, 64, 128, 128, 128};
300 static const int max_vsync_start[5] = {0, 64, 128, 128, 128};
301 static const int max_vsync_width[5] = {0, 8, 8, 0, 0};
302
303 #define IS_PANEL(disp_type) \
304     (disp_type == DISP_TYPE_LCD || disp_type == DISP_TYPE_TFT)
305 #define IS_CRT(disp_type) (disp_type == DISP_TYPE_CRT)
306 #define IS_TV(disp_type) \
307     (disp_type == DISP_TYPE_NTSC || disp_type == DISP_TYPE_PAL)
308
309
310 enum tv_filters_t {
311         TV_FILT_LUM = 1,
312         TV_FILT_CHROM = 2,
313         TV_FILT_FLICKER = 4
314 };
315
316 enum tv_format_t {
317         TV_FMT_COMPOSITE = 0,
318         TV_FMT_S_VIDEO
319 };
320
321
322 struct e1356fb_fix {
323         int system;       // the number of a pre-packaged system
324         u64 regbase_phys; // phys start address of registers
325         u64 membase_phys; // phys start address of fb memory
326
327         // Memory parameters
328         int mem_speed;    // speed: 50, 60, 70, or 80 (nsec)
329         int mem_type;     // mem type: EDO-2CAS, FPM-2CAS, EDO-2WE, FPM-2WE
330         int mem_refresh;  // refresh rate in KHz
331         int mem_smr;      // suspend mode refresh: CAS_BEFORE_RAS, SELF, or NONE
332         // Clocks
333         int busclk;       // BUSCLK frequency, in KHz
334         int mclk;         // MCLK freq, in KHz, will either be BUSCLK or BUSCLK/2
335         int clki;         // CLKI frequency, in KHz
336         int clki2;        // CLKI2 frequency, in KHz
337
338         int disp_type;    // LCD, TFT, CRT, PAL, or NTSC
339
340         // TV Options
341         u8  tv_filt;      // TV Filter mask, LUM, CHROM, and FLICKER
342         int tv_fmt;       // TV output format, COMPOSITE or S_VIDEO
343     
344         // Panel (LCD,TFT) Options
345         int panel_el;     // enable support for EL-type panels
346         int panel_width;  // Panel data width: LCD: 4/8/16, TFT: 9/12/18
347     
348         // Misc
349         int noaccel;
350         int nopan;
351 #ifdef CONFIG_MTRR
352         int nomtrr;
353 #endif
354         int nohwcursor;
355         int mmunalign;    // force unaligned returned VA in mmap()
356         char fontname[40];
357
358         char *mode_option;
359 };
360
361
362 typedef struct {
363         int pixclk_d;     // Desired Pixel Clock, KHz
364         int pixclk;       // Closest supported clock to desired clock, KHz
365         int error;        // percent error between pixclock and pixclock_d
366         int clksrc;       // equal to busclk, mclk, clki, or clki2, KHz
367         int divisor;      // pixclk = clksrc/divisor, where divisor = 1,2,3, or 4
368         u8  pixclk_bits;  // pixclock register value for above settings
369 } pixclock_info_t;
370
371
372 struct e1356fb_par {
373         int width;
374         int height;
375         int width_virt;   // Width in pixels
376         int height_virt;  // Height in lines
377         int bpp;          // bits-per-pixel
378         int Bpp;          // Bytes-per-pixel
379
380         // Timing
381         pixclock_info_t ipclk;
382         int horiz_ndp;    // Horiz. Non-Display Period, pixels
383         int vert_ndp;     // Vert. Non-Display Period, lines
384         int hsync_pol;    // Polarity of horiz. sync signal (HRTC for CRT/TV,
385         // FPLINE for TFT). 0=active lo, 1=active hi
386         int hsync_start;  // Horiz. Sync Start position, pixels
387         int hsync_width;  // Horiz. Sync Pulse width, pixels
388         int hsync_freq;   // calculated horizontal sync frequency
389         int vsync_pol;    // Polarity of vert. sync signal (VRTC for CRT/TV,
390         // FPFRAME for TFT). 0=active lo, 1=active hi
391         int vsync_start;  // Vert. Sync Start position, lines
392         int vsync_width;  // Vert. Sync Pulse width, lines
393         int vsync_freq;   // calculated vertical sync frequency
394
395         int cmap_len;     // color-map length
396 };
397
398
399
400 struct fb_info_e1356 {
401         struct fb_info fb_info;
402
403         void *regbase_virt;
404         unsigned long regbase_size;
405         void *membase_virt;
406         unsigned long fb_size;
407
408         e1356_reg_t reg;
409
410         void* putcs_buffer;
411     
412         int max_pixclock;   // Max supported pixel clock, KHz
413         int open, mmaped;   // open count, is mmap'ed
414         
415         u8 chip_rev;
416     
417 #ifdef CONFIG_MTRR
418         int mtrr_idx;
419 #endif
420
421 #ifdef SHADOW_FRAME_BUFFER
422         struct {
423                 void* fb;
424                 struct timer_list timer;
425         } shadow;
426 #endif
427
428         struct { unsigned red, green, blue, pad; } palette[256];
429         struct display disp;
430
431 #if defined(FBCON_HAS_CFB16)
432         u16 fbcon_cmap16[16];
433 #endif
434     
435         struct {
436                 int type;
437                 int state;
438                 int w,h,u;
439                 int x,y,redraw;
440                 unsigned long enable,disable;
441                 struct timer_list timer;
442                 spinlock_t lock; 
443         } cursor;
444  
445         struct e1356fb_fix fix;
446         struct e1356fb_par default_par;
447         struct e1356fb_par current_par;
448 };
449
450
451 // The following are boot options for particular SED1356-based target systems
452
453 enum {
454         SYS_NULL,
455         SYS_PB1000,
456         SYS_PB1500,
457         SYS_SDU1356,
458         SYS_CLIO1050,
459         NUM_SYSTEMS // must be last
460 };
461
462 static struct {
463         struct e1356fb_fix fix;
464         struct e1356fb_par par;
465 } systems[NUM_SYSTEMS] = {
466
467         /*
468          * NULL system to help us detect missing options
469          * when the driver is compiled as a module.
470          */
471         {
472                 {   // fix
473                         SYS_NULL,
474                 },
475                 {   // par
476                 }
477         },
478
479         /*
480          * Alchemy Pb1000 evaluation board, SED1356
481          */
482         {
483                 {   // fix
484                         SYS_PB1000,
485                         /*
486                          * Note!: these are "pseudo" physical addresses;
487                          * the SED1356 is not actually mapped here, but rather
488                          * at the 36-bit address of 0xE 0000 0000. There is an
489                          * ugly hack in the Au1000 TLB refill handler that will
490                          * translate pte_t's in the range 0xE000 0000 -->
491                          * 0xEFFF FFFF to the 36-bit range 0xE 0000 0000 -->
492                          * 0xE 0FFF FFFF. The long-term solution is to support
493                          * 36-bit physical addresses in linux-mips32 mm, since
494                          * the mips32 specification specifically supports this.
495                          */
496                         0xE00000000, 0xE00200000,
497                         60, MEM_TYPE_EDO_2CAS, 64, MEM_SMR_CBR,
498                         0, 0,   // BUSCLK and MCLK are calculated at run-time
499                         40000, 14318, // CLKI, CLKI2
500 #ifdef CONFIG_PB1000_CRT
501                         DISP_TYPE_CRT,
502                         0, 0, // TV Options
503                         0, 0, // Panel options
504 #elif defined (CONFIG_PB1000_NTSC)
505                         DISP_TYPE_NTSC,
506                         TV_FILT_FLICKER|TV_FILT_LUM|TV_FILT_CHROM,
507                         TV_FMT_COMPOSITE,
508                         0, 0, // Panel options
509 #elif defined (CONFIG_PB1000_TFT)
510                         DISP_TYPE_TFT,
511                         0, 0, // TV Options
512                         0, 12, // Panel options, EL panel?, data width?
513 #else
514                         DISP_TYPE_PAL,
515                         TV_FILT_FLICKER|TV_FILT_LUM|TV_FILT_CHROM,
516                         TV_FMT_COMPOSITE,
517                         0, 0, // Panel options
518 #endif
519                         0, 0,
520 #ifdef CONFIG_MTRR
521                         0,
522 #endif
523                         0,
524                         0,
525                         {0},
526                         "800x600@60"
527                 },
528                 {   // par
529                         0, 0, 800, 600, 8, 1,
530                         // timings will be set by modedb
531                         {0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
532                         256
533                 }
534         },
535
536         /*
537          * Alchemy Pb1500 evaluation board, SED13806
538          */
539         {
540                 {   // fix
541                         SYS_PB1500,
542                         /*
543                          * Note!: these are "pseudo" physical addresses;
544                          * the SED1356 is not actually mapped here, but rather
545                          * at the 36-bit address of 0xE 0000 0000. There is an
546                          * ugly hack in the Au1000 TLB refill handler that will
547                          * translate pte_t's in the range 0xE000 0000 -->
548                          * 0xEFFF FFFF to the 36-bit range 0xE 0000 0000 -->
549                          * 0xE 0FFF FFFF. The long-term solution is to support
550                          * 36-bit physical addresses in linux-mips32 mm, since
551                          * the mips32 specification specifically supports this.
552                          */
553                         0xE1B000000, 0xE1B200000,
554                         50, MEM_TYPE_EMBEDDED_SDRAM, 64, MEM_SMR_CBR,
555                         0, 0,   // BUSCLK and MCLK are calculated at run-time
556                         40000, 14318, // CLKI, CLKI2
557 #ifdef CONFIG_PB1500_CRT
558                         DISP_TYPE_CRT,
559                         0, 0, // TV Options
560                         0, 0, // Panel options
561 #else
562                         DISP_TYPE_TFT,
563                         0, 0, // TV Options
564                         0, 12, // Panel options, EL panel?, data width?
565 #endif
566                         0, 0,
567 #ifdef CONFIG_MTRR
568                         0,
569 #endif
570                         0,
571                         0,
572                         {0},
573                         "800x600@60"
574                 },
575                 {   // par
576                         0, 0, 800, 600, 8, 1,
577                         // timings will be set by modedb
578                         {0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
579                         256
580                 }
581         },
582
583         /*
584          * Epson SDU1356B0C PCI eval card. These settings assume the
585          * card is configured for PCI, the MediaPlug is disabled,
586          * and the onboard clock synthesizer is at the power-up
587          * clock settings.
588          */
589         {
590                 {   // fix
591                         SYS_SDU1356,
592                         0x0, 0x0,  // addresses obtained from PCI config space
593                         // FIXME: just guess for now
594                         60, MEM_TYPE_EDO_2CAS, 64, MEM_SMR_CBR,
595                         33000, 0, 40000, 25175, // BUSCLK, MCLK, CLKI, CLKI2
596                         DISP_TYPE_CRT,
597                         0, 0,
598                         0, 0,
599                         0, 0,
600 #ifdef CONFIG_MTRR
601                         0,
602 #endif
603                         0,
604                         0,
605                         {0},
606                         "800x600@60"
607                 },
608                 {   // par
609                         0, 0, 1024, 768, 8, 1,
610                         // timings will be set by modedb
611                         {0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
612                         256
613                 }
614         },
615
616         /*
617          * Vadem Clio 1050 - this is for the benefit of the Linux-VR project.
618          * FIXME: Most of these settings are just guesses, until I can get a
619          * Clio 1050 and dump the registers that WinCE has setup.
620          */
621         {
622                 {   // fix
623                         SYS_CLIO1050,
624                         0x0a000000, 0x0a200000,
625                         60, MEM_TYPE_EDO_2CAS, 64, MEM_SMR_CBR,
626                         40000, 40000, 14318, 14318,
627                         DISP_TYPE_TFT,
628                         0, 0,
629                         0, 16,
630                         0, 0,
631 #ifdef CONFIG_MTRR
632                         0,
633 #endif
634                         0,
635                         0,
636                         {0},
637                         "640x480@85"
638                 },
639                 {   // par
640                         0, 0, 1024, 768, 16, 2,
641                         // timings will be set by modedb
642                         {0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
643                         16
644                 }
645         }
646 };