summaryrefslogtreecommitdiff
path: root/arch/arm/mach-socfpga/misc_s10.c
blob: e599362f145861abd6f57412c4c8d5784c59d92d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2016-2018 Intel Corporation <www.intel.com>
 *
 */

#include <altera.h>
#include <common.h>
#include <errno.h>
#include <fdtdec.h>
#include <miiphy.h>
#include <netdev.h>
#include <asm/io.h>
#include <asm/arch/reset_manager.h>
#include <asm/arch/system_manager.h>
#include <asm/arch/misc.h>
#include <asm/pl310.h>
#include <linux/libfdt.h>

#include <dt-bindings/reset/altr,rst-mgr-s10.h>

DECLARE_GLOBAL_DATA_PTR;

static struct socfpga_system_manager *sysmgr_regs =
	(struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS;

/*
 * DesignWare Ethernet initialization
 */
#ifdef CONFIG_ETH_DESIGNWARE

static u32 socfpga_phymode_setup(u32 gmac_index, const char *phymode)
{
	u32 modereg;

	if (!phymode)
		return -EINVAL;

	if (!strcmp(phymode, "mii") || !strcmp(phymode, "gmii") ||
	    !strcmp(phymode, "sgmii"))
		modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII;
	else if (!strcmp(phymode, "rgmii"))
		modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII;
	else if (!strcmp(phymode, "rmii"))
		modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII;
	else
		return -EINVAL;

	clrsetbits_le32(&sysmgr_regs->emac0 + gmac_index,
			SYSMGR_EMACGRP_CTRL_PHYSEL_MASK,
			modereg);

	return 0;
}

static int socfpga_set_phymode(void)
{
	const void *fdt = gd->fdt_blob;
	struct fdtdec_phandle_args args;
	const char *phy_mode;
	u32 gmac_index;
	int nodes[3];	/* Max. 3 GMACs */
	int ret, count;
	int i, node;

	count = fdtdec_find_aliases_for_id(fdt, "ethernet",
					   COMPAT_ALTERA_SOCFPGA_DWMAC,
					   nodes, ARRAY_SIZE(nodes));
	for (i = 0; i < count; i++) {
		node = nodes[i];
		if (node <= 0)
			continue;

		ret = fdtdec_parse_phandle_with_args(fdt, node, "resets",
						     "#reset-cells", 1, 0,
						     &args);
		if (ret || args.args_count != 1) {
			debug("GMAC%i: Failed to parse DT 'resets'!\n", i);
			continue;
		}

		gmac_index = args.args[0] - EMAC0_RESET;

		phy_mode = fdt_getprop(fdt, node, "phy-mode", NULL);
		ret = socfpga_phymode_setup(gmac_index, phy_mode);
		if (ret) {
			debug("GMAC%i: Failed to parse DT 'phy-mode'!\n", i);
			continue;
		}
	}

	return 0;
}
#else
static int socfpga_set_phymode(void)
{
	return 0;
};
#endif

/*
 * Print CPU information
 */
#if defined(CONFIG_DISPLAY_CPUINFO)
int print_cpuinfo(void)
{
	puts("CPU:   Intel FPGA SoCFPGA Platform (ARMv8 64bit Cortex-A53)\n");

	return 0;
}
#endif

#ifdef CONFIG_ARCH_MISC_INIT
int arch_misc_init(void)
{
	char qspi_string[13];

	sprintf(qspi_string, "<0x%08x>", cm_get_qspi_controller_clk_hz());
	env_set("qspi_clock", qspi_string);

	socfpga_set_phymode();
	return 0;
}
#endif

int arch_early_init_r(void)
{
	return 0;
}

void do_bridge_reset(int enable)
{
	socfpga_bridges_reset(enable);
}