162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Joshua Henderson, joshua.henderson@microchip.com 462306a36Sopenharmony_ci * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci#include <linux/init.h> 762306a36Sopenharmony_ci#include <linux/kernel.h> 862306a36Sopenharmony_ci#include <linux/of_address.h> 962306a36Sopenharmony_ci#include <linux/of_fdt.h> 1062306a36Sopenharmony_ci#include <linux/of_platform.h> 1162306a36Sopenharmony_ci#include <linux/platform_data/sdhci-pic32.h> 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include <asm/fw/fw.h> 1462306a36Sopenharmony_ci#include <asm/mips-boards/generic.h> 1562306a36Sopenharmony_ci#include <asm/prom.h> 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#include "pic32mzda.h" 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ciconst char *get_system_type(void) 2062306a36Sopenharmony_ci{ 2162306a36Sopenharmony_ci return "PIC32MZDA"; 2262306a36Sopenharmony_ci} 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_civoid __init plat_mem_setup(void) 2562306a36Sopenharmony_ci{ 2662306a36Sopenharmony_ci void *dtb; 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci dtb = get_fdt(); 2962306a36Sopenharmony_ci if (!dtb) { 3062306a36Sopenharmony_ci pr_err("pic32: no DTB found.\n"); 3162306a36Sopenharmony_ci return; 3262306a36Sopenharmony_ci } 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci /* 3562306a36Sopenharmony_ci * Load the builtin device tree. This causes the chosen node to be 3662306a36Sopenharmony_ci * parsed resulting in our memory appearing. 3762306a36Sopenharmony_ci */ 3862306a36Sopenharmony_ci __dt_setup_arch(dtb); 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci pr_info("Found following command lines\n"); 4162306a36Sopenharmony_ci pr_info(" boot_command_line: %s\n", boot_command_line); 4262306a36Sopenharmony_ci pr_info(" arcs_cmdline : %s\n", arcs_cmdline); 4362306a36Sopenharmony_ci#ifdef CONFIG_CMDLINE_BOOL 4462306a36Sopenharmony_ci pr_info(" builtin_cmdline : %s\n", CONFIG_CMDLINE); 4562306a36Sopenharmony_ci#endif 4662306a36Sopenharmony_ci if (dtb != __dtb_start) 4762306a36Sopenharmony_ci strscpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci#ifdef CONFIG_EARLY_PRINTK 5062306a36Sopenharmony_ci fw_init_early_console(); 5162306a36Sopenharmony_ci#endif 5262306a36Sopenharmony_ci pic32_config_init(); 5362306a36Sopenharmony_ci} 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_cistatic __init void pic32_init_cmdline(int argc, char *argv[]) 5662306a36Sopenharmony_ci{ 5762306a36Sopenharmony_ci unsigned int count = COMMAND_LINE_SIZE - 1; 5862306a36Sopenharmony_ci int i; 5962306a36Sopenharmony_ci char *dst = &(arcs_cmdline[0]); 6062306a36Sopenharmony_ci char *src; 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci for (i = 1; i < argc && count; ++i) { 6362306a36Sopenharmony_ci src = argv[i]; 6462306a36Sopenharmony_ci while (*src && count) { 6562306a36Sopenharmony_ci *dst++ = *src++; 6662306a36Sopenharmony_ci --count; 6762306a36Sopenharmony_ci } 6862306a36Sopenharmony_ci *dst++ = ' '; 6962306a36Sopenharmony_ci } 7062306a36Sopenharmony_ci if (i > 1) 7162306a36Sopenharmony_ci --dst; 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci *dst = 0; 7462306a36Sopenharmony_ci} 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_civoid __init prom_init(void) 7762306a36Sopenharmony_ci{ 7862306a36Sopenharmony_ci pic32_init_cmdline((int)fw_arg0, (char **)fw_arg1); 7962306a36Sopenharmony_ci} 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_cistatic struct pic32_sdhci_platform_data sdhci_data = { 8262306a36Sopenharmony_ci .setup_dma = pic32_set_sdhci_adma_fifo_threshold, 8362306a36Sopenharmony_ci}; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_cistatic struct of_dev_auxdata pic32_auxdata_lookup[] __initdata = { 8662306a36Sopenharmony_ci OF_DEV_AUXDATA("microchip,pic32mzda-sdhci", 0, "sdhci", &sdhci_data), 8762306a36Sopenharmony_ci { /* sentinel */} 8862306a36Sopenharmony_ci}; 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_cistatic int __init pic32_of_prepare_platform_data(struct of_dev_auxdata *lookup) 9162306a36Sopenharmony_ci{ 9262306a36Sopenharmony_ci struct device_node *root, *np; 9362306a36Sopenharmony_ci struct resource res; 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci root = of_find_node_by_path("/"); 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci for (; lookup->compatible; lookup++) { 9862306a36Sopenharmony_ci np = of_find_compatible_node(NULL, NULL, lookup->compatible); 9962306a36Sopenharmony_ci if (np) { 10062306a36Sopenharmony_ci lookup->name = (char *)np->name; 10162306a36Sopenharmony_ci if (lookup->phys_addr) { 10262306a36Sopenharmony_ci of_node_put(np); 10362306a36Sopenharmony_ci continue; 10462306a36Sopenharmony_ci } 10562306a36Sopenharmony_ci if (!of_address_to_resource(np, 0, &res)) 10662306a36Sopenharmony_ci lookup->phys_addr = res.start; 10762306a36Sopenharmony_ci of_node_put(np); 10862306a36Sopenharmony_ci } 10962306a36Sopenharmony_ci } 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci of_node_put(root); 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci return 0; 11462306a36Sopenharmony_ci} 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_cistatic int __init plat_of_setup(void) 11762306a36Sopenharmony_ci{ 11862306a36Sopenharmony_ci if (!of_have_populated_dt()) 11962306a36Sopenharmony_ci panic("Device tree not present"); 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci pic32_of_prepare_platform_data(pic32_auxdata_lookup); 12262306a36Sopenharmony_ci if (of_platform_default_populate(NULL, pic32_auxdata_lookup, NULL)) 12362306a36Sopenharmony_ci panic("Failed to populate DT"); 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci return 0; 12662306a36Sopenharmony_ci} 12762306a36Sopenharmony_ciarch_initcall(plat_of_setup); 128