tools: mkimage: provide dtc path during build
[openwrt/openwrt.git] / target / linux / mvebu / patches-4.4 / 121-phy-convert-swphy-register-generation-to-tabular-for.patch
1 From cd834fe430f030a63bfa9277bba194e8eef4dbd0 Mon Sep 17 00:00:00 2001
2 From: Russell King <rmk+kernel@arm.linux.org.uk>
3 Date: Sun, 20 Sep 2015 10:18:59 +0100
4 Subject: [PATCH 710/744] phy: convert swphy register generation to tabular
5 form
6
7 Convert the swphy register generation to tabular form which allows us
8 to eliminate multiple switch() statements. This results in a smaller
9 object code size, more efficient, and easier to add support for faster
10 speeds.
11
12 Before:
13
14 Idx Name Size VMA LMA File off Algn
15 0 .text 00000164 00000000 00000000 00000034 2**2
16
17 text data bss dec hex filename
18 388 0 0 388 184 swphy.o
19
20 After:
21
22 Idx Name Size VMA LMA File off Algn
23 0 .text 000000fc 00000000 00000000 00000034 2**2
24 5 .rodata 00000028 00000000 00000000 00000138 2**2
25
26 text data bss dec hex filename
27 324 0 0 324 144 swphy.o
28
29 Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
30 Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
31 ---
32 drivers/net/phy/swphy.c | 143 ++++++++++++++++++++++++++----------------------
33 1 file changed, 78 insertions(+), 65 deletions(-)
34
35 --- a/drivers/net/phy/swphy.c
36 +++ b/drivers/net/phy/swphy.c
37 @@ -20,6 +20,72 @@
38
39 #include "swphy.h"
40
41 +struct swmii_regs {
42 + u16 bmcr;
43 + u16 bmsr;
44 + u16 lpa;
45 + u16 lpagb;
46 +};
47 +
48 +enum {
49 + SWMII_SPEED_10 = 0,
50 + SWMII_SPEED_100,
51 + SWMII_SPEED_1000,
52 + SWMII_DUPLEX_HALF = 0,
53 + SWMII_DUPLEX_FULL,
54 +};
55 +
56 +/*
57 + * These two tables get bitwise-anded together to produce the final result.
58 + * This means the speed table must contain both duplex settings, and the
59 + * duplex table must contain all speed settings.
60 + */
61 +static const struct swmii_regs speed[] = {
62 + [SWMII_SPEED_10] = {
63 + .bmcr = BMCR_FULLDPLX,
64 + .lpa = LPA_10FULL | LPA_10HALF,
65 + },
66 + [SWMII_SPEED_100] = {
67 + .bmcr = BMCR_FULLDPLX | BMCR_SPEED100,
68 + .bmsr = BMSR_100FULL | BMSR_100HALF,
69 + .lpa = LPA_100FULL | LPA_100HALF,
70 + },
71 + [SWMII_SPEED_1000] = {
72 + .bmcr = BMCR_FULLDPLX | BMCR_SPEED1000,
73 + .bmsr = BMSR_ESTATEN,
74 + .lpagb = LPA_1000FULL | LPA_1000HALF,
75 + },
76 +};
77 +
78 +static const struct swmii_regs duplex[] = {
79 + [SWMII_DUPLEX_HALF] = {
80 + .bmcr = ~BMCR_FULLDPLX,
81 + .bmsr = BMSR_ESTATEN | BMSR_100HALF,
82 + .lpa = LPA_10HALF | LPA_100HALF,
83 + .lpagb = LPA_1000HALF,
84 + },
85 + [SWMII_DUPLEX_FULL] = {
86 + .bmcr = ~0,
87 + .bmsr = BMSR_ESTATEN | BMSR_100FULL,
88 + .lpa = LPA_10FULL | LPA_100FULL,
89 + .lpagb = LPA_1000FULL,
90 + },
91 +};
92 +
93 +static int swphy_decode_speed(int speed)
94 +{
95 + switch (speed) {
96 + case 1000:
97 + return SWMII_SPEED_1000;
98 + case 100:
99 + return SWMII_SPEED_100;
100 + case 10:
101 + return SWMII_SPEED_10;
102 + default:
103 + return -EINVAL;
104 + }
105 +}
106 +
107 /**
108 * swphy_update_regs - update MII register array with fixed phy state
109 * @regs: array of 32 registers to update
110 @@ -30,81 +96,28 @@
111 */
112 int swphy_update_regs(u16 *regs, const struct fixed_phy_status *state)
113 {
114 + int speed_index, duplex_index;
115 u16 bmsr = BMSR_ANEGCAPABLE;
116 u16 bmcr = 0;
117 u16 lpagb = 0;
118 u16 lpa = 0;
119
120 - if (state->duplex) {
121 - switch (state->speed) {
122 - case 1000:
123 - bmsr |= BMSR_ESTATEN;
124 - break;
125 - case 100:
126 - bmsr |= BMSR_100FULL;
127 - break;
128 - case 10:
129 - bmsr |= BMSR_10FULL;
130 - break;
131 - default:
132 - break;
133 - }
134 - } else {
135 - switch (state->speed) {
136 - case 1000:
137 - bmsr |= BMSR_ESTATEN;
138 - break;
139 - case 100:
140 - bmsr |= BMSR_100HALF;
141 - break;
142 - case 10:
143 - bmsr |= BMSR_10HALF;
144 - break;
145 - default:
146 - break;
147 - }
148 + speed_index = swphy_decode_speed(state->speed);
149 + if (speed_index < 0) {
150 + pr_warn("swphy: unknown speed\n");
151 + return -EINVAL;
152 }
153
154 + duplex_index = state->duplex ? SWMII_DUPLEX_FULL : SWMII_DUPLEX_HALF;
155 +
156 + bmsr |= speed[speed_index].bmsr & duplex[duplex_index].bmsr;
157 +
158 if (state->link) {
159 bmsr |= BMSR_LSTATUS | BMSR_ANEGCOMPLETE;
160
161 - if (state->duplex) {
162 - bmcr |= BMCR_FULLDPLX;
163 -
164 - switch (state->speed) {
165 - case 1000:
166 - bmcr |= BMCR_SPEED1000;
167 - lpagb |= LPA_1000FULL;
168 - break;
169 - case 100:
170 - bmcr |= BMCR_SPEED100;
171 - lpa |= LPA_100FULL;
172 - break;
173 - case 10:
174 - lpa |= LPA_10FULL;
175 - break;
176 - default:
177 - pr_warn("swphy: unknown speed\n");
178 - return -EINVAL;
179 - }
180 - } else {
181 - switch (state->speed) {
182 - case 1000:
183 - bmcr |= BMCR_SPEED1000;
184 - lpagb |= LPA_1000HALF;
185 - break;
186 - case 100:
187 - bmcr |= BMCR_SPEED100;
188 - lpa |= LPA_100HALF;
189 - break;
190 - case 10:
191 - lpa |= LPA_10HALF;
192 - break;
193 - default:
194 - pr_warn("swphy: unknown speed\n");
195 - return -EINVAL;
196 - }
197 - }
198 + bmcr |= speed[speed_index].bmcr & duplex[duplex_index].bmcr;
199 + lpa |= speed[speed_index].lpa & duplex[duplex_index].lpa;
200 + lpagb |= speed[speed_index].lpagb & duplex[duplex_index].lpagb;
201
202 if (state->pause)
203 lpa |= LPA_PAUSE_CAP;