1 /*
2  * (C) Copyright 2015
3  * Dirk Eibach,  Guntermann & Drunck GmbH, eibach@gdsys.de
4  *
5  * SPDX-License-Identifier:	GPL-2.0+
6  */
7 
8 #include <common.h>
9 #include <command.h>
10 #include <dm.h>
11 #include <env.h>
12 #include <fdt_support.h>
13 #include <fsl_esdhc.h>
14 #include <init.h>
15 #include <miiphy.h>
16 #include <misc.h>
17 #include <sysinfo.h>
18 #include <tpm-v1.h>
19 #include <video_osd.h>
20 #include <asm/global_data.h>
21 
22 #include "../common/ihs_mdio.h"
23 #include "../../../drivers/sysinfo/gazerbeam.h"
24 
25 DECLARE_GLOBAL_DATA_PTR;
26 
27 struct ihs_mdio_info ihs_mdio_info[] = {
28 	{ .fpga = NULL, .name = "ihs0", .base = 0x58 },
29 	{ .fpga = NULL, .name = "ihs1", .base = 0x58 },
30 };
31 
get_tpm(struct udevice ** devp)32 static int get_tpm(struct udevice **devp)
33 {
34 	int rc;
35 
36 	rc = uclass_first_device_err(UCLASS_TPM, devp);
37 	if (rc) {
38 		printf("Could not find TPM (ret=%d)\n", rc);
39 		return CMD_RET_FAILURE;
40 	}
41 
42 	return 0;
43 }
44 
board_early_init_r(void)45 int board_early_init_r(void)
46 {
47 	struct udevice *sysinfo;
48 	struct udevice *serdes;
49 	int mc = 0;
50 	int con = 0;
51 
52 	if (sysinfo_get(&sysinfo))
53 		puts("Could not find sysinfo information device.\n");
54 
55 	/* Initialize serdes */
56 	uclass_get_device_by_phandle(UCLASS_MISC, sysinfo, "serdes", &serdes);
57 
58 	if (sysinfo_detect(sysinfo))
59 		puts("Device information detection failed.\n");
60 
61 	sysinfo_get_int(sysinfo, BOARD_MULTICHANNEL, &mc);
62 	sysinfo_get_int(sysinfo, BOARD_VARIANT, &con);
63 
64 	if (mc == 2 || mc == 1)
65 		dev_disable_by_path("/immr@e0000000/i2c@3100/pca9698@22");
66 
67 	if (mc == 4) {
68 		dev_disable_by_path("/immr@e0000000/i2c@3100/pca9698@20");
69 		dev_enable_by_path("/localbus@e0005000/iocon_uart@2,0");
70 		dev_enable_by_path("/fpga1bus");
71 	}
72 
73 	if (mc == 2 || con == VAR_CON) {
74 		dev_enable_by_path("/fpga0bus/fpga0_video1");
75 		dev_enable_by_path("/fpga0bus/fpga0_iic_video1");
76 		dev_enable_by_path("/fpga0bus/fpga0_axi_video1");
77 	}
78 
79 	if (con == VAR_CON) {
80 		dev_enable_by_path("/fpga0bus/fpga0_video0");
81 		dev_enable_by_path("/fpga0bus/fpga0_iic_video0");
82 		dev_enable_by_path("/fpga0bus/fpga0_axi_video0");
83 	}
84 
85 	return 0;
86 }
87 
checksysinfo(void)88 int checksysinfo(void)
89 {
90 	struct udevice *sysinfo;
91 	char *s = env_get("serial#");
92 	int mc = 0;
93 	int con = 0;
94 
95 	if (sysinfo_get(&sysinfo))
96 		puts("Could not find sysinfo information device.\n");
97 
98 	sysinfo_get_int(sysinfo, BOARD_MULTICHANNEL, &mc);
99 	sysinfo_get_int(sysinfo, BOARD_VARIANT, &con);
100 
101 	puts("Board: Gazerbeam ");
102 	printf("%s ", mc == 4 ? "MC4" : mc == 2 ? "MC2" : "SC");
103 	printf("%s", con == VAR_CON ? "CON" : "CPU");
104 
105 	if (s) {
106 		puts(", serial# ");
107 		puts(s);
108 	}
109 
110 	puts("\n");
111 
112 	return 0;
113 }
114 
display_osd_info(struct udevice * osd,struct video_osd_info * osd_info)115 static void display_osd_info(struct udevice *osd,
116 			     struct video_osd_info *osd_info)
117 {
118 	printf("OSD-%s: Digital-OSD version %01d.%02d, %d x %d characters\n",
119 	       osd->name, osd_info->major_version, osd_info->minor_version,
120 	       osd_info->width, osd_info->height);
121 }
122 
last_stage_init(void)123 int last_stage_init(void)
124 {
125 	int fpga_hw_rev = 0;
126 	int i;
127 	struct udevice *sysinfo;
128 	struct udevice *osd;
129 	struct video_osd_info osd_info;
130 	struct udevice *tpm;
131 	int ret;
132 
133 	if (sysinfo_get(&sysinfo))
134 		puts("Could not find sysinfo information device.\n");
135 
136 	if (sysinfo) {
137 		int res = sysinfo_get_int(sysinfo, BOARD_HWVERSION,
138 					  &fpga_hw_rev);
139 
140 		if (res)
141 			printf("Could not determind FPGA HW revision (res = %d)\n",
142 			       res);
143 	}
144 
145 	env_set_ulong("fpga_hw_rev", fpga_hw_rev);
146 
147 	ret = get_tpm(&tpm);
148 	if (ret || tpm_init(tpm) || tpm_startup(tpm, TPM_ST_CLEAR) ||
149 	    tpm_continue_self_test(tpm)) {
150 		printf("TPM init failed\n");
151 	}
152 
153 	if (fpga_hw_rev >= 4) {
154 		for (i = 0; i < 4; i++) {
155 			struct udevice *rxaui;
156 			char name[8];
157 
158 			snprintf(name, sizeof(name), "rxaui%d", i);
159 			/* Disable RXAUI polarity inversion */
160 			ret = uclass_get_device_by_phandle(UCLASS_MISC, sysinfo,
161 							   name, &rxaui);
162 			if (!ret)
163 				misc_set_enabled(rxaui, false);
164 		}
165 	}
166 
167 	for (uclass_first_device(UCLASS_VIDEO_OSD, &osd);
168 	     osd;
169 	     uclass_next_device(&osd)) {
170 		video_osd_get_info(osd, &osd_info);
171 		display_osd_info(osd, &osd_info);
172 	}
173 
174 	return 0;
175 }
176 
177 #if defined(CONFIG_OF_BOARD_SETUP)
ft_board_setup(void * blob,struct bd_info * bd)178 int ft_board_setup(void *blob, struct bd_info *bd)
179 {
180 	ft_cpu_setup(blob, bd);
181 	fsl_fdt_fixup_dr_usb(blob, bd);
182 	fdt_fixup_esdhc(blob, bd);
183 
184 	return 0;
185 }
186 #endif
187