.. | .. |
---|
153 | 153 | |
---|
154 | 154 | enum inno_hdmi_phy_type { |
---|
155 | 155 | INNO_HDMI_PHY_RK3228, |
---|
156 | | - INNO_HDMI_PHY_RK3328 |
---|
| 156 | + INNO_HDMI_PHY_RK3328, |
---|
| 157 | + INNO_HDMI_PHY_RK3528 |
---|
157 | 158 | }; |
---|
158 | 159 | |
---|
159 | 160 | struct phy_config { |
---|
.. | .. |
---|
287 | 288 | {33750000, 1, 10, 2, 4}, |
---|
288 | 289 | {74250000, 1, 40, 8, 1}, |
---|
289 | 290 | {74250000, 18, 80, 8, 2}, |
---|
| 291 | + {74250000, 1, 20, 4, 8}, |
---|
290 | 292 | {148500000, 2, 40, 4, 3}, |
---|
| 293 | + {148500000, 1, 10, 2, 8}, |
---|
291 | 294 | {297000000, 4, 40, 2, 3}, |
---|
| 295 | + {297000000, 2, 20, 2, 8}, |
---|
292 | 296 | {594000000, 8, 40, 1, 3}, |
---|
| 297 | + {594000000, 4, 20, 1, 8}, |
---|
293 | 298 | { ~0UL, 0, 0, 0, 0} |
---|
294 | 299 | }; |
---|
295 | 300 | |
---|
.. | .. |
---|
330 | 335 | 594000000, { |
---|
331 | 336 | 0x10, 0x1a, 0x1a, 0x1a, 0x07, 0x15, 0x08, 0x08, 0x08, |
---|
332 | 337 | 0x00, 0xac, 0xcc, 0xcc, 0xcc, |
---|
| 338 | + }, |
---|
| 339 | + }, { |
---|
| 340 | + ~0UL, { |
---|
| 341 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
---|
| 342 | + 0x00, 0x00, 0x00, 0x00, 0x00, |
---|
| 343 | + }, |
---|
| 344 | + } |
---|
| 345 | +}; |
---|
| 346 | + |
---|
| 347 | +static const struct phy_config rk3528_phy_cfg[] = { |
---|
| 348 | + /* tmdsclk bias-clk bias-data voltage-clk voltage-data pre-emphasis-data */ |
---|
| 349 | + { 165000000, { |
---|
| 350 | + 0x03, 0x04, 0x0c, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, |
---|
| 351 | + 0x00, 0x00, 0x00, 0x00, 0x00, |
---|
| 352 | + }, |
---|
| 353 | + }, { |
---|
| 354 | + 340000000, { |
---|
| 355 | + 0x03, 0x04, 0x0c, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, |
---|
| 356 | + 0x00, 0x00, 0x00, 0x00, 0x00, |
---|
| 357 | + }, |
---|
| 358 | + }, { |
---|
| 359 | + 594000000, { |
---|
| 360 | + 0x02, 0x08, 0x0d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, |
---|
| 361 | + 0x00, 0x00, 0x00, 0x00, 0x00, |
---|
333 | 362 | }, |
---|
334 | 363 | }, { |
---|
335 | 364 | ~0UL, { |
---|
.. | .. |
---|
462 | 491 | else if (inno->plat_data->dev_type == INNO_HDMI_PHY_RK3228 && |
---|
463 | 492 | tmdsclock <= 33750000 && inno->efuse_flag) |
---|
464 | 493 | chipversion = 4; |
---|
| 494 | + else if (inno->plat_data->dev_type == INNO_HDMI_PHY_RK3528) |
---|
| 495 | + chipversion = 8; |
---|
465 | 496 | |
---|
466 | 497 | for (; cfg->tmdsclock != ~0UL; cfg++) |
---|
467 | 498 | if (tmdsclock <= cfg->tmdsclock && |
---|
.. | .. |
---|
631 | 662 | { |
---|
632 | 663 | struct device *dev = inno->dev; |
---|
633 | 664 | struct device_node *np = dev->of_node; |
---|
| 665 | + struct device_node *clk_np = NULL; |
---|
634 | 666 | struct clk_init_data init = {}; |
---|
635 | 667 | struct clk *refclk; |
---|
636 | 668 | const char *parent_name; |
---|
637 | 669 | int ret; |
---|
| 670 | + |
---|
| 671 | + if (inno->plat_data->dev_type == INNO_HDMI_PHY_RK3528) |
---|
| 672 | + clk_np = of_get_child_by_name(np, "clk-port"); |
---|
| 673 | + |
---|
| 674 | + if (!clk_np) |
---|
| 675 | + clk_np = np; |
---|
638 | 676 | |
---|
639 | 677 | refclk = devm_clk_get(dev, "refclk"); |
---|
640 | 678 | if (IS_ERR(refclk)) { |
---|
.. | .. |
---|
651 | 689 | init.ops = &inno_hdmi_phy_clk_ops; |
---|
652 | 690 | |
---|
653 | 691 | /* optional override of the clock name */ |
---|
654 | | - of_property_read_string(np, "clock-output-names", &init.name); |
---|
| 692 | + of_property_read_string(clk_np, "clock-output-names", &init.name); |
---|
655 | 693 | |
---|
656 | 694 | inno->hw.init = &init; |
---|
657 | 695 | |
---|
.. | .. |
---|
662 | 700 | return ret; |
---|
663 | 701 | } |
---|
664 | 702 | |
---|
665 | | - ret = of_clk_add_provider(np, of_clk_src_simple_get, inno->pclk); |
---|
| 703 | + ret = of_clk_add_provider(clk_np, of_clk_src_simple_get, inno->pclk); |
---|
666 | 704 | if (ret) { |
---|
667 | 705 | dev_err(dev, "failed to register OF clock provider: %d\n", ret); |
---|
668 | 706 | return ret; |
---|
.. | .. |
---|
1078 | 1116 | return frac; |
---|
1079 | 1117 | } |
---|
1080 | 1118 | |
---|
| 1119 | +static int |
---|
| 1120 | +inno_hdmi_phy_rk3528_power_on(struct inno_hdmi_phy *inno, |
---|
| 1121 | + const struct post_pll_config *cfg, |
---|
| 1122 | + const struct phy_config *phy_cfg) |
---|
| 1123 | +{ |
---|
| 1124 | + u32 val; |
---|
| 1125 | + u64 temp; |
---|
| 1126 | + |
---|
| 1127 | + /* Power off post PLL */ |
---|
| 1128 | + inno_update_bits(inno, 0xaa, 1, 0); |
---|
| 1129 | + |
---|
| 1130 | + val = cfg->prediv; |
---|
| 1131 | + inno_write(inno, 0xab, val); |
---|
| 1132 | + |
---|
| 1133 | + if (cfg->postdiv == 1) { |
---|
| 1134 | + inno_write(inno, 0xad, 0x8); |
---|
| 1135 | + inno_write(inno, 0xaa, 2); |
---|
| 1136 | + } else { |
---|
| 1137 | + val = (cfg->postdiv / 2) - 1; |
---|
| 1138 | + inno_write(inno, 0xad, val); |
---|
| 1139 | + inno_write(inno, 0xaa, 0x0e); |
---|
| 1140 | + } |
---|
| 1141 | + |
---|
| 1142 | + val = cfg->fbdiv & 0xff; |
---|
| 1143 | + inno_write(inno, 0xac, val); |
---|
| 1144 | + val = (cfg->fbdiv >> 8) & BIT(0); |
---|
| 1145 | + inno_update_bits(inno, 0xad, BIT(4), val); |
---|
| 1146 | + |
---|
| 1147 | + /* current bias clk/data 2 */ |
---|
| 1148 | + val = phy_cfg->regs[0] << 4 | phy_cfg->regs[1]; |
---|
| 1149 | + inno_write(inno, 0xbf, val); |
---|
| 1150 | + |
---|
| 1151 | + /* current bias data 1/0 */ |
---|
| 1152 | + val = phy_cfg->regs[1] << 4 | phy_cfg->regs[1]; |
---|
| 1153 | + inno_write(inno, 0xc0, val); |
---|
| 1154 | + |
---|
| 1155 | + /* output voltage */ |
---|
| 1156 | + inno_write(inno, 0xb5, phy_cfg->regs[2]); |
---|
| 1157 | + inno_write(inno, 0xb6, phy_cfg->regs[3]); |
---|
| 1158 | + inno_write(inno, 0xb7, phy_cfg->regs[3]); |
---|
| 1159 | + inno_write(inno, 0xb8, phy_cfg->regs[3]); |
---|
| 1160 | + |
---|
| 1161 | + /* pre-emphasis */ |
---|
| 1162 | + inno_write(inno, 0xbb, phy_cfg->regs[4]); |
---|
| 1163 | + inno_write(inno, 0xbc, phy_cfg->regs[4]); |
---|
| 1164 | + inno_write(inno, 0xbd, phy_cfg->regs[4]); |
---|
| 1165 | + |
---|
| 1166 | + /* enable LDO */ |
---|
| 1167 | + inno_write(inno, 0xb4, 0x7); |
---|
| 1168 | + |
---|
| 1169 | + /* enable serializer */ |
---|
| 1170 | + inno_write(inno, 0xbe, 0x70); |
---|
| 1171 | + |
---|
| 1172 | + inno_write(inno, 0xb2, 0x0f); |
---|
| 1173 | + |
---|
| 1174 | + for (val = 0; val < 5; val++) { |
---|
| 1175 | + if (inno_read(inno, 0xaf) & 1) |
---|
| 1176 | + break; |
---|
| 1177 | + udelay(1000); |
---|
| 1178 | + } |
---|
| 1179 | + if (!(inno_read(inno, 0xaf) & 1)) { |
---|
| 1180 | + dev_err(inno->dev, "HDMI PHY Post PLL unlock\n"); |
---|
| 1181 | + return -ETIMEDOUT; |
---|
| 1182 | + } |
---|
| 1183 | + |
---|
| 1184 | + /* set termination resistance */ |
---|
| 1185 | + if (phy_cfg->tmdsclock > 340000000) { |
---|
| 1186 | + inno_write(inno, 0xc7, 0x76); |
---|
| 1187 | + inno_write(inno, 0xc5, 0x83); |
---|
| 1188 | + inno_write(inno, 0xc8, 0x00); |
---|
| 1189 | + inno_write(inno, 0xc9, 0x2f); |
---|
| 1190 | + inno_write(inno, 0xca, 0x2f); |
---|
| 1191 | + inno_write(inno, 0xcb, 0x2f); |
---|
| 1192 | + } else { |
---|
| 1193 | + inno_write(inno, 0xc7, 0x76); |
---|
| 1194 | + inno_write(inno, 0xc5, 0x83); |
---|
| 1195 | + inno_write(inno, 0xc8, 0x00); |
---|
| 1196 | + inno_write(inno, 0xc9, 0x0f); |
---|
| 1197 | + inno_write(inno, 0xca, 0x0f); |
---|
| 1198 | + inno_write(inno, 0xcb, 0x0f); |
---|
| 1199 | + } |
---|
| 1200 | + |
---|
| 1201 | + /* set TMDS sync detection counter length */ |
---|
| 1202 | + temp = 47520000000; |
---|
| 1203 | + do_div(temp, inno->tmdsclock); |
---|
| 1204 | + inno_write(inno, 0xd8, (temp >> 8) & 0xff); |
---|
| 1205 | + inno_write(inno, 0xd9, temp & 0xff); |
---|
| 1206 | + |
---|
| 1207 | + /* Power up post PLL */ |
---|
| 1208 | + inno_update_bits(inno, 0xaa, 1, 0); |
---|
| 1209 | + /* Power up tmds driver */ |
---|
| 1210 | + inno_update_bits(inno, 0xb0, 4, 4); |
---|
| 1211 | + inno_write(inno, 0xb2, 0x0f); |
---|
| 1212 | + |
---|
| 1213 | + if (phy_cfg->tmdsclock > 340000000) |
---|
| 1214 | + msleep(100); |
---|
| 1215 | + /* set pdata_en to 0/1 */ |
---|
| 1216 | + inno_update_bits(inno, 0x02, 1, 0); |
---|
| 1217 | + inno_update_bits(inno, 0x02, 1, 1); |
---|
| 1218 | + |
---|
| 1219 | + /* Enable PHY IRQ */ |
---|
| 1220 | + inno_write(inno, 0x05, 0x22); |
---|
| 1221 | + inno_write(inno, 0x07, 0x22); |
---|
| 1222 | + inno_write(inno, 0xcc, 0x0f); |
---|
| 1223 | + |
---|
| 1224 | + return 0; |
---|
| 1225 | +} |
---|
| 1226 | + |
---|
| 1227 | +static void inno_hdmi_phy_rk3528_power_off(struct inno_hdmi_phy *inno) |
---|
| 1228 | +{ |
---|
| 1229 | + /* Power off driver */ |
---|
| 1230 | + inno_write(inno, 0xb2, 0); |
---|
| 1231 | + /* Power off serializer */ |
---|
| 1232 | + inno_write(inno, 0xbe, 0); |
---|
| 1233 | + /* Power off post pll */ |
---|
| 1234 | + inno_update_bits(inno, 0xaa, 1, 1); |
---|
| 1235 | + /* Power off rxsense detection circuit */ |
---|
| 1236 | + inno_write(inno, 0xcc, 0); |
---|
| 1237 | + /* Power off band gap */ |
---|
| 1238 | + inno_update_bits(inno, 0xb0, 4, 0); |
---|
| 1239 | + /* Disable PHY IRQ */ |
---|
| 1240 | + inno_write(inno, 0x05, 0); |
---|
| 1241 | + inno_write(inno, 0x07, 0); |
---|
| 1242 | +} |
---|
| 1243 | + |
---|
| 1244 | +static void inno_hdmi_phy_rk3528_init(struct inno_hdmi_phy *inno) |
---|
| 1245 | +{ |
---|
| 1246 | + /* |
---|
| 1247 | + * Use phy internal register control |
---|
| 1248 | + * rxsense/poweron/pllpd/pdataen signal. |
---|
| 1249 | + */ |
---|
| 1250 | + inno_write(inno, 0x02, 0x81); |
---|
| 1251 | + |
---|
| 1252 | + /* if phy had been set in uboot, pll is locked */ |
---|
| 1253 | + if (inno_read(inno, 0xa9) & BIT(0)) { |
---|
| 1254 | + dev_info(inno->dev, "phy had been powered up\n"); |
---|
| 1255 | + inno->phy->power_count = 1; |
---|
| 1256 | + } else { |
---|
| 1257 | + /* manual power down post-PLL */ |
---|
| 1258 | + inno_hdmi_phy_rk3528_power_off(inno); |
---|
| 1259 | + } |
---|
| 1260 | +} |
---|
| 1261 | + |
---|
| 1262 | +static int |
---|
| 1263 | +inno_hdmi_phy_rk3528_pre_pll_update(struct inno_hdmi_phy *inno, |
---|
| 1264 | + const struct pre_pll_config *cfg) |
---|
| 1265 | +{ |
---|
| 1266 | + u32 val; |
---|
| 1267 | + |
---|
| 1268 | + inno_update_bits(inno, 0xb0, 4, 4); |
---|
| 1269 | + inno_write(inno, 0xcc, 0x0f); |
---|
| 1270 | + |
---|
| 1271 | + /* Power on PLL */ |
---|
| 1272 | + inno_update_bits(inno, 0xa0, 1, 0); |
---|
| 1273 | + /* Configure pre-pll */ |
---|
| 1274 | + inno_update_bits(inno, 0xa0, 2, (cfg->vco_div_5_en & 1) << 1); |
---|
| 1275 | + inno_write(inno, 0xa1, cfg->prediv); |
---|
| 1276 | + if (cfg->fracdiv) |
---|
| 1277 | + val = ((cfg->fbdiv >> 8) & 0x0f) | 0xc0; |
---|
| 1278 | + else |
---|
| 1279 | + val = ((cfg->fbdiv >> 8) & 0x0f) | 0xf0; |
---|
| 1280 | + inno_write(inno, 0xa2, val); |
---|
| 1281 | + inno_write(inno, 0xa3, cfg->fbdiv & 0xff); |
---|
| 1282 | + val = (cfg->pclk_div_a & 0x1f) | |
---|
| 1283 | + ((cfg->pclk_div_b & 3) << 5); |
---|
| 1284 | + inno_write(inno, 0xa5, val); |
---|
| 1285 | + val = (cfg->pclk_div_d & 0x1f) | |
---|
| 1286 | + ((cfg->pclk_div_c & 3) << 5); |
---|
| 1287 | + inno_write(inno, 0xa6, val); |
---|
| 1288 | + val = ((cfg->tmds_div_a & 3) << 4) | |
---|
| 1289 | + ((cfg->tmds_div_b & 3) << 2) | |
---|
| 1290 | + (cfg->tmds_div_c & 3); |
---|
| 1291 | + inno_write(inno, 0xa4, val); |
---|
| 1292 | + |
---|
| 1293 | + if (cfg->fracdiv) { |
---|
| 1294 | + val = cfg->fracdiv & 0xff; |
---|
| 1295 | + inno_write(inno, 0xd3, val); |
---|
| 1296 | + val = (cfg->fracdiv >> 8) & 0xff; |
---|
| 1297 | + inno_write(inno, 0xd2, val); |
---|
| 1298 | + val = (cfg->fracdiv >> 16) & 0xff; |
---|
| 1299 | + inno_write(inno, 0xd1, val); |
---|
| 1300 | + } else { |
---|
| 1301 | + inno_write(inno, 0xd3, 0); |
---|
| 1302 | + inno_write(inno, 0xd2, 0); |
---|
| 1303 | + inno_write(inno, 0xd1, 0); |
---|
| 1304 | + } |
---|
| 1305 | + |
---|
| 1306 | + /* Wait for PLL lock */ |
---|
| 1307 | + for (val = 0; val < 5; val++) { |
---|
| 1308 | + if (inno_read(inno, 0xa9) & 1) |
---|
| 1309 | + break; |
---|
| 1310 | + usleep_range(1000, 2000); |
---|
| 1311 | + } |
---|
| 1312 | + if (val == 5) { |
---|
| 1313 | + dev_err(inno->dev, "Pre-PLL unlock\n"); |
---|
| 1314 | + return -ETIMEDOUT; |
---|
| 1315 | + } |
---|
| 1316 | + |
---|
| 1317 | + return 0; |
---|
| 1318 | +} |
---|
| 1319 | + |
---|
| 1320 | +static unsigned long |
---|
| 1321 | +inno_hdmi_rk3528_phy_pll_recalc_rate(struct inno_hdmi_phy *inno, |
---|
| 1322 | + unsigned long parent_rate) |
---|
| 1323 | +{ |
---|
| 1324 | + unsigned long frac; |
---|
| 1325 | + u8 nd, no_a, no_b, no_d; |
---|
| 1326 | + u16 nf; |
---|
| 1327 | + u64 vco = parent_rate; |
---|
| 1328 | + |
---|
| 1329 | + nd = inno_read(inno, 0xa1) & 0x3f; |
---|
| 1330 | + nf = ((inno_read(inno, 0xa2) & 0x0f) << 8) | inno_read(inno, 0xa3); |
---|
| 1331 | + vco *= nf; |
---|
| 1332 | + if ((inno_read(inno, 0xa2) & 0x30) == 0) { |
---|
| 1333 | + frac = inno_read(inno, 0xd3) | |
---|
| 1334 | + (inno_read(inno, 0xd2) << 8) | |
---|
| 1335 | + (inno_read(inno, 0xd1) << 16); |
---|
| 1336 | + vco += DIV_ROUND_CLOSEST(parent_rate * frac, (1 << 24)); |
---|
| 1337 | + } |
---|
| 1338 | + if (inno_read(inno, 0xa0) & 2) { |
---|
| 1339 | + do_div(vco, nd * 5); |
---|
| 1340 | + } else { |
---|
| 1341 | + no_a = inno_read(inno, 0xa5) & 0x1f; |
---|
| 1342 | + no_b = ((inno_read(inno, 0xa5) >> 5) & 7) + 2; |
---|
| 1343 | + no_d = inno_read(inno, 0xa6) & 0x1f; |
---|
| 1344 | + if (no_a == 1) |
---|
| 1345 | + do_div(vco, nd * no_b * no_d * 2); |
---|
| 1346 | + else |
---|
| 1347 | + do_div(vco, nd * no_a * no_d * 2); |
---|
| 1348 | + } |
---|
| 1349 | + |
---|
| 1350 | + frac = vco; |
---|
| 1351 | + inno->pixclock = DIV_ROUND_CLOSEST(frac, 1000) * 1000; |
---|
| 1352 | + |
---|
| 1353 | + dev_dbg(inno->dev, "%s rate %lu\n", __func__, inno->pixclock); |
---|
| 1354 | + |
---|
| 1355 | + return frac; |
---|
| 1356 | +} |
---|
| 1357 | + |
---|
1081 | 1358 | static unsigned long |
---|
1082 | 1359 | inno_hdmi_rk3228_phy_pll_recalc_rate(struct inno_hdmi_phy *inno, |
---|
1083 | 1360 | unsigned long parent_rate) |
---|
.. | .. |
---|
1128 | 1405 | .recalc_rate = inno_hdmi_rk3328_phy_pll_recalc_rate, |
---|
1129 | 1406 | }; |
---|
1130 | 1407 | |
---|
| 1408 | +static const struct inno_hdmi_phy_ops rk3528_hdmi_phy_ops = { |
---|
| 1409 | + .init = inno_hdmi_phy_rk3528_init, |
---|
| 1410 | + .power_on = inno_hdmi_phy_rk3528_power_on, |
---|
| 1411 | + .power_off = inno_hdmi_phy_rk3528_power_off, |
---|
| 1412 | + .pre_pll_update = inno_hdmi_phy_rk3528_pre_pll_update, |
---|
| 1413 | + .recalc_rate = inno_hdmi_rk3528_phy_pll_recalc_rate, |
---|
| 1414 | +}; |
---|
| 1415 | + |
---|
1131 | 1416 | static const struct inno_hdmi_phy_drv_data rk3228_hdmi_phy_drv_data = { |
---|
1132 | 1417 | .dev_type = INNO_HDMI_PHY_RK3228, |
---|
1133 | 1418 | .ops = &rk3228_hdmi_phy_ops, |
---|
.. | .. |
---|
1140 | 1425 | .phy_cfg_table = rk3328_phy_cfg, |
---|
1141 | 1426 | }; |
---|
1142 | 1427 | |
---|
| 1428 | +static const struct inno_hdmi_phy_drv_data rk3528_hdmi_phy_drv_data = { |
---|
| 1429 | + .dev_type = INNO_HDMI_PHY_RK3528, |
---|
| 1430 | + .ops = &rk3528_hdmi_phy_ops, |
---|
| 1431 | + .phy_cfg_table = rk3528_phy_cfg, |
---|
| 1432 | +}; |
---|
| 1433 | + |
---|
1143 | 1434 | static const struct of_device_id inno_hdmi_phy_of_match[] = { |
---|
1144 | 1435 | { .compatible = "rockchip,rk3228-hdmi-phy", |
---|
1145 | 1436 | .data = &rk3228_hdmi_phy_drv_data |
---|
1146 | 1437 | }, |
---|
1147 | 1438 | { .compatible = "rockchip,rk3328-hdmi-phy", |
---|
1148 | 1439 | .data = &rk3328_hdmi_phy_drv_data |
---|
| 1440 | + }, |
---|
| 1441 | + { .compatible = "rockchip,rk3528-hdmi-phy", |
---|
| 1442 | + .data = &rk3528_hdmi_phy_drv_data |
---|
1149 | 1443 | }, |
---|
1150 | 1444 | {} |
---|
1151 | 1445 | }; |
---|
.. | .. |
---|
1244 | 1538 | if (of_get_property(np, "rockchip,phy-table", &val)) { |
---|
1245 | 1539 | if (val % PHY_TAB_LEN || !val) { |
---|
1246 | 1540 | dev_err(dev, "Invalid phy cfg table format!\n"); |
---|
1247 | | - return -EINVAL; |
---|
| 1541 | + ret = -EINVAL; |
---|
| 1542 | + goto err_regsmap; |
---|
1248 | 1543 | } |
---|
1249 | 1544 | |
---|
1250 | 1545 | phy_config = kmalloc(val, GFP_KERNEL); |
---|
1251 | 1546 | if (!phy_config) { |
---|
1252 | 1547 | dev_err(dev, "kmalloc phy table failed\n"); |
---|
1253 | | - return -ENOMEM; |
---|
| 1548 | + ret = -ENOMEM; |
---|
| 1549 | + goto err_regsmap; |
---|
1254 | 1550 | } |
---|
1255 | 1551 | |
---|
1256 | 1552 | phy_table_size = val / PHY_TAB_LEN; |
---|
.. | .. |
---|
1259 | 1555 | GFP_KERNEL); |
---|
1260 | 1556 | if (!inno->phy_cfg) { |
---|
1261 | 1557 | kfree(phy_config); |
---|
1262 | | - return -ENOMEM; |
---|
| 1558 | + ret = -ENOMEM; |
---|
| 1559 | + goto err_regsmap; |
---|
1263 | 1560 | } |
---|
1264 | 1561 | of_property_read_u32_array(np, "rockchip,phy-table", |
---|
1265 | 1562 | phy_config, val / sizeof(u32)); |
---|
.. | .. |
---|
1268 | 1565 | phy_table_size); |
---|
1269 | 1566 | if (ret) { |
---|
1270 | 1567 | kfree(phy_config); |
---|
1271 | | - return ret; |
---|
| 1568 | + goto err_regsmap; |
---|
1272 | 1569 | } |
---|
1273 | 1570 | kfree(phy_config); |
---|
1274 | 1571 | } else { |
---|