011-add_preliminary_board_support.patch 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539
  1. From b95a2bbbcae5423e5404a7b3c8dd1685e1786f13 Mon Sep 17 00:00:00 2001
  2. From: Maxime Bizon <[email protected]>
  3. Date: Wed, 17 Sep 2008 15:55:36 +0200
  4. Subject: [PATCH] [MIPS] BCM63XX: Add preliminary board support.
  5. Signed-off-by: Maxime Bizon <[email protected]>
  6. ---
  7. arch/mips/bcm63xx/Kconfig | 2 +
  8. arch/mips/bcm63xx/Makefile | 2 +
  9. arch/mips/bcm63xx/boards/Kconfig | 10 +
  10. arch/mips/bcm63xx/boards/Makefile | 1 +
  11. arch/mips/bcm63xx/boards/board_bcm963xx.c | 322 ++++++++++++++++++++++++
  12. arch/mips/bcm63xx/prom.c | 4 +
  13. arch/mips/bcm63xx/setup.c | 16 +-
  14. include/asm-mips/mach-bcm63xx/bcm63xx_board.h | 12 +
  15. include/asm-mips/mach-bcm63xx/board_bcm963xx.h | 50 ++++
  16. 9 files changed, 417 insertions(+), 2 deletions(-)
  17. create mode 100644 arch/mips/bcm63xx/boards/Kconfig
  18. create mode 100644 arch/mips/bcm63xx/boards/Makefile
  19. create mode 100644 arch/mips/bcm63xx/boards/board_bcm963xx.c
  20. create mode 100644 include/asm-mips/mach-bcm63xx/bcm63xx_board.h
  21. create mode 100644 include/asm-mips/mach-bcm63xx/board_bcm963xx.h
  22. diff --git a/arch/mips/bcm63xx/Kconfig b/arch/mips/bcm63xx/Kconfig
  23. index be120f7..8c192e7 100644
  24. --- a/arch/mips/bcm63xx/Kconfig
  25. +++ b/arch/mips/bcm63xx/Kconfig
  26. @@ -17,3 +17,5 @@ config BCM63XX_CPU_6358
  27. select USB_ARCH_HAS_EHCI
  28. select USB_EHCI_BIG_ENDIAN_MMIO
  29. endmenu
  30. +
  31. +source "arch/mips/bcm63xx/boards/Kconfig"
  32. diff --git a/arch/mips/bcm63xx/Makefile b/arch/mips/bcm63xx/Makefile
  33. index 5358093..10462ae 100644
  34. --- a/arch/mips/bcm63xx/Makefile
  35. +++ b/arch/mips/bcm63xx/Makefile
  36. @@ -5,3 +5,5 @@ obj-y += dev-usb-ohci.o
  37. obj-y += dev-usb-ehci.o
  38. obj-y += dev-enet.o
  39. obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
  40. +
  41. +obj-y += boards/
  42. diff --git a/arch/mips/bcm63xx/boards/Kconfig b/arch/mips/bcm63xx/boards/Kconfig
  43. new file mode 100644
  44. index 0000000..da5eeaa
  45. --- /dev/null
  46. +++ b/arch/mips/bcm63xx/boards/Kconfig
  47. @@ -0,0 +1,10 @@
  48. +choice
  49. + prompt "Board support"
  50. + depends on BCM63XX
  51. + default BOARD_BCM963XX
  52. +
  53. +config BOARD_BCM963XX
  54. + bool "Generic Broadcom 963xx boards"
  55. + help
  56. +
  57. +endchoice
  58. diff --git a/arch/mips/bcm63xx/boards/Makefile b/arch/mips/bcm63xx/boards/Makefile
  59. new file mode 100644
  60. index 0000000..af07c1a
  61. --- /dev/null
  62. +++ b/arch/mips/bcm63xx/boards/Makefile
  63. @@ -0,0 +1 @@
  64. +obj-$(CONFIG_BOARD_BCM963XX) += board_bcm963xx.o
  65. diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c
  66. new file mode 100644
  67. index 0000000..de52a2a
  68. --- /dev/null
  69. +++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
  70. @@ -0,0 +1,322 @@
  71. +/*
  72. + * This file is subject to the terms and conditions of the GNU General Public
  73. + * License. See the file "COPYING" in the main directory of this archive
  74. + * for more details.
  75. + *
  76. + * Copyright (C) 2008 Maxime Bizon <[email protected]>
  77. + */
  78. +
  79. +#include <linux/init.h>
  80. +#include <linux/kernel.h>
  81. +#include <linux/string.h>
  82. +#include <linux/platform_device.h>
  83. +#include <linux/mtd/mtd.h>
  84. +#include <linux/mtd/partitions.h>
  85. +#include <linux/mtd/physmap.h>
  86. +#include <asm/addrspace.h>
  87. +#include <bcm63xx_board.h>
  88. +#include <bcm63xx_cpu.h>
  89. +#include <bcm63xx_regs.h>
  90. +#include <bcm63xx_io.h>
  91. +#include <bcm63xx_board.h>
  92. +#include <bcm63xx_dev_pci.h>
  93. +#include <bcm63xx_dev_uart.h>
  94. +#include <bcm63xx_dev_enet.h>
  95. +#include <bcm63xx_dev_pcmcia.h>
  96. +#include <bcm63xx_dev_usb_ohci.h>
  97. +#include <bcm63xx_dev_usb_ehci.h>
  98. +#include <board_bcm963xx.h>
  99. +
  100. +#define PFX "board_bcm963xx: "
  101. +
  102. +static struct bcm963xx_nvram nvram;
  103. +static unsigned int mac_addr_used = 0;
  104. +static struct board_info board;
  105. +
  106. +/*
  107. + * known 6348 boards
  108. + */
  109. +#ifdef CONFIG_BCM63XX_CPU_6348
  110. +static struct board_info __initdata board_96348r = {
  111. + .name = "96348R",
  112. + .expected_cpu_id = 0x6348,
  113. +
  114. + .has_enet0 = 1,
  115. + .has_pci = 1,
  116. +
  117. + .enet0 = {
  118. + .has_phy = 1,
  119. + .use_internal_phy = 1,
  120. + },
  121. +};
  122. +
  123. +static struct board_info __initdata board_96348gw = {
  124. + .name = "96348GW",
  125. + .expected_cpu_id = 0x6348,
  126. +
  127. + .has_enet0 = 1,
  128. + .has_pci = 1,
  129. +
  130. + .enet0 = {
  131. + .has_phy = 1,
  132. + .use_internal_phy = 1,
  133. + },
  134. +};
  135. +#endif
  136. +
  137. +/*
  138. + * known 6358 boards
  139. + */
  140. +#ifdef CONFIG_BCM63XX_CPU_6358
  141. +static struct board_info __initdata board_96358vw2 = {
  142. + .name = "96358VW2",
  143. + .expected_cpu_id = 0x6358,
  144. +
  145. + .has_enet0 = 1,
  146. + .has_enet1 = 1,
  147. + .has_pci = 1,
  148. +
  149. + .enet0 = {
  150. + .has_phy = 1,
  151. + .use_internal_phy = 1,
  152. + },
  153. +
  154. + .enet1 = {
  155. + .force_speed_100 = 1,
  156. + .force_duplex_full = 1,
  157. + },
  158. +
  159. +
  160. + .has_ohci0 = 1,
  161. + .has_pccard = 1,
  162. + .has_ehci0 = 1,
  163. +};
  164. +#endif
  165. +
  166. +/*
  167. + * all boards
  168. + */
  169. +static const struct board_info __initdata *bcm963xx_boards[] = {
  170. +#ifdef CONFIG_BCM63XX_CPU_6348
  171. + &board_96348r,
  172. + &board_96348gw,
  173. +#endif
  174. +
  175. +#ifdef CONFIG_BCM63XX_CPU_6358
  176. + &board_96358vw2,
  177. +#endif
  178. +};
  179. +
  180. +/*
  181. + * early init callback, read nvram data from flash and checksum it
  182. + */
  183. +void __init board_prom_init(void)
  184. +{
  185. + unsigned int check_len, i;
  186. + u8 *boot_addr, *cfe, *p;
  187. + char cfe_version[32];
  188. + u32 val;
  189. +
  190. + /* read base address of boot chip select (0) */
  191. + val = bcm_mpi_readl(MPI_CSBASE_REG(0));
  192. + val &= MPI_CSBASE_BASE_MASK;
  193. + boot_addr = (u8 *)KSEG1ADDR(val);
  194. +
  195. + /* dump cfe version */
  196. + cfe = boot_addr + BCM963XX_CFE_VERSION_OFFSET;
  197. + if (!memcmp(cfe, "cfe-v", 5))
  198. + snprintf(cfe_version, sizeof(cfe_version), "%u.%u.%u-%u.%u",
  199. + cfe[5], cfe[6], cfe[7], cfe[8], cfe[9]);
  200. + else
  201. + strcpy(cfe_version, "unknown");
  202. + printk(KERN_INFO PFX "CFE version: %s\n", cfe_version);
  203. +
  204. + /* extract nvram data */
  205. + memcpy(&nvram, boot_addr + BCM963XX_NVRAM_OFFSET, sizeof(nvram));
  206. +
  207. + /* check checksum before using data */
  208. + if (nvram.version <= 4)
  209. + check_len = offsetof(struct bcm963xx_nvram, checksum_old);
  210. + else
  211. + check_len = sizeof(nvram);
  212. + val = 0;
  213. + p = (u8 *)&nvram;
  214. + while (check_len--)
  215. + val += *p;
  216. + if (val) {
  217. + printk(KERN_ERR PFX "invalid nvram checksum\n");
  218. + return;
  219. + }
  220. +
  221. + /* find board by name */
  222. + for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) {
  223. + if (strncmp(nvram.name, bcm963xx_boards[i]->name,
  224. + sizeof(nvram.name)))
  225. + continue;
  226. + /* copy, board desc array is marked initdata */
  227. + memcpy(&board, bcm963xx_boards[i], sizeof(board));
  228. + break;
  229. + }
  230. +
  231. + /* bail out if board is not found, will complain later */
  232. + if (!board.name)
  233. + return;
  234. +
  235. + /* setup pin multiplexing depending on board enabled device,
  236. + * this has to be done this early since PCI init is done
  237. + * inside arch_initcall */
  238. + val = 0;
  239. +
  240. + if (board.has_pci) {
  241. + bcm63xx_pci_enabled = 1;
  242. + if (BCMCPU_IS_6348())
  243. + val |= GPIO_MODE_6348_G2_PCI;
  244. + }
  245. +
  246. + if (board.has_pccard) {
  247. + if (BCMCPU_IS_6348())
  248. + val |= GPIO_MODE_6348_G1_MII_PCCARD;
  249. + }
  250. +
  251. + if (board.has_enet0 && !board.enet0.use_internal_phy) {
  252. + if (BCMCPU_IS_6348())
  253. + val |= GPIO_MODE_6348_G3_EXT_MII |
  254. + GPIO_MODE_6348_G0_EXT_MII;
  255. + }
  256. +
  257. + if (board.has_enet1 && !board.enet1.use_internal_phy) {
  258. + if (BCMCPU_IS_6348())
  259. + val |= GPIO_MODE_6348_G3_EXT_MII |
  260. + GPIO_MODE_6348_G0_EXT_MII;
  261. + }
  262. +
  263. + bcm_gpio_writel(val, GPIO_MODE_REG);
  264. +}
  265. +
  266. +/*
  267. + * second stage init callback, good time to panic if we couldn't
  268. + * identify on which board we're running since early printk is working
  269. + */
  270. +void __init board_setup(void)
  271. +{
  272. + if (!board.name)
  273. + panic("unable to detect bcm963xx board");
  274. + printk(KERN_INFO PFX "board name: %s\n", board.name);
  275. +
  276. + /* make sure we're running on expected cpu */
  277. + if (bcm63xx_get_cpu_id() != board.expected_cpu_id)
  278. + panic("unexpected CPU for bcm963xx board");
  279. +}
  280. +
  281. +/*
  282. + * return board name for /proc/cpuinfo
  283. + */
  284. +const char *board_get_name(void)
  285. +{
  286. + return board.name;
  287. +}
  288. +
  289. +/*
  290. + * register & return a new board mac address
  291. + */
  292. +static int board_get_mac_address(u8 *mac)
  293. +{
  294. + u8 *p;
  295. + int count;
  296. +
  297. + if (mac_addr_used >= nvram.mac_addr_count) {
  298. + printk(KERN_ERR PFX "not enough mac address\n");
  299. + return -ENODEV;
  300. + }
  301. +
  302. + memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
  303. + p = mac + ETH_ALEN - 1;
  304. + count = mac_addr_used;
  305. +
  306. + while (count--) {
  307. + do {
  308. + (*p)++;
  309. + if (*p != 0)
  310. + break;
  311. + p--;
  312. + } while (p != mac);
  313. + }
  314. +
  315. + if (p == mac) {
  316. + printk(KERN_ERR PFX "unable to fetch mac address\n");
  317. + return -ENODEV;
  318. + }
  319. +
  320. + mac_addr_used++;
  321. + return 0;
  322. +}
  323. +
  324. +static struct mtd_partition mtd_partitions[] = {
  325. + {
  326. + .name = "cfe",
  327. + .offset = 0x0,
  328. + .size = 0x40000,
  329. + }
  330. +};
  331. +
  332. +static struct physmap_flash_data flash_data = {
  333. + .width = 2,
  334. + .nr_parts = ARRAY_SIZE(mtd_partitions),
  335. + .parts = mtd_partitions,
  336. +};
  337. +
  338. +static struct resource mtd_resources[] = {
  339. + {
  340. + .start = 0, /* filled at runtime */
  341. + .end = 0, /* filled at runtime */
  342. + .flags = IORESOURCE_MEM,
  343. + }
  344. +};
  345. +
  346. +static struct platform_device mtd_dev = {
  347. + .name = "physmap-flash",
  348. + .resource = mtd_resources,
  349. + .num_resources = ARRAY_SIZE(mtd_resources),
  350. + .dev = {
  351. + .platform_data = &flash_data,
  352. + },
  353. +};
  354. +
  355. +/*
  356. + * third stage init callback, register all board devices.
  357. + */
  358. +int __init board_register_devices(void)
  359. +{
  360. + u32 val;
  361. +
  362. + bcm63xx_uart_register();
  363. +
  364. + if (board.has_pccard)
  365. + bcm63xx_pcmcia_register();
  366. +
  367. + if (board.has_enet0 &&
  368. + !board_get_mac_address(board.enet0.mac_addr))
  369. + bcm63xx_enet_register(0, &board.enet0);
  370. +
  371. + if (board.has_enet1 &&
  372. + !board_get_mac_address(board.enet1.mac_addr))
  373. + bcm63xx_enet_register(1, &board.enet1);
  374. +
  375. + if (board.has_ohci0)
  376. + bcm63xx_ohci_register();
  377. +
  378. + if (board.has_ehci0)
  379. + bcm63xx_ehci_register();
  380. +
  381. +
  382. + /* read base address of boot chip select (0) */
  383. + val = bcm_mpi_readl(MPI_CSBASE_REG(0));
  384. + val &= MPI_CSBASE_BASE_MASK;
  385. + mtd_resources[0].start = val;
  386. + mtd_resources[0].end = 0x1FFFFFFF;
  387. +
  388. + platform_device_register(&mtd_dev);
  389. +
  390. + return 0;
  391. +}
  392. +
  393. diff --git a/arch/mips/bcm63xx/prom.c b/arch/mips/bcm63xx/prom.c
  394. index f0b49e8..d97ceed 100644
  395. --- a/arch/mips/bcm63xx/prom.c
  396. +++ b/arch/mips/bcm63xx/prom.c
  397. @@ -9,6 +9,7 @@
  398. #include <linux/init.h>
  399. #include <linux/bootmem.h>
  400. #include <asm/bootinfo.h>
  401. +#include <bcm63xx_board.h>
  402. #include <bcm63xx_cpu.h>
  403. #include <bcm63xx_io.h>
  404. #include <bcm63xx_regs.h>
  405. @@ -36,6 +37,9 @@ void __init prom_init(void)
  406. /* assign command line from kernel config */
  407. strcpy(arcs_cmdline, CONFIG_CMDLINE);
  408. +
  409. + /* do low level board init */
  410. + board_prom_init();
  411. }
  412. void __init prom_free_prom_memory(void)
  413. diff --git a/arch/mips/bcm63xx/setup.c b/arch/mips/bcm63xx/setup.c
  414. index 4d8b127..c4516fb 100644
  415. --- a/arch/mips/bcm63xx/setup.c
  416. +++ b/arch/mips/bcm63xx/setup.c
  417. @@ -16,6 +16,7 @@
  418. #include <asm/time.h>
  419. #include <asm/reboot.h>
  420. #include <asm/cacheflush.h>
  421. +#include <bcm63xx_board.h>
  422. #include <bcm63xx_cpu.h>
  423. #include <bcm63xx_regs.h>
  424. #include <bcm63xx_io.h>
  425. @@ -87,8 +88,9 @@ static void __bcm63xx_machine_reboot(char *p)
  426. const char *get_system_type(void)
  427. {
  428. static char buf[128];
  429. - sprintf(buf, "bcm963xx (0x%04x/0x%04X)",
  430. - bcm63xx_get_cpu_id(), bcm63xx_get_cpu_rev());
  431. + snprintf(buf, sizeof (buf), "bcm63xx/%s (0x%04x/0x%04X)",
  432. + board_get_name(),
  433. + bcm63xx_get_cpu_id(), bcm63xx_get_cpu_rev());
  434. return buf;
  435. }
  436. @@ -96,6 +98,7 @@ void __init plat_time_init(void)
  437. {
  438. mips_hpt_frequency = bcm63xx_get_cpu_freq() / 2;
  439. }
  440. +
  441. void __init plat_mem_setup(void)
  442. {
  443. add_memory_region(0, bcm63xx_get_memory_size(), BOOT_MEM_RAM);
  444. @@ -107,4 +110,13 @@ void __init plat_mem_setup(void)
  445. set_io_port_base(0);
  446. ioport_resource.start = 0;
  447. ioport_resource.end = ~0;
  448. +
  449. + board_setup();
  450. +}
  451. +
  452. +int __init bcm63xx_register_devices(void)
  453. +{
  454. + return board_register_devices();
  455. }
  456. +
  457. +device_initcall(bcm63xx_register_devices);
  458. diff --git a/include/asm-mips/mach-bcm63xx/bcm63xx_board.h b/include/asm-mips/mach-bcm63xx/bcm63xx_board.h
  459. new file mode 100644
  460. index 0000000..fa3e7e6
  461. --- /dev/null
  462. +++ b/include/asm-mips/mach-bcm63xx/bcm63xx_board.h
  463. @@ -0,0 +1,12 @@
  464. +#ifndef BCM63XX_BOARD_H_
  465. +#define BCM63XX_BOARD_H_
  466. +
  467. +const char *board_get_name(void);
  468. +
  469. +void board_prom_init(void);
  470. +
  471. +void board_setup(void);
  472. +
  473. +int board_register_devices(void);
  474. +
  475. +#endif /* ! BCM63XX_BOARD_H_ */
  476. diff --git a/include/asm-mips/mach-bcm63xx/board_bcm963xx.h b/include/asm-mips/mach-bcm63xx/board_bcm963xx.h
  477. new file mode 100644
  478. index 0000000..17e4e7e
  479. --- /dev/null
  480. +++ b/include/asm-mips/mach-bcm63xx/board_bcm963xx.h
  481. @@ -0,0 +1,50 @@
  482. +#ifndef BOARD_BCM963XX_H_
  483. +#define BOARD_BCM963XX_H_
  484. +
  485. +#include <linux/types.h>
  486. +#include <bcm63xx_dev_enet.h>
  487. +
  488. +/*
  489. + * flash mapping
  490. + */
  491. +#define BCM963XX_CFE_VERSION_OFFSET 0x570
  492. +#define BCM963XX_NVRAM_OFFSET 0x580
  493. +
  494. +/*
  495. + * nvram structure
  496. + */
  497. +struct bcm963xx_nvram {
  498. + u32 version;
  499. + u8 reserved1[256];
  500. + u8 name[16];
  501. + u32 main_tp_number;
  502. + u32 psi_size;
  503. + u32 mac_addr_count;
  504. + u8 mac_addr_base[6];
  505. + u8 reserved2[2];
  506. + u32 checksum_old;
  507. + u8 reserved3[720];
  508. + u32 checksum_high;
  509. +};
  510. +
  511. +/*
  512. + * board definition
  513. + */
  514. +struct board_info {
  515. + u8 name[16];
  516. + unsigned int expected_cpu_id;
  517. +
  518. + /* enabled feature/device */
  519. + unsigned int has_enet0:1;
  520. + unsigned int has_enet1:1;
  521. + unsigned int has_pci:1;
  522. + unsigned int has_pccard:1;
  523. + unsigned int has_ohci0:1;
  524. + unsigned int has_ehci0:1;
  525. +
  526. + /* ethernet config */
  527. + struct bcm63xx_enet_platform_data enet0;
  528. + struct bcm63xx_enet_platform_data enet1;
  529. +};
  530. +
  531. +#endif /* ! BOARD_BCM963XX_H_ */
  532. --
  533. 1.5.4.3