1 /* 2 * Joshua Henderson, joshua.henderson@microchip.com 3 * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. 4 * 5 * This program is free software; you can distribute it and/or modify it 6 * under the terms of the GNU General Public License (Version 2) as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * for more details. 13 */ 14 #include <linux/init.h> 15 #include <linux/kernel.h> 16 #include <linux/of_address.h> 17 #include <linux/of_fdt.h> 18 #include <linux/of_platform.h> 19 #include <linux/platform_data/sdhci-pic32.h> 20 21 #include <asm/fw/fw.h> 22 #include <asm/mips-boards/generic.h> 23 #include <asm/prom.h> 24 25 #include "pic32mzda.h" 26 27 const char *get_system_type(void) 28 { 29 return "PIC32MZDA"; 30 } 31 32 static ulong get_fdtaddr(void) 33 { 34 ulong ftaddr = 0; 35 36 if ((fw_arg0 == -2) && fw_arg1 && !fw_arg2 && !fw_arg3) 37 return (ulong)fw_arg1; 38 39 if (__dtb_start < __dtb_end) 40 ftaddr = (ulong)__dtb_start; 41 42 return ftaddr; 43 } 44 45 void __init plat_mem_setup(void) 46 { 47 void *dtb; 48 49 dtb = (void *)get_fdtaddr(); 50 if (!dtb) { 51 pr_err("pic32: no DTB found.\n"); 52 return; 53 } 54 55 /* 56 * Load the builtin device tree. This causes the chosen node to be 57 * parsed resulting in our memory appearing. 58 */ 59 __dt_setup_arch(dtb); 60 61 pr_info("Found following command lines\n"); 62 pr_info(" boot_command_line: %s\n", boot_command_line); 63 pr_info(" arcs_cmdline : %s\n", arcs_cmdline); 64 #ifdef CONFIG_CMDLINE_BOOL 65 pr_info(" builtin_cmdline : %s\n", CONFIG_CMDLINE); 66 #endif 67 if (dtb != __dtb_start) 68 strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); 69 70 #ifdef CONFIG_EARLY_PRINTK 71 fw_init_early_console(-1); 72 #endif 73 pic32_config_init(); 74 } 75 76 static __init void pic32_init_cmdline(int argc, char *argv[]) 77 { 78 unsigned int count = COMMAND_LINE_SIZE - 1; 79 int i; 80 char *dst = &(arcs_cmdline[0]); 81 char *src; 82 83 for (i = 1; i < argc && count; ++i) { 84 src = argv[i]; 85 while (*src && count) { 86 *dst++ = *src++; 87 --count; 88 } 89 *dst++ = ' '; 90 } 91 if (i > 1) 92 --dst; 93 94 *dst = 0; 95 } 96 97 void __init prom_init(void) 98 { 99 pic32_init_cmdline((int)fw_arg0, (char **)fw_arg1); 100 } 101 102 void __init prom_free_prom_memory(void) 103 { 104 } 105 106 void __init device_tree_init(void) 107 { 108 if (!initial_boot_params) 109 return; 110 111 unflatten_and_copy_device_tree(); 112 } 113 114 static struct pic32_sdhci_platform_data sdhci_data = { 115 .setup_dma = pic32_set_sdhci_adma_fifo_threshold, 116 }; 117 118 static struct of_dev_auxdata pic32_auxdata_lookup[] __initdata = { 119 OF_DEV_AUXDATA("microchip,pic32mzda-sdhci", 0, "sdhci", &sdhci_data), 120 { /* sentinel */} 121 }; 122 123 static int __init pic32_of_prepare_platform_data(struct of_dev_auxdata *lookup) 124 { 125 struct device_node *root, *np; 126 struct resource res; 127 128 root = of_find_node_by_path("/"); 129 130 for (; lookup->compatible; lookup++) { 131 np = of_find_compatible_node(NULL, NULL, lookup->compatible); 132 if (np) { 133 lookup->name = (char *)np->name; 134 if (lookup->phys_addr) 135 continue; 136 if (!of_address_to_resource(np, 0, &res)) 137 lookup->phys_addr = res.start; 138 } 139 } 140 141 return 0; 142 } 143 144 static int __init plat_of_setup(void) 145 { 146 if (!of_have_populated_dt()) 147 panic("Device tree not present"); 148 149 pic32_of_prepare_platform_data(pic32_auxdata_lookup); 150 if (of_platform_default_populate(NULL, pic32_auxdata_lookup, NULL)) 151 panic("Failed to populate DT"); 152 153 return 0; 154 } 155 arch_initcall(plat_of_setup); 156