embox

Форк
0
/
emac_mdio.c 
207 строк · 4.5 Кб
1
/**
2
 * @file
3
 *
4
 * @date 08.02.2016
5
 * @author: Anton Bondarev
6
 */
7
#include <util/log.h>
8

9
#include <hal/reg.h>
10
#include "emac.h"
11

12
#include <drivers/common/memory.h>
13

14
#include <framework/mod/options.h>
15

16
#define MDIO_BASE	OPTION_GET(NUMBER, mdio_base)
17

18
#define MAX_PAGESEL 31
19
#define MAX_IR 20
20
#define MAX_CR 19
21
#define MAX_GMIICR 18
22
#define MAX_PTPCR1 16
23
#define MAX_DISSPI_SETPG2 0x12
24
#define MAX_DISSPI_SETPG1 0x11
25
#define MAX_DISSPI_SETPG0 0x10
26

27
static int phy_num = -1;
28

29
void emac_mdio_enable(void) {
30
	REG_STORE(MDIO_BASE + MDIO_R_CONTROL,
31
			MDIO_CONTROL_ENABLE | 0x20 /* Freq */);
32

33
	while (REG_LOAD(MDIO_BASE + MDIO_R_CONTROL) & MDIO_CONTROL_IDLE);
34
}
35

36
void emac_mdio_writereg(unsigned char reg_num,unsigned short data) {
37
	unsigned int tmp=0,tmp1=0;
38

39
	tmp=(1<<31);
40
	log_debug("EMW 1 tmp=%x",tmp);
41
	tmp1=1<<30;
42
	log_debug("EMW 2 tmp1=%x",tmp1);
43
	tmp|=tmp1;
44
	tmp1=((reg_num&0x1f)<<21);
45
	log_debug("EMW 3 tmp1=%x",tmp1);
46
	tmp|=tmp1;
47
	tmp1=((phy_num & 0x1f) << 16);
48
	log_debug("EMW 4 tmp1=%x",tmp1);
49
	tmp|=tmp1;
50
	tmp1=data&0xffff;
51
	log_debug("EMW 5 tmp1=%x",tmp1);
52
	tmp|=tmp1;
53
	log_debug("EMW tmp=%x",tmp);
54
		log_debug("trace 1");
55
	REG_STORE(MDIO_BASE+MDIO_R_USERACCESS0,tmp);
56
		log_debug("trace 2");
57
	tmp1=0;
58
	while(REG_LOAD(MDIO_BASE+MDIO_R_USERINTRAW)==0)
59
	{
60
		tmp1++;
61
		log_debug("wait..");
62
	}
63
	REG_STORE(MDIO_BASE+MDIO_R_USERINTRAW,REG_LOAD(MDIO_BASE+MDIO_R_USERINTRAW));
64
	//res=REG_LOAD(MDIO_BASE+MDIO_R_USERACCESS0);
65
}
66

67
int emac_mdio_readreg(unsigned char reg_num) {
68
	unsigned int res=0;
69
	unsigned int tmp=0,tmp1=0;
70

71
	tmp=(1<<31);
72
	log_debug("EMR 1 tmp=%x",tmp);
73
	tmp1=((reg_num&0x1f)<<21);
74
	log_debug("EMR 2 tmp1=%x",tmp1);
75
	tmp|=tmp1;
76
	tmp1=((phy_num & 0x1f) << 16);
77
	log_debug("EMR 3 tmp1=%x",tmp1);
78
	tmp|=tmp1;
79
	log_debug("EMR tmp=%x",tmp);
80
	REG_STORE(MDIO_BASE+MDIO_R_USERACCESS0,tmp);
81
	tmp1=0;
82
	while(REG_LOAD(MDIO_BASE+MDIO_R_USERINTRAW)==0)
83
	{
84
		log_debug("wait..");
85
		tmp1++;
86
	}
87
	REG_STORE(MDIO_BASE+MDIO_R_USERINTRAW,REG_LOAD(MDIO_BASE+MDIO_R_USERINTRAW));
88

89
	res=REG_LOAD(MDIO_BASE+MDIO_R_USERACCESS0);
90
	if(((res>>29)&0x1)==0)
91
	{
92
		log_error("emac_mdio_readreg err - ACC not - res=%x",res);
93
		return 0;
94
	}
95
	return res&0xffff;
96
}
97

