Home | History | Annotate | Download | only in mach-socfpga
      1 // SPDX-License-Identifier: GPL-2.0
      2 /*
      3  *  Copyright (C) 2016-2017 Intel Corporation <www.intel.com>
      4  */
      5 
      6 #include <asm/arch/pinmux.h>
      7 #include <asm/io.h>
      8 #include <common.h>
      9 #include <fdtdec.h>
     10 
     11 static int do_pinctr_pin(const void *blob, int child, const char *node_name)
     12 {
     13 	int len;
     14 	fdt_addr_t base_addr;
     15 	fdt_size_t size;
     16 	const u32 *cell;
     17 	u32 offset, value;
     18 
     19 	base_addr = fdtdec_get_addr_size(blob, child, "reg", &size);
     20 	if (base_addr != FDT_ADDR_T_NONE) {
     21 		cell = fdt_getprop(blob, child, "pinctrl-single,pins", &len);
     22 		if (!cell || len <= 0)
     23 			return -EFAULT;
     24 
     25 		debug("%p %d\n", cell, len);
     26 		for (; len > 0; len -= (2 * sizeof(u32))) {
     27 			offset = fdt32_to_cpu(*cell++);
     28 			value = fdt32_to_cpu(*cell++);
     29 			debug("<0x%x 0x%x>\n", offset, value);
     30 			writel(value, base_addr + offset);
     31 		}
     32 		return 0;
     33 	}
     34 	return -EFAULT;
     35 }
     36 
     37 static int do_pinctrl_pins(const void *blob, int node, const char *child_name)
     38 {
     39 	int child, len;
     40 	const char *node_name;
     41 
     42 	child = fdt_first_subnode(blob, node);
     43 
     44 	if (child < 0)
     45 		return -EINVAL;
     46 
     47 	node_name = fdt_get_name(blob, child, &len);
     48 
     49 	while (node_name) {
     50 		if (!strcmp(child_name, node_name))
     51 			return do_pinctr_pin(blob, child, node_name);
     52 
     53 		child = fdt_next_subnode(blob, child);
     54 
     55 		if (child < 0)
     56 			break;
     57 
     58 		node_name = fdt_get_name(blob, child, &len);
     59 	}
     60 
     61 	return -EFAULT;
     62 }
     63 
     64 int config_dedicated_pins(const void *blob)
     65 {
     66 	int node;
     67 
     68 	node = fdtdec_next_compatible(blob, 0,
     69 			COMPAT_ALTERA_SOCFPGA_PINCTRL_SINGLE);
     70 	if (node < 0)
     71 		return -EINVAL;
     72 
     73 	if (do_pinctrl_pins(blob, node, "dedicated_cfg"))
     74 		return -EFAULT;
     75 
     76 	if (do_pinctrl_pins(blob, node, "dedicated"))
     77 		return -EFAULT;
     78 
     79 	return 0;
     80 }
     81 
     82 int config_pins(const void *blob, const char *pin_grp)
     83 {
     84 	int node;
     85 
     86 	node = fdtdec_next_compatible(blob, 0,
     87 			COMPAT_ALTERA_SOCFPGA_PINCTRL_SINGLE);
     88 	if (node < 0)
     89 		return -EINVAL;
     90 
     91 	if (do_pinctrl_pins(blob, node, pin_grp))
     92 		return -EFAULT;
     93 
     94 	return 0;
     95 }
     96