~funderscore blog cgit wiki get in touch
aboutsummaryrefslogtreecommitdiff
blob: 495a97691881976ddeb0923f986cea94352eed53 (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
135
136
137
138
139
140
#include <common.h>
#include <command.h>
#include <console.h> /* ctrlc */
#include <pci.h>
#include <asm/io.h>

#include "hydra.h"

enum {
	HWVER_100 = 0,
	HWVER_110 = 1,
	HWVER_120 = 2,
};

static struct pci_device_id hydra_supported[] = {
	{ 0x6d5e, 0xcdc1 },
	{}
};

static struct ihs_fpga *fpga;

struct ihs_fpga *get_fpga(void)
{
	return fpga;
}

void print_hydra_version(uint index)
{
	u32 versions = readl(&fpga->versions);
	u32 fpga_version = readl(&fpga->fpga_version);

	uint hardware_version = versions & 0xf;

	printf("FPGA%u: mapped to %p\n       ", index, fpga);

	switch (hardware_version) {
	case HWVER_100:
		printf("HW-Ver 1.00\n");
		break;

	case HWVER_110:
		printf("HW-Ver 1.10\n");
		break;

	case HWVER_120:
		printf("HW-Ver 1.20\n");
		break;

	default:
		printf("HW-Ver %d(not supported)\n",
		       hardware_version);
		break;
	}

	printf("       FPGA V %d.%02d\n",
	       fpga_version / 100, fpga_version % 100);
}

void hydra_initialize(void)
{
	uint i;
	pci_dev_t devno;

	/* Find and probe all the matching PCI devices */
	for (i = 0; (devno = pci_find_devices(hydra_supported, i)) >= 0; i++) {
		u32 val;

		/* Try to enable I/O accesses and bus-mastering */
		val = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
		pci_write_config_dword(devno, PCI_COMMAND, val);

		/* Make sure it worked */
		pci_read_config_dword(devno, PCI_COMMAND, &val);
		if (!(val & PCI_COMMAND_MEMORY)) {
			puts("Can't enable I/O memory\n");
			continue;
		}
		if (!(val & PCI_COMMAND_MASTER)) {
			puts("Can't enable bus-mastering\n");
			continue;
		}

		/* read FPGA details */
		fpga = pci_map_bar(devno, PCI_BASE_ADDRESS_0,
				   PCI_REGION_MEM);

		print_hydra_version(i);
	}
}

#define REFL_PATTERN (0xdededede)
#define REFL_PATTERN_INV (~REFL_PATTERN)

int do_hydrate(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
	uint k = 0;
	void __iomem *pcie2_base = (void __iomem *)(MVEBU_REG_PCIE_BASE +
						    0x4000);

	if (!fpga)
		return -1;

	while (1) {
		u32 res;

		writel(REFL_PATTERN, &fpga->reflection_low);
		res = readl(&fpga->reflection_low);
		if (res != REFL_PATTERN_INV)
			printf("round %u: read %08x, expected %08x\n",
			       k, res, REFL_PATTERN_INV);
		writel(REFL_PATTERN_INV, &fpga->reflection_low);
		res = readl(&fpga->reflection_low);
		if (res != REFL_PATTERN)
			printf("round %u: read %08x, expected %08x\n",
			       k, res, REFL_PATTERN);

		res = readl(pcie2_base + 0x118) & 0x1f;
		if (res)
			printf("FrstErrPtr %u\n", res);
		res = readl(pcie2_base + 0x104);
		if (res) {
			printf("Uncorrectable Error Status 0x%08x\n", res);
			writel(res, pcie2_base + 0x104);
		}

		if (!(++k % 10000))
			printf("round %u\n", k);

		if (ctrlc())
			break;
	}

	return 0;
}

U_BOOT_CMD(
	hydrate,	1,	0,	do_hydrate,
	"hydra reflection test",
	"hydra reflection test"
);