98
void emac_mdelay(int value) {
99
	volatile int delay = value * 4096;
100

101
	while (delay --);
102
}
103

104
void emac_detect_phy(void) {
105
	uint32_t tmp;
106
	tmp = REG_LOAD(MDIO_BASE + MDIO_R_ALIVE);
107

108
	for (int i = 0; i < 31; i++) {
109
		if (tmp & (1 << i)) {
110
			phy_num = i;
111
			break;
112
		}
113
	}
114

115
	if (phy_num == -1) {
116
		log_error("Could not detect PHY");
117
	}
118

119
	log_debug("Detected PHY %d", phy_num);
120

121
	REG_STORE(MDIO_BASE+MDIO_R_USERPHYSEL0,phy_num);
122
}
123

124
void emac_autonegotiate(void) {
125
	int tmp, val, cntr = 0;
126

127
	tmp = emac_mdio_readreg(MII_BMCR);
128
	val = tmp | BMCR_FULLDPLX | BMCR_ANENABLE |
129
						BMCR_SPEED100;
130
	log_debug("MII_BMCR=%08x,write%08x", tmp, val);
131
	emac_mdio_writereg(MII_BMCR, val);
132

133
	val = emac_mdio_readreg(MII_ADVERTISE);
134

135
	log_debug("MII_ADVERTISE=%08x", val);
136
#if EMAC_VERSION == 0
137
	val = PHY_ADV;
138
#else
139
	val = ADVERTISE_100FULL | ADVERTISE_100HALF |
140
		ADVERTISE_10HALF | ADVERTISE_10FULL;
141
#endif
142
	emac_mdio_writereg(MII_ADVERTISE, val);
143

144
	tmp = emac_mdio_readreg(MII_BMCR);
145

146
	/* Restart Auto_negotiation  */
147
	emac_mdio_writereg(MII_BMCR, tmp | BMCR_ANRESTART);
148

149
	/*check AutoNegotiate complete */
150
	log_debug("MII_BMCR=%08x,write%08x", tmp, val);
151
	do {
152
		emac_mdelay(40000);
153
		if (emac_mdio_readreg(MII_BMSR) & BMSR_ANEGCOMPLETE)
154
			break;
155

156
		cntr++;
157
	} while (cntr < 200);
158

159
	if (!(emac_mdio_readreg(MII_BMSR) & BMSR_ANEGCOMPLETE)) {
160
		log_error("Autonegotiation not completed");
161
	}
162

163
	tmp = emac_mdio_readreg(MII_LPA);
164
	tmp &= emac_mdio_readreg(MII_ADVERTISE);
165

166
	if (tmp & ADVERTISE_100FULL) {
167
		log_info("\t100 Mbps FULL");
168
		emac_set_macctrl(1 | 0x20 | (1 << 15));
169
	} else if (tmp & ADVERTISE_100HALF) {
170
		log_info("\t100 Mbps HALF");
171
		emac_set_macctrl(0 | 0x20 | (1 << 15));
172
	} else if (tmp & ADVERTISE_10FULL) {
173
		log_info("\t10 Mbps FULL");
174
		emac_set_macctrl(1 | 0x20);
175
	} else if (tmp & ADVERTISE_10HALF) {
176
		log_info("\t10 Mbps HALF");
177
		emac_set_macctrl(0 | 0x20);
178
	} else {
179
		log_info("Auto negotiatie error");
180
	}
181
}
182

183
void emac_mdio_config(void) {
184
	log_debug("emac_mdio_config started");
185

186
	emac_mdio_enable();
187

188
	emac_mdelay(10000);
189

190
	emac_detect_phy();
191

192
	emac_autonegotiate();
193

194
#if (OPTION_GET(NUMBER, speed) == 100)
195
	return;
196
#else
197
	emac_mdio_writereg(MAX_CR,res);
198
	res=emac_mdio_readreg(MAX_GMIICR);
199
	log_debug("EMC res3=%x",res);
200
	res|=0x8480;
201
	log_debug("EMC res4=%x",res);
202
	emac_mdio_writereg(MAX_GMIICR,res);
203
	log_debug("emac_mdio_config ended");
204
#endif
205
}
206

207
PERIPH_MEMORY_DEFINE(emac_mdio_region, MDIO_BASE, 0x800);
208

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.