1
2
3
4
5
6
7
8
9
10#include <linux/platform_device.h>
11#include <linux/init.h>
12#include <linux/serial.h>
13#include <linux/io.h>
14#include <linux/serial_sci.h>
15#include <linux/sh_dma.h>
16#include <linux/sh_timer.h>
17#include <linux/sh_intc.h>
18#include <cpu/dma-register.h>
19
20static struct plat_sci_port scif0_platform_data = {
21 .flags = UPF_BOOT_AUTOCONF,
22 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
23 .type = PORT_SCIF,
24 .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
25};
26
27static struct resource scif0_resources[] = {
28 DEFINE_RES_MEM(0xffe00000, 0x100),
29 DEFINE_RES_IRQ(evt2irq(0x700)),
30};
31
32static struct platform_device scif0_device = {
33 .name = "sh-sci",
34 .id = 0,
35 .resource = scif0_resources,
36 .num_resources = ARRAY_SIZE(scif0_resources),
37 .dev = {
38 .platform_data = &scif0_platform_data,
39 },
40};
41
42static struct plat_sci_port scif1_platform_data = {
43 .flags = UPF_BOOT_AUTOCONF,
44 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
45 .type = PORT_SCIF,
46 .regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
47};
48
49static struct resource scif1_resources[] = {
50 DEFINE_RES_MEM(0xffe10000, 0x100),
51 DEFINE_RES_IRQ(evt2irq(0xb80)),
52};
53
54static struct platform_device scif1_device = {
55 .name = "sh-sci",
56 .id = 1,
57 .resource = scif1_resources,
58 .num_resources = ARRAY_SIZE(scif1_resources),
59 .dev = {
60 .platform_data = &scif1_platform_data,
61 },
62};
63
64static struct sh_timer_config tmu0_platform_data = {
65 .channel_offset = 0x04,
66 .timer_bit = 0,
67 .clockevent_rating = 200,
68};
69
70static struct resource tmu0_resources[] = {
71 [0] = {
72 .start = 0xffd80008,
73 .end = 0xffd80013,
74 .flags = IORESOURCE_MEM,
75 },
76 [1] = {
77 .start = evt2irq(0x580),
78 .flags = IORESOURCE_IRQ,
79 },
80};
81
82static struct platform_device tmu0_device = {
83 .name = "sh_tmu",
84 .id = 0,
85 .dev = {
86 .platform_data = &tmu0_platform_data,
87 },
88 .resource = tmu0_resources,
89 .num_resources = ARRAY_SIZE(tmu0_resources),
90};
91
92static struct sh_timer_config tmu1_platform_data = {
93 .channel_offset = 0x10,
94 .timer_bit = 1,
95 .clocksource_rating = 200,
96};
97
98static struct resource tmu1_resources[] = {
99 [0] = {
100 .start = 0xffd80014,
101 .end = 0xffd8001f,
102 .flags = IORESOURCE_MEM,
103 },
104 [1] = {
105 .start = evt2irq(0x5a0),
106 .flags = IORESOURCE_IRQ,
107 },
108};
109
110static struct platform_device tmu1_device = {
111 .name = "sh_tmu",
112 .id = 1,
113 .dev = {
114 .platform_data = &tmu1_platform_data,
115 },
116 .resource = tmu1_resources,
117 .num_resources = ARRAY_SIZE(tmu1_resources),
118};
119
120static struct sh_timer_config tmu2_platform_data = {
121 .channel_offset = 0x1c,
122 .timer_bit = 2,
123};
124
125static struct resource tmu2_resources[] = {
126 [0] = {
127 .start = 0xffd80020,
128 .end = 0xffd8002f,
129 .flags = IORESOURCE_MEM,
130 },
131 [1] = {
132 .start = evt2irq(0x5c0),
133 .flags = IORESOURCE_IRQ,
134 },
135};
136
137static struct platform_device tmu2_device = {
138 .name = "sh_tmu",
139 .id = 2,
140 .dev = {
141 .platform_data = &tmu2_platform_data,
142 },
143 .resource = tmu2_resources,
144 .num_resources = ARRAY_SIZE(tmu2_resources),
145};
146
147static struct sh_timer_config tmu3_platform_data = {
148 .channel_offset = 0x04,
149 .timer_bit = 0,
150};
151
152static struct resource tmu3_resources[] = {
153 [0] = {
154 .start = 0xffdc0008,
155 .end = 0xffdc0013,
156 .flags = IORESOURCE_MEM,
157 },
158 [1] = {
159 .start = evt2irq(0xe00),
160 .flags = IORESOURCE_IRQ,
161 },
162};
163
164static struct platform_device tmu3_device = {
165 .name = "sh_tmu",
166 .id = 3,
167 .dev = {
168 .platform_data = &tmu3_platform_data,
169 },
170 .resource = tmu3_resources,
171 .num_resources = ARRAY_SIZE(tmu3_resources),
172};
173
174static struct sh_timer_config tmu4_platform_data = {
175 .channel_offset = 0x10,
176 .timer_bit = 1,
177};
178
179static struct resource tmu4_resources[] = {
180 [0] = {
181 .start = 0xffdc0014,
182 .end = 0xffdc001f,
183 .flags = IORESOURCE_MEM,
184 },
185 [1] = {
186 .start = evt2irq(0xe20),
187 .flags = IORESOURCE_IRQ,
188 },
189};
190
191static struct platform_device tmu4_device = {
192 .name = "sh_tmu",
193 .id = 4,
194 .dev = {
195 .platform_data = &tmu4_platform_data,
196 },
197 .resource = tmu4_resources,
198 .num_resources = ARRAY_SIZE(tmu4_resources),
199};
200
201static struct sh_timer_config tmu5_platform_data = {
202 .channel_offset = 0x1c,
203 .timer_bit = 2,
204};
205
206static struct resource tmu5_resources[] = {
207 [0] = {
208 .start = 0xffdc0020,
209 .end = 0xffdc002b,
210 .flags = IORESOURCE_MEM,
211 },
212 [1] = {
213 .start = evt2irq(0xe40),
214 .flags = IORESOURCE_IRQ,
215 },
216};
217
218static struct platform_device tmu5_device = {
219 .name = "sh_tmu",
220 .id = 5,
221 .dev = {
222 .platform_data = &tmu5_platform_data,
223 },
224 .resource = tmu5_resources,
225 .num_resources = ARRAY_SIZE(tmu5_resources),
226};
227
228static struct resource rtc_resources[] = {
229 [0] = {
230 .start = 0xffe80000,
231 .end = 0xffe80000 + 0x58 - 1,
232 .flags = IORESOURCE_IO,
233 },
234 [1] = {
235
236 .start = evt2irq(0x480),
237 .flags = IORESOURCE_IRQ,
238 },
239};
240
241static struct platform_device rtc_device = {
242 .name = "sh-rtc",
243 .id = -1,
244 .num_resources = ARRAY_SIZE(rtc_resources),
245 .resource = rtc_resources,
246};
247
248
249static const struct sh_dmae_channel sh7780_dmae0_channels[] = {
250 {
251 .offset = 0,
252 .dmars = 0,
253 .dmars_bit = 0,
254 }, {
255 .offset = 0x10,
256 .dmars = 0,
257 .dmars_bit = 8,
258 }, {
259 .offset = 0x20,
260 .dmars = 4,
261 .dmars_bit = 0,
262 }, {
263 .offset = 0x30,
264 .dmars = 4,
265 .dmars_bit = 8,
266 }, {
267 .offset = 0x50,
268 .dmars = 8,
269 .dmars_bit = 0,
270 }, {
271 .offset = 0x60,
272 .dmars = 8,
273 .dmars_bit = 8,
274 }
275};
276
277static const struct sh_dmae_channel sh7780_dmae1_channels[] = {
278 {
279 .offset = 0,
280 }, {
281 .offset = 0x10,
282 }, {
283 .offset = 0x20,
284 }, {
285 .offset = 0x30,
286 }, {
287 .offset = 0x50,
288 }, {
289 .offset = 0x60,
290 }
291};
292
293static const unsigned int ts_shift[] = TS_SHIFT;
294
295static struct sh_dmae_pdata dma0_platform_data = {
296 .channel = sh7780_dmae0_channels,
297 .channel_num = ARRAY_SIZE(sh7780_dmae0_channels),
298 .ts_low_shift = CHCR_TS_LOW_SHIFT,
299 .ts_low_mask = CHCR_TS_LOW_MASK,
300 .ts_high_shift = CHCR_TS_HIGH_SHIFT,
301 .ts_high_mask = CHCR_TS_HIGH_MASK,
302 .ts_shift = ts_shift,
303 .ts_shift_num = ARRAY_SIZE(ts_shift),
304 .dmaor_init = DMAOR_INIT,
305};
306
307static struct sh_dmae_pdata dma1_platform_data = {
308 .channel = sh7780_dmae1_channels,
309 .channel_num = ARRAY_SIZE(sh7780_dmae1_channels),
310 .ts_low_shift = CHCR_TS_LOW_SHIFT,
311 .ts_low_mask = CHCR_TS_LOW_MASK,
312 .ts_high_shift = CHCR_TS_HIGH_SHIFT,
313 .ts_high_mask = CHCR_TS_HIGH_MASK,
314 .ts_shift = ts_shift,
315 .ts_shift_num = ARRAY_SIZE(ts_shift),
316 .dmaor_init = DMAOR_INIT,
317};
318
319static struct resource sh7780_dmae0_resources[] = {
320 [0] = {
321
322 .start = 0xfc808020,
323 .end = 0xfc80808f,
324 .flags = IORESOURCE_MEM,
325 },
326 [1] = {
327
328 .start = 0xfc809000,
329 .end = 0xfc80900b,
330 .flags = IORESOURCE_MEM,
331 },
332 {
333
334
335
336
337 .name = "error_irq",
338 .start = evt2irq(0x640),
339 .end = evt2irq(0x640),
340 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
341 },
342};
343
344static struct resource sh7780_dmae1_resources[] = {
345 [0] = {
346
347 .start = 0xfc818020,
348 .end = 0xfc81808f,
349 .flags = IORESOURCE_MEM,
350 },
351
352 {
353
354
355
356
357 .name = "error_irq",
358 .start = evt2irq(0x7c0),
359 .end = evt2irq(0x7c0),
360 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
361 },
362};
363
364static struct platform_device dma0_device = {
365 .name = "sh-dma-engine",
366 .id = 0,
367 .resource = sh7780_dmae0_resources,
368 .num_resources = ARRAY_SIZE(sh7780_dmae0_resources),
369 .dev = {
370 .platform_data = &dma0_platform_data,
371 },
372};
373
374static struct platform_device dma1_device = {
375 .name = "sh-dma-engine",
376 .id = 1,
377 .resource = sh7780_dmae1_resources,
378 .num_resources = ARRAY_SIZE(sh7780_dmae1_resources),
379 .dev = {
380 .platform_data = &dma1_platform_data,
381 },
382};
383
384static struct platform_device *sh7780_devices[] __initdata = {
385 &scif0_device,
386 &scif1_device,
387 &tmu0_device,
388 &tmu1_device,
389 &tmu2_device,
390 &tmu3_device,
391 &tmu4_device,
392 &tmu5_device,
393 &rtc_device,
394 &dma0_device,
395 &dma1_device,
396};
397
398static int __init sh7780_devices_setup(void)
399{
400 return platform_add_devices(sh7780_devices,
401 ARRAY_SIZE(sh7780_devices));
402}
403arch_initcall(sh7780_devices_setup);
404
405static struct platform_device *sh7780_early_devices[] __initdata = {
406 &scif0_device,
407 &scif1_device,
408 &tmu0_device,
409 &tmu1_device,
410 &tmu2_device,
411 &tmu3_device,
412 &tmu4_device,
413 &tmu5_device,
414};
415
416void __init plat_early_device_setup(void)
417{
418 if (mach_is_sh2007()) {
419 scif0_platform_data.scscr &= ~SCSCR_CKE1;
420 scif1_platform_data.scscr &= ~SCSCR_CKE1;
421 }
422
423 early_platform_add_devices(sh7780_early_devices,
424 ARRAY_SIZE(sh7780_early_devices));
425}
426
427enum {
428 UNUSED = 0,
429
430
431
432 IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
433 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
434 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
435 IRL_HHLL, IRL_HHLH, IRL_HHHL,
436
437 IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
438 RTC, WDT, TMU0, TMU1, TMU2, TMU2_TICPI,
439 HUDI, DMAC0, SCIF0, DMAC1, CMT, HAC,
440 PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD, PCIC5,
441 SCIF1, SIOF, HSPI, MMCIF, TMU3, TMU4, TMU5, SSI, FLCTL, GPIO,
442
443
444
445 TMU012, TMU345,
446};
447
448static struct intc_vect vectors[] __initdata = {
449 INTC_VECT(RTC, 0x480), INTC_VECT(RTC, 0x4a0),
450 INTC_VECT(RTC, 0x4c0),
451 INTC_VECT(WDT, 0x560),
452 INTC_VECT(TMU0, 0x580), INTC_VECT(TMU1, 0x5a0),
453 INTC_VECT(TMU2, 0x5c0), INTC_VECT(TMU2_TICPI, 0x5e0),
454 INTC_VECT(HUDI, 0x600),
455 INTC_VECT(DMAC0, 0x640), INTC_VECT(DMAC0, 0x660),
456 INTC_VECT(DMAC0, 0x680), INTC_VECT(DMAC0, 0x6a0),
457 INTC_VECT(DMAC0, 0x6c0),
458 INTC_VECT(SCIF0, 0x700), INTC_VECT(SCIF0, 0x720),
459 INTC_VECT(SCIF0, 0x740), INTC_VECT(SCIF0, 0x760),
460 INTC_VECT(DMAC0, 0x780), INTC_VECT(DMAC0, 0x7a0),
461 INTC_VECT(DMAC1, 0x7c0), INTC_VECT(DMAC1, 0x7e0),
462 INTC_VECT(CMT, 0x900), INTC_VECT(HAC, 0x980),
463 INTC_VECT(PCISERR, 0xa00), INTC_VECT(PCIINTA, 0xa20),
464 INTC_VECT(PCIINTB, 0xa40), INTC_VECT(PCIINTC, 0xa60),
465 INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIC5, 0xaa0),
466 INTC_VECT(PCIC5, 0xac0), INTC_VECT(PCIC5, 0xae0),
467 INTC_VECT(PCIC5, 0xb00), INTC_VECT(PCIC5, 0xb20),
468 INTC_VECT(SCIF1, 0xb80), INTC_VECT(SCIF1, 0xba0),
469 INTC_VECT(SCIF1, 0xbc0), INTC_VECT(SCIF1, 0xbe0),
470 INTC_VECT(SIOF, 0xc00), INTC_VECT(HSPI, 0xc80),
471 INTC_VECT(MMCIF, 0xd00), INTC_VECT(MMCIF, 0xd20),
472 INTC_VECT(MMCIF, 0xd40), INTC_VECT(MMCIF, 0xd60),
473 INTC_VECT(DMAC1, 0xd80), INTC_VECT(DMAC1, 0xda0),
474 INTC_VECT(DMAC1, 0xdc0), INTC_VECT(DMAC1, 0xde0),
475 INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20),
476 INTC_VECT(TMU5, 0xe40),
477 INTC_VECT(SSI, 0xe80),
478 INTC_VECT(FLCTL, 0xf00), INTC_VECT(FLCTL, 0xf20),
479 INTC_VECT(FLCTL, 0xf40), INTC_VECT(FLCTL, 0xf60),
480 INTC_VECT(GPIO, 0xf80), INTC_VECT(GPIO, 0xfa0),
481 INTC_VECT(GPIO, 0xfc0), INTC_VECT(GPIO, 0xfe0),
482};
483
484static struct intc_group groups[] __initdata = {
485 INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI),
486 INTC_GROUP(TMU345, TMU3, TMU4, TMU5),
487};
488
489static struct intc_mask_reg mask_registers[] __initdata = {
490 { 0xffd40038, 0xffd4003c, 32,
491 { 0, 0, 0, 0, 0, 0, GPIO, FLCTL,
492 SSI, MMCIF, HSPI, SIOF, PCIC5, PCIINTD, PCIINTC, PCIINTB,
493 PCIINTA, PCISERR, HAC, CMT, 0, 0, DMAC1, DMAC0,
494 HUDI, 0, WDT, SCIF1, SCIF0, RTC, TMU345, TMU012 } },
495};
496
497static struct intc_prio_reg prio_registers[] __initdata = {
498 { 0xffd40000, 0, 32, 8, { TMU0, TMU1,
499 TMU2, TMU2_TICPI } },
500 { 0xffd40004, 0, 32, 8, { TMU3, TMU4, TMU5, RTC } },
501 { 0xffd40008, 0, 32, 8, { SCIF0, SCIF1, WDT } },
502 { 0xffd4000c, 0, 32, 8, { HUDI, DMAC0, DMAC1 } },
503 { 0xffd40010, 0, 32, 8, { CMT, HAC,
504 PCISERR, PCIINTA, } },
505 { 0xffd40014, 0, 32, 8, { PCIINTB, PCIINTC,
506 PCIINTD, PCIC5 } },
507 { 0xffd40018, 0, 32, 8, { SIOF, HSPI, MMCIF, SSI } },
508 { 0xffd4001c, 0, 32, 8, { FLCTL, GPIO } },
509};
510
511static DECLARE_INTC_DESC(intc_desc, "sh7780", vectors, groups,
512 mask_registers, prio_registers, NULL);
513
514
515
516static struct intc_vect irq_vectors[] __initdata = {
517 INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),
518 INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300),
519 INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380),
520 INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200),
521};
522
523static struct intc_mask_reg irq_mask_registers[] __initdata = {
524 { 0xffd00044, 0xffd00064, 32,
525 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
526};
527
528static struct intc_prio_reg irq_prio_registers[] __initdata = {
529 { 0xffd00010, 0, 32, 4, { IRQ0, IRQ1, IRQ2, IRQ3,
530 IRQ4, IRQ5, IRQ6, IRQ7 } },
531};
532
533static struct intc_sense_reg irq_sense_registers[] __initdata = {
534 { 0xffd0001c, 32, 2, { IRQ0, IRQ1, IRQ2, IRQ3,
535 IRQ4, IRQ5, IRQ6, IRQ7 } },
536};
537
538static struct intc_mask_reg irq_ack_registers[] __initdata = {
539 { 0xffd00024, 0, 32,
540 { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
541};
542
543static DECLARE_INTC_DESC_ACK(intc_irq_desc, "sh7780-irq", irq_vectors,
544 NULL, irq_mask_registers, irq_prio_registers,
545 irq_sense_registers, irq_ack_registers);
546
547
548
549static struct intc_vect irl_vectors[] __initdata = {
550 INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220),
551 INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260),
552 INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0),
553 INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0),
554 INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320),
555 INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360),
556 INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0),
557 INTC_VECT(IRL_HHHL, 0x3c0),
558};
559
560static struct intc_mask_reg irl3210_mask_registers[] __initdata = {
561 { 0xffd40080, 0xffd40084, 32,
562 { IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
563 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
564 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
565 IRL_HHLL, IRL_HHLH, IRL_HHHL, } },
566};
567
568static struct intc_mask_reg irl7654_mask_registers[] __initdata = {
569 { 0xffd40080, 0xffd40084, 32,
570 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
571 IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
572 IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
573 IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
574 IRL_HHLL, IRL_HHLH, IRL_HHHL, } },
575};
576
577static DECLARE_INTC_DESC(intc_irl7654_desc, "sh7780-irl7654", irl_vectors,
578 NULL, irl7654_mask_registers, NULL, NULL);
579
580static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7780-irl3210", irl_vectors,
581 NULL, irl3210_mask_registers, NULL, NULL);
582
583#define INTC_ICR0 0xffd00000
584#define INTC_INTMSK0 0xffd00044
585#define INTC_INTMSK1 0xffd00048
586#define INTC_INTMSK2 0xffd40080
587#define INTC_INTMSKCLR1 0xffd00068
588#define INTC_INTMSKCLR2 0xffd40084
589
590void __init plat_irq_setup(void)
591{
592
593 __raw_writel(0xff000000, INTC_INTMSK0);
594
595
596 __raw_writel(0xc0000000, INTC_INTMSK1);
597 __raw_writel(0xfffefffe, INTC_INTMSK2);
598
599
600 __raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
601
602
603 __raw_writel(__raw_readl(INTC_ICR0) | 0x00200000, INTC_ICR0);
604
605 register_intc_controller(&intc_desc);
606}
607
608void __init plat_irq_setup_pins(int mode)
609{
610 switch (mode) {
611 case IRQ_MODE_IRQ:
612
613 __raw_writel(__raw_readl(INTC_ICR0) | 0x00c00000, INTC_ICR0);
614 register_intc_controller(&intc_irq_desc);
615 break;
616 case IRQ_MODE_IRL7654:
617
618 __raw_writel(0x40000000, INTC_INTMSKCLR1);
619 __raw_writel(0x0000fffe, INTC_INTMSKCLR2);
620 break;
621 case IRQ_MODE_IRL3210:
622
623 __raw_writel(0x80000000, INTC_INTMSKCLR1);
624 __raw_writel(0xfffe0000, INTC_INTMSKCLR2);
625 break;
626 case IRQ_MODE_IRL7654_MASK:
627
628 __raw_writel(0x40000000, INTC_INTMSKCLR1);
629 register_intc_controller(&intc_irl7654_desc);
630 break;
631 case IRQ_MODE_IRL3210_MASK:
632
633 __raw_writel(0x80000000, INTC_INTMSKCLR1);
634 register_intc_controller(&intc_irl3210_desc);
635 break;
636 default:
637 BUG();
638 }
639}
640