This source file includes following definitions.
- dns323_pci_map_irq
- dns323_pci_init
- dns323_parse_hex_nibble
- dns323_parse_hex_byte
- dns323_read_mac_addr
- dns323a_power_off
- dns323b_power_off
- dns323c_power_off
- dns323c_phy_fixup
- dns323_identify_rev
- dns323_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 #include <linux/gpio.h>
17 #include <linux/kernel.h>
18 #include <linux/init.h>
19 #include <linux/delay.h>
20 #include <linux/platform_device.h>
21 #include <linux/pci.h>
22 #include <linux/irq.h>
23 #include <linux/mtd/physmap.h>
24 #include <linux/mv643xx_eth.h>
25 #include <linux/leds.h>
26 #include <linux/gpio_keys.h>
27 #include <linux/input.h>
28 #include <linux/i2c.h>
29 #include <linux/ata_platform.h>
30 #include <linux/phy.h>
31 #include <linux/marvell_phy.h>
32 #include <asm/mach-types.h>
33 #include <asm/mach/arch.h>
34 #include <asm/mach/pci.h>
35 #include <asm/system_info.h>
36 #include <plat/orion-gpio.h>
37 #include "orion5x.h"
38 #include "common.h"
39 #include "mpp.h"
40
41
42 #define DNS323_GPIO_LED_RIGHT_AMBER 1
43 #define DNS323_GPIO_LED_LEFT_AMBER 2
44 #define DNS323_GPIO_SYSTEM_UP 3
45 #define DNS323_GPIO_LED_POWER1 4
46 #define DNS323_GPIO_LED_POWER2 5
47 #define DNS323_GPIO_OVERTEMP 6
48 #define DNS323_GPIO_RTC 7
49 #define DNS323_GPIO_POWER_OFF 8
50 #define DNS323_GPIO_KEY_POWER 9
51 #define DNS323_GPIO_KEY_RESET 10
52
53
54 #define DNS323C_GPIO_KEY_POWER 1
55 #define DNS323C_GPIO_POWER_OFF 2
56 #define DNS323C_GPIO_LED_RIGHT_AMBER 8
57 #define DNS323C_GPIO_LED_LEFT_AMBER 9
58 #define DNS323C_GPIO_LED_POWER 17
59 #define DNS323C_GPIO_FAN_BIT1 18
60 #define DNS323C_GPIO_FAN_BIT0 19
61
62
63 enum {
64 DNS323_REV_A1,
65 DNS323_REV_B1,
66 DNS323_REV_C1,
67 };
68
69
70
71
72
73
74 static int __init dns323_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
75 {
76 int irq;
77
78
79
80
81 irq = orion5x_pci_map_irq(dev, slot, pin);
82 if (irq != -1)
83 return irq;
84
85 return -1;
86 }
87
88 static struct hw_pci dns323_pci __initdata = {
89 .nr_controllers = 2,
90 .setup = orion5x_pci_sys_setup,
91 .scan = orion5x_pci_sys_scan_bus,
92 .map_irq = dns323_pci_map_irq,
93 };
94
95 static int __init dns323_pci_init(void)
96 {
97
98
99
100 if (machine_is_dns323() && system_rev == DNS323_REV_A1)
101 pci_common_init(&dns323_pci);
102
103 return 0;
104 }
105
106 subsys_initcall(dns323_pci_init);
107
108
109
110
111
112
113
114
115
116
117
118
119 #define DNS323_NOR_BOOT_BASE 0xf4000000
120 #define DNS323_NOR_BOOT_SIZE SZ_8M
121
122 static struct mtd_partition dns323_partitions[] = {
123 {
124 .name = "MTD1",
125 .size = 0x00010000,
126 .offset = 0,
127 }, {
128 .name = "MTD2",
129 .size = 0x00010000,
130 .offset = 0x00010000,
131 }, {
132 .name = "Linux Kernel",
133 .size = 0x00180000,
134 .offset = 0x00020000,
135 }, {
136 .name = "File System",
137 .size = 0x00630000,
138 .offset = 0x001A0000,
139 }, {
140 .name = "u-boot",
141 .size = 0x00030000,
142 .offset = 0x007d0000,
143 },
144 };
145
146 static struct physmap_flash_data dns323_nor_flash_data = {
147 .width = 1,
148 .parts = dns323_partitions,
149 .nr_parts = ARRAY_SIZE(dns323_partitions)
150 };
151
152 static struct resource dns323_nor_flash_resource = {
153 .flags = IORESOURCE_MEM,
154 .start = DNS323_NOR_BOOT_BASE,
155 .end = DNS323_NOR_BOOT_BASE + DNS323_NOR_BOOT_SIZE - 1,
156 };
157
158 static struct platform_device dns323_nor_flash = {
159 .name = "physmap-flash",
160 .id = 0,
161 .dev = {
162 .platform_data = &dns323_nor_flash_data,
163 },
164 .resource = &dns323_nor_flash_resource,
165 .num_resources = 1,
166 };
167
168
169
170
171
172 static struct mv643xx_eth_platform_data dns323_eth_data = {
173 .phy_addr = MV643XX_ETH_PHY_ADDR(8),
174 };
175
176
177
178
179 static int __init dns323_parse_hex_nibble(char n)
180 {
181 if (n >= '0' && n <= '9')
182 return n - '0';
183
184 if (n >= 'A' && n <= 'F')
185 return n - 'A' + 10;
186
187 if (n >= 'a' && n <= 'f')
188 return n - 'a' + 10;
189
190 return -1;
191 }
192
193 static int __init dns323_parse_hex_byte(const char *b)
194 {
195 int hi;
196 int lo;
197
198 hi = dns323_parse_hex_nibble(b[0]);
199 lo = dns323_parse_hex_nibble(b[1]);
200
201 if (hi < 0 || lo < 0)
202 return -1;
203
204 return (hi << 4) | lo;
205 }
206
207 static int __init dns323_read_mac_addr(void)
208 {
209 u_int8_t addr[6];
210 int i;
211 char *mac_page;
212
213
214
215
216 mac_page = ioremap(DNS323_NOR_BOOT_BASE + 0x7d0000 + 196480, 1024);
217 if (!mac_page)
218 return -ENOMEM;
219
220
221 for (i = 0; i < 5; i++) {
222 if (*(mac_page + (i * 3) + 2) != ':') {
223 goto error_fail;
224 }
225 }
226
227 for (i = 0; i < 6; i++) {
228 int byte;
229
230 byte = dns323_parse_hex_byte(mac_page + (i * 3));
231 if (byte < 0) {
232 goto error_fail;
233 }
234
235 addr[i] = byte;
236 }
237
238 iounmap(mac_page);
239 printk("DNS-323: Found ethernet MAC address: %pM\n", addr);
240
241 memcpy(dns323_eth_data.mac_addr, addr, 6);
242
243 return 0;
244
245 error_fail:
246 iounmap(mac_page);
247 return -EINVAL;
248 }
249
250
251
252
253
254 static struct gpio_led dns323ab_leds[] = {
255 {
256 .name = "power:blue",
257 .gpio = DNS323_GPIO_LED_POWER2,
258 .default_trigger = "default-on",
259 }, {
260 .name = "right:amber",
261 .gpio = DNS323_GPIO_LED_RIGHT_AMBER,
262 .active_low = 1,
263 }, {
264 .name = "left:amber",
265 .gpio = DNS323_GPIO_LED_LEFT_AMBER,
266 .active_low = 1,
267 },
268 };
269
270
271 static struct gpio_led dns323c_leds[] = {
272 {
273 .name = "power:blue",
274 .gpio = DNS323C_GPIO_LED_POWER,
275 .default_trigger = "timer",
276 .active_low = 1,
277 }, {
278 .name = "right:amber",
279 .gpio = DNS323C_GPIO_LED_RIGHT_AMBER,
280 .active_low = 1,
281 }, {
282 .name = "left:amber",
283 .gpio = DNS323C_GPIO_LED_LEFT_AMBER,
284 .active_low = 1,
285 },
286 };
287
288
289 static struct gpio_led_platform_data dns323ab_led_data = {
290 .num_leds = ARRAY_SIZE(dns323ab_leds),
291 .leds = dns323ab_leds,
292 .gpio_blink_set = orion_gpio_led_blink_set,
293 };
294
295 static struct gpio_led_platform_data dns323c_led_data = {
296 .num_leds = ARRAY_SIZE(dns323c_leds),
297 .leds = dns323c_leds,
298 .gpio_blink_set = orion_gpio_led_blink_set,
299 };
300
301 static struct platform_device dns323_gpio_leds = {
302 .name = "leds-gpio",
303 .id = -1,
304 .dev = {
305 .platform_data = &dns323ab_led_data,
306 },
307 };
308
309
310
311
312
313 static struct gpio_keys_button dns323ab_buttons[] = {
314 {
315 .code = KEY_RESTART,
316 .gpio = DNS323_GPIO_KEY_RESET,
317 .desc = "Reset Button",
318 .active_low = 1,
319 }, {
320 .code = KEY_POWER,
321 .gpio = DNS323_GPIO_KEY_POWER,
322 .desc = "Power Button",
323 .active_low = 1,
324 },
325 };
326
327 static struct gpio_keys_platform_data dns323ab_button_data = {
328 .buttons = dns323ab_buttons,
329 .nbuttons = ARRAY_SIZE(dns323ab_buttons),
330 };
331
332 static struct gpio_keys_button dns323c_buttons[] = {
333 {
334 .code = KEY_POWER,
335 .gpio = DNS323C_GPIO_KEY_POWER,
336 .desc = "Power Button",
337 .active_low = 1,
338 },
339 };
340
341 static struct gpio_keys_platform_data dns323c_button_data = {
342 .buttons = dns323c_buttons,
343 .nbuttons = ARRAY_SIZE(dns323c_buttons),
344 };
345
346 static struct platform_device dns323_button_device = {
347 .name = "gpio-keys",
348 .id = -1,
349 .num_resources = 0,
350 .dev = {
351 .platform_data = &dns323ab_button_data,
352 },
353 };
354
355
356
357
358 static struct mv_sata_platform_data dns323_sata_data = {
359 .n_ports = 2,
360 };
361
362
363
364
365 static unsigned int dns323a_mpp_modes[] __initdata = {
366 MPP0_PCIE_RST_OUTn,
367 MPP1_GPIO,
368 MPP2_GPIO,
369 MPP3_UNUSED,
370 MPP4_GPIO,
371 MPP5_GPIO,
372 MPP6_GPIO,
373 MPP7_GPIO,
374 MPP8_GPIO,
375 MPP9_GPIO,
376 MPP10_GPIO,
377 MPP11_UNUSED,
378 MPP12_UNUSED,
379 MPP13_UNUSED,
380 MPP14_UNUSED,
381 MPP15_UNUSED,
382 MPP16_UNUSED,
383 MPP17_UNUSED,
384 MPP18_UNUSED,
385 MPP19_UNUSED,
386 0,
387 };
388
389 static unsigned int dns323b_mpp_modes[] __initdata = {
390 MPP0_UNUSED,
391 MPP1_GPIO,
392 MPP2_GPIO,
393 MPP3_GPIO,
394 MPP4_GPIO,
395 MPP5_GPIO,
396 MPP6_GPIO,
397 MPP7_GPIO,
398 MPP8_GPIO,
399 MPP9_GPIO,
400 MPP10_GPIO,
401 MPP11_UNUSED,
402 MPP12_SATA_LED,
403 MPP13_SATA_LED,
404 MPP14_SATA_LED,
405 MPP15_SATA_LED,
406 MPP16_UNUSED,
407 MPP17_UNUSED,
408 MPP18_UNUSED,
409 MPP19_UNUSED,
410 0,
411 };
412
413 static unsigned int dns323c_mpp_modes[] __initdata = {
414 MPP0_GPIO,
415 MPP1_GPIO,
416 MPP2_GPIO,
417 MPP3_UNUSED,
418 MPP4_UNUSED,
419 MPP5_UNUSED,
420 MPP6_UNUSED,
421 MPP7_UNUSED,
422 MPP8_GPIO,
423 MPP9_GPIO,
424 MPP10_GPIO,
425 MPP11_UNUSED,
426 MPP12_SATA_LED,
427 MPP13_SATA_LED,
428 MPP14_SATA_LED,
429 MPP15_SATA_LED,
430 MPP16_UNUSED,
431 MPP17_GPIO,
432 MPP18_GPIO,
433 MPP19_GPIO,
434 0,
435 };
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463 static struct i2c_board_info __initdata dns323ab_i2c_devices[] = {
464 {
465 I2C_BOARD_INFO("g760a", 0x3e),
466 }, {
467 I2C_BOARD_INFO("lm75", 0x48),
468 }, {
469 I2C_BOARD_INFO("m41t80", 0x68),
470 },
471 };
472
473
474
475
476
477
478
479
480 static struct i2c_board_info __initdata dns323c_i2c_devices[] = {
481 {
482 I2C_BOARD_INFO("lm75", 0x48),
483 }, {
484 I2C_BOARD_INFO("m41t80", 0x68),
485 },
486 };
487
488
489 static void dns323a_power_off(void)
490 {
491 pr_info("DNS-323: Triggering power-off...\n");
492 gpio_set_value(DNS323_GPIO_POWER_OFF, 1);
493 }
494
495
496 static void dns323b_power_off(void)
497 {
498 pr_info("DNS-323: Triggering power-off...\n");
499
500 gpio_set_value(DNS323_GPIO_POWER_OFF, 1);
501 mdelay(100);
502 gpio_set_value(DNS323_GPIO_POWER_OFF, 0);
503 }
504
505
506 static void dns323c_power_off(void)
507 {
508 pr_info("DNS-323: Triggering power-off...\n");
509 gpio_set_value(DNS323C_GPIO_POWER_OFF, 1);
510 }
511
512 static int dns323c_phy_fixup(struct phy_device *phy)
513 {
514 phy->dev_flags |= MARVELL_PHY_M1118_DNS323_LEDS;
515
516 return 0;
517 }
518
519 static int __init dns323_identify_rev(void)
520 {
521 u32 dev, rev, i, reg;
522
523 pr_debug("DNS-323: Identifying board ... \n");
524
525
526 orion5x_pcie_id(&dev, &rev);
527 if (dev == MV88F5181_DEV_ID) {
528 pr_debug("DNS-323: 5181 found, board is A1\n");
529 return DNS323_REV_A1;
530 }
531 pr_debug("DNS-323: 5182 found, board is B1 or C1, checking PHY...\n");
532
533
534
535
536
537
538
539 #define ETH_SMI_REG (ORION5X_ETH_VIRT_BASE + 0x2000 + 0x004)
540 #define SMI_BUSY 0x10000000
541 #define SMI_READ_VALID 0x08000000
542 #define SMI_OPCODE_READ 0x04000000
543 #define SMI_OPCODE_WRITE 0x00000000
544
545 for (i = 0; i < 1000; i++) {
546 reg = readl(ETH_SMI_REG);
547 if (!(reg & SMI_BUSY))
548 break;
549 }
550 if (i >= 1000) {
551 pr_warn("DNS-323: Timeout accessing PHY, assuming rev B1\n");
552 return DNS323_REV_B1;
553 }
554 writel((3 << 21) |
555 (8 << 16) |
556 SMI_OPCODE_READ, ETH_SMI_REG);
557 for (i = 0; i < 1000; i++) {
558 reg = readl(ETH_SMI_REG);
559 if (reg & SMI_READ_VALID)
560 break;
561 }
562 if (i >= 1000) {
563 pr_warn("DNS-323: Timeout reading PHY, assuming rev B1\n");
564 return DNS323_REV_B1;
565 }
566 pr_debug("DNS-323: Ethernet PHY ID 0x%x\n", reg & 0xffff);
567
568
569
570
571
572 switch(reg & 0xfff0) {
573 case 0x0cc0:
574 return DNS323_REV_B1;
575 case 0x0e10:
576 return DNS323_REV_C1;
577 default:
578 pr_warn("DNS-323: Unknown PHY ID 0x%04x, assuming rev B1\n",
579 reg & 0xffff);
580 }
581 return DNS323_REV_B1;
582 }
583
584 static void __init dns323_init(void)
585 {
586
587 orion5x_init();
588
589
590 system_rev = dns323_identify_rev();
591 pr_info("DNS-323: Identified HW revision %c1\n", 'A' + system_rev);
592
593
594
595
596 switch(system_rev) {
597 case DNS323_REV_A1:
598 orion5x_mpp_conf(dns323a_mpp_modes);
599 writel(0, MPP_DEV_CTRL);
600 break;
601 case DNS323_REV_B1:
602 orion5x_mpp_conf(dns323b_mpp_modes);
603 break;
604 case DNS323_REV_C1:
605 orion5x_mpp_conf(dns323c_mpp_modes);
606 break;
607 }
608
609
610
611
612 mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
613 ORION_MBUS_DEVBUS_BOOT_ATTR,
614 DNS323_NOR_BOOT_BASE,
615 DNS323_NOR_BOOT_SIZE);
616 platform_device_register(&dns323_nor_flash);
617
618
619 switch(system_rev) {
620 case DNS323_REV_A1:
621
622
623
624 dns323ab_leds[0].active_low = 1;
625 gpio_request(DNS323_GPIO_LED_POWER1, "Power Led Enable");
626 gpio_direction_output(DNS323_GPIO_LED_POWER1, 0);
627
628 case DNS323_REV_B1:
629 i2c_register_board_info(0, dns323ab_i2c_devices,
630 ARRAY_SIZE(dns323ab_i2c_devices));
631 break;
632 case DNS323_REV_C1:
633
634 dns323_gpio_leds.dev.platform_data = &dns323c_led_data;
635 dns323_button_device.dev.platform_data = &dns323c_button_data;
636
637
638 i2c_register_board_info(0, dns323c_i2c_devices,
639 ARRAY_SIZE(dns323c_i2c_devices));
640 platform_device_register_simple("dns323c-fan", 0, NULL, 0);
641
642
643 if (!IS_BUILTIN(CONFIG_PHYLIB))
644 break;
645 phy_register_fixup_for_uid(MARVELL_PHY_ID_88E1118,
646 MARVELL_PHY_ID_MASK,
647 dns323c_phy_fixup);
648 }
649
650 platform_device_register(&dns323_gpio_leds);
651 platform_device_register(&dns323_button_device);
652
653
654
655
656 if (dns323_read_mac_addr() < 0)
657 printk("DNS-323: Failed to read MAC address\n");
658 orion5x_ehci0_init();
659 orion5x_eth_init(&dns323_eth_data);
660 orion5x_i2c_init();
661 orion5x_uart0_init();
662
663
664 switch(system_rev) {
665 case DNS323_REV_A1:
666
667 if (gpio_request(DNS323_GPIO_POWER_OFF, "POWEROFF") != 0 ||
668 gpio_direction_output(DNS323_GPIO_POWER_OFF, 0) != 0)
669 pr_err("DNS-323: failed to setup power-off GPIO\n");
670 pm_power_off = dns323a_power_off;
671 break;
672 case DNS323_REV_B1:
673
674 orion5x_sata_init(&dns323_sata_data);
675
676
677
678
679
680 if (gpio_request(DNS323_GPIO_SYSTEM_UP, "SYS_READY") == 0)
681 gpio_direction_output(DNS323_GPIO_SYSTEM_UP, 1);
682
683
684 if (gpio_request(DNS323_GPIO_POWER_OFF, "POWEROFF") != 0 ||
685 gpio_direction_output(DNS323_GPIO_POWER_OFF, 0) != 0)
686 pr_err("DNS-323: failed to setup power-off GPIO\n");
687 pm_power_off = dns323b_power_off;
688 break;
689 case DNS323_REV_C1:
690
691 orion5x_sata_init(&dns323_sata_data);
692
693
694 if (gpio_request(DNS323C_GPIO_POWER_OFF, "POWEROFF") != 0 ||
695 gpio_direction_output(DNS323C_GPIO_POWER_OFF, 0) != 0)
696 pr_err("DNS-323: failed to setup power-off GPIO\n");
697 pm_power_off = dns323c_power_off;
698
699
700
701
702
703
704
705
706
707 writel(0x5, ORION5X_SATA_VIRT_BASE + 0x2c);
708 break;
709 }
710 }
711
712
713 MACHINE_START(DNS323, "D-Link DNS-323")
714
715 .atag_offset = 0x100,
716 .nr_irqs = ORION5X_NR_IRQS,
717 .init_machine = dns323_init,
718 .map_io = orion5x_map_io,
719 .init_early = orion5x_init_early,
720 .init_irq = orion5x_init_irq,
721 .init_time = orion5x_timer_init,
722 .fixup = tag_fixup_mem32,
723 .restart = orion5x_restart,
724 MACHINE_END