1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) Marvell International Ltd. and its affiliates 4 */ 5 6 #include "ddr3_init.h" 7 #include "mv_ddr_regs.h" 8 9 #define VREF_INITIAL_STEP 3 10 #define VREF_SECOND_STEP 1 11 #define VREF_MAX_INDEX 7 12 #define MAX_VALUE (1024 - 1) 13 #define MIN_VALUE (-MAX_VALUE) 14 #define GET_RD_SAMPLE_DELAY(data, cs) ((data >> rd_sample_mask[cs]) & 0xf) 15 16 u32 ca_delay; 17 int ddr3_tip_centr_skip_min_win_check = 0; 18 u8 current_vref[MAX_BUS_NUM][MAX_INTERFACE_NUM]; 19 u8 last_vref[MAX_BUS_NUM][MAX_INTERFACE_NUM]; 20 u16 current_valid_window[MAX_BUS_NUM][MAX_INTERFACE_NUM]; 21 u16 last_valid_window[MAX_BUS_NUM][MAX_INTERFACE_NUM]; 22 u8 lim_vref[MAX_BUS_NUM][MAX_INTERFACE_NUM]; 23 u8 interface_state[MAX_INTERFACE_NUM]; 24 u8 vref_window_size[MAX_INTERFACE_NUM][MAX_BUS_NUM]; 25 u8 vref_window_size_th = 12; 26 27 static u8 pup_st[MAX_BUS_NUM][MAX_INTERFACE_NUM]; 28 29 static u32 rd_sample_mask[] = { 30 0, 31 8, 32 16, 33 24 34 }; 35 36 #define VREF_STEP_1 0 37 #define VREF_STEP_2 1 38 #define VREF_CONVERGE 2 39 40 /* 41 * ODT additional timing 42 */ 43 int ddr3_tip_write_additional_odt_setting(u32 dev_num, u32 if_id) 44 { 45 u32 cs_num = 0, max_read_sample = 0, min_read_sample = 0x1f; 46 u32 data_read[MAX_INTERFACE_NUM] = { 0 }; 47 u32 read_sample[MAX_CS_NUM]; 48 u32 val; 49 u32 pup_index; 50 int max_phase = MIN_VALUE, current_phase; 51 enum hws_access_type access_type = ACCESS_TYPE_UNICAST; 52 u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE); 53 54 CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id, 55 DUNIT_ODT_CTRL_REG, 56 0 << 8, 0x3 << 8)); 57 CHECK_STATUS(ddr3_tip_if_read(dev_num, access_type, if_id, 58 RD_DATA_SMPL_DLYS_REG, 59 data_read, MASK_ALL_BITS)); 60 val = data_read[if_id]; 61 62 for (cs_num = 0; cs_num < MAX_CS_NUM; cs_num++) { 63 read_sample[cs_num] = GET_RD_SAMPLE_DELAY(val, cs_num); 64 65 /* find maximum of read_samples */ 66 if (read_sample[cs_num] >= max_read_sample) { 67 if (read_sample[cs_num] == max_read_sample) 68 max_phase = MIN_VALUE; 69 else 70 max_read_sample = read_sample[cs_num]; 71 72 for (pup_index = 0; 73 pup_index < octets_per_if_num; 74 pup_index++) { 75 CHECK_STATUS(ddr3_tip_bus_read 76 (dev_num, if_id, 77 ACCESS_TYPE_UNICAST, pup_index, 78 DDR_PHY_DATA, 79 RL_PHY_REG(cs_num), 80 &val)); 81 82 current_phase = ((int)val & 0xe0) >> 6; 83 if (current_phase >= max_phase) 84 max_phase = current_phase; 85 } 86 } 87 88 /* find minimum */ 89 if (read_sample[cs_num] < min_read_sample) 90 min_read_sample = read_sample[cs_num]; 91 } 92 93 min_read_sample = min_read_sample - 1; 94 max_read_sample = max_read_sample + 4 + (max_phase + 1) / 2 + 1; 95 if (min_read_sample >= 0xf) 96 min_read_sample = 0xf; 97 if (max_read_sample >= 0x1f) 98 max_read_sample = 0x1f; 99 100 CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id, 101 DDR_ODT_TIMING_LOW_REG, 102 ((min_read_sample - 1) << 12), 103 0xf << 12)); 104 CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id, 105 DDR_ODT_TIMING_LOW_REG, 106 (max_read_sample << 16), 107 0x1f << 16)); 108 109 return MV_OK; 110 } 111 112 int get_valid_win_rx(u32 dev_num, u32 if_id, u8 res[4]) 113 { 114 u32 reg_pup = RESULT_PHY_REG; 115 u32 reg_data; 116 u32 cs_num; 117 int i; 118 119 cs_num = 0; 120 121 /* TBD */ 122 reg_pup += cs_num; 123 124 for (i = 0; i < 4; i++) { 125 CHECK_STATUS(ddr3_tip_bus_read(dev_num, if_id, 126 ACCESS_TYPE_UNICAST, i, 127 DDR_PHY_DATA, reg_pup, 128 ®_data)); 129 res[i] = (reg_data >> RESULT_PHY_RX_OFFS) & 0x1f; 130 } 131 132 return 0; 133 } 134 135 /* 136 * This algorithm deals with the vertical optimum from Voltage point of view 137 * of the sample signal. 138 * Voltage sample point can improve the Eye / window size of the bit and the 139 * pup. 140 * The problem is that it is tune for all DQ the same so there isn't any 141 * PBS like code. 142 * It is more like centralization. 143 * But because we don't have The training SM support we do it a bit more 144 * smart search to save time. 145 */ 146 int ddr3_tip_vref(u32 dev_num) 147 { 148 /* 149 * The Vref register have non linear order. Need to check what will be 150 * in future projects. 151 */ 152 u32 vref_map[8] = { 153 1, 2, 3, 4, 5, 6, 7, 0 154 }; 155 /* State and parameter definitions */ 156 u32 initial_step = VREF_INITIAL_STEP; 157 /* need to be assign with minus ????? */ 158 u32 second_step = VREF_SECOND_STEP; 159 u32 algo_run_flag = 0, currrent_vref = 0; 160 u32 while_count = 0; 161 u32 pup = 0, if_id = 0, num_pup = 0, rep = 0; 162 u32 val = 0; 163 u32 reg_addr = 0xa8; 164 u32 copy_start_pattern, copy_end_pattern; 165 enum hws_result *flow_result = ddr3_tip_get_result_ptr(training_stage); 166 u8 res[4]; 167 u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE); 168 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); 169 170 CHECK_STATUS(ddr3_tip_special_rx(dev_num)); 171 172 /* save start/end pattern */ 173 copy_start_pattern = start_pattern; 174 copy_end_pattern = end_pattern; 175 176 /* set vref as centralization pattern */ 177 start_pattern = PATTERN_VREF; 178 end_pattern = PATTERN_VREF; 179 180 /* init params */ 181 for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) { 182 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id); 183 for (pup = 0; 184 pup < octets_per_if_num; pup++) { 185 current_vref[pup][if_id] = 0; 186 last_vref[pup][if_id] = 0; 187 lim_vref[pup][if_id] = 0; 188 current_valid_window[pup][if_id] = 0; 189 last_valid_window[pup][if_id] = 0; 190 if (vref_window_size[if_id][pup] > 191 vref_window_size_th) { 192 pup_st[pup][if_id] = VREF_CONVERGE; 193 DEBUG_TRAINING_HW_ALG( 194 DEBUG_LEVEL_INFO, 195 ("VREF config, IF[ %d ]pup[ %d ] - Vref tune not requered (%d)\n", 196 if_id, pup, __LINE__)); 197 } else { 198 pup_st[pup][if_id] = VREF_STEP_1; 199 CHECK_STATUS(ddr3_tip_bus_read 200 (dev_num, if_id, 201 ACCESS_TYPE_UNICAST, pup, 202 DDR_PHY_DATA, reg_addr, &val)); 203 CHECK_STATUS(ddr3_tip_bus_write 204 (dev_num, ACCESS_TYPE_UNICAST, 205 if_id, ACCESS_TYPE_UNICAST, 206 pup, DDR_PHY_DATA, reg_addr, 207 (val & (~0xf)) | vref_map[0])); 208 DEBUG_TRAINING_HW_ALG( 209 DEBUG_LEVEL_INFO, 210 ("VREF config, IF[ %d ]pup[ %d ] - Vref = %X (%d)\n", 211 if_id, pup, 212 (val & (~0xf)) | vref_map[0], 213 __LINE__)); 214 } 215 } 216 interface_state[if_id] = 0; 217 } 218 219 /* TODO: Set number of active interfaces */ 220 num_pup = octets_per_if_num * MAX_INTERFACE_NUM; 221 222 while ((algo_run_flag <= num_pup) & (while_count < 10)) { 223 while_count++; 224 for (rep = 1; rep < 4; rep++) { 225 ddr3_tip_centr_skip_min_win_check = 1; 226 ddr3_tip_centralization_rx(dev_num); 227 ddr3_tip_centr_skip_min_win_check = 0; 228 229 /* Read Valid window results only for non converge pups */ 230 for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) { 231 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id); 232 if (interface_state[if_id] != 4) { 233 get_valid_win_rx(dev_num, if_id, res); 234 for (pup = 0; 235 pup < octets_per_if_num; 236 pup++) { 237 VALIDATE_BUS_ACTIVE 238 (tm->bus_act_mask, pup); 239 if (pup_st[pup] 240 [if_id] == 241 VREF_CONVERGE) 242 continue; 243 244 current_valid_window[pup] 245 [if_id] = 246 (current_valid_window[pup] 247 [if_id] * (rep - 1) + 248 1000 * res[pup]) / rep; 249 } 250 } 251 } 252 } 253 254 for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) { 255 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id); 256 DEBUG_TRAINING_HW_ALG( 257 DEBUG_LEVEL_TRACE, 258 ("current_valid_window: IF[ %d ] - ", if_id)); 259 260 for (pup = 0; 261 pup < octets_per_if_num; pup++) { 262 VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup); 263 DEBUG_TRAINING_HW_ALG(DEBUG_LEVEL_TRACE, 264 ("%d ", 265 current_valid_window 266 [pup][if_id])); 267 } 268 DEBUG_TRAINING_HW_ALG(DEBUG_LEVEL_TRACE, ("\n")); 269 } 270 271 /* Compare results and respond as function of state */ 272 for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) { 273 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id); 274 for (pup = 0; 275 pup < octets_per_if_num; pup++) { 276 VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup); 277 DEBUG_TRAINING_HW_ALG(DEBUG_LEVEL_TRACE, 278 ("I/F[ %d ], pup[ %d ] STATE #%d (%d)\n", 279 if_id, pup, 280 pup_st[pup] 281 [if_id], __LINE__)); 282 283 if (pup_st[pup][if_id] == VREF_CONVERGE) 284 continue; 285 286 DEBUG_TRAINING_HW_ALG(DEBUG_LEVEL_TRACE, 287 ("I/F[ %d ], pup[ %d ] CHECK progress - Current %d Last %d, limit VREF %d (%d)\n", 288 if_id, pup, 289 current_valid_window[pup] 290 [if_id], 291 last_valid_window[pup] 292 [if_id], lim_vref[pup] 293 [if_id], __LINE__)); 294 295 /* 296 * The -1 is for solution resolution +/- 1 tap 297 * of ADLL 298 */ 299 if (current_valid_window[pup][if_id] + 200 >= 300 (last_valid_window[pup][if_id])) { 301 if (pup_st[pup][if_id] == VREF_STEP_1) { 302 /* 303 * We stay in the same state and 304 * step just update the window 305 * size (take the max) and Vref 306 */ 307 if (current_vref[pup] 308 [if_id] == VREF_MAX_INDEX) { 309 /* 310 * If we step to the end 311 * and didn't converge 312 * to some particular 313 * better Vref value 314 * define the pup as 315 * converge and step 316 * back to nominal 317 * Vref. 318 */ 319 pup_st[pup] 320 [if_id] = 321 VREF_CONVERGE; 322 algo_run_flag++; 323 interface_state 324 [if_id]++; 325 DEBUG_TRAINING_HW_ALG 326 (DEBUG_LEVEL_TRACE, 327 ("I/F[ %d ], pup[ %d ] VREF_CONVERGE - Vref = %X (%d)\n", 328 if_id, pup, 329 current_vref[pup] 330 [if_id], 331 __LINE__)); 332 } else { 333 /* continue to update the Vref index */ 334 current_vref[pup] 335 [if_id] = 336 ((current_vref[pup] 337 [if_id] + 338 initial_step) > 339 VREF_MAX_INDEX) ? 340 VREF_MAX_INDEX 341 : (current_vref[pup] 342 [if_id] + 343 initial_step); 344 if (current_vref[pup] 345 [if_id] == 346 VREF_MAX_INDEX) { 347 pup_st[pup] 348 [if_id] 349 = 350 VREF_STEP_2; 351 } 352 lim_vref[pup] 353 [if_id] = 354 last_vref[pup] 355 [if_id] = 356 current_vref[pup] 357 [if_id]; 358 } 359 360 last_valid_window[pup] 361 [if_id] = 362 GET_MAX(current_valid_window 363 [pup][if_id], 364 last_valid_window 365 [pup] 366 [if_id]); 367 368 /* update the Vref for next stage */ 369 currrent_vref = 370 current_vref[pup] 371 [if_id]; 372 CHECK_STATUS 373 (ddr3_tip_bus_read 374 (dev_num, if_id, 375 ACCESS_TYPE_UNICAST, pup, 376 DDR_PHY_DATA, reg_addr, 377 &val)); 378 CHECK_STATUS 379 (ddr3_tip_bus_write 380 (dev_num, 381 ACCESS_TYPE_UNICAST, 382 if_id, 383 ACCESS_TYPE_UNICAST, pup, 384 DDR_PHY_DATA, reg_addr, 385 (val & (~0xf)) | 386 vref_map[currrent_vref])); 387 DEBUG_TRAINING_HW_ALG 388 (DEBUG_LEVEL_TRACE, 389 ("VREF config, IF[ %d ]pup[ %d ] - Vref = %X (%d)\n", 390 if_id, pup, 391 (val & (~0xf)) | 392 vref_map[currrent_vref], 393 __LINE__)); 394 } else if (pup_st[pup][if_id] 395 == VREF_STEP_2) { 396 /* 397 * We keep on search back with 398 * the same step size. 399 */ 400 last_valid_window[pup] 401 [if_id] = 402 GET_MAX(current_valid_window 403 [pup][if_id], 404 last_valid_window 405 [pup] 406 [if_id]); 407 last_vref[pup][if_id] = 408 current_vref[pup] 409 [if_id]; 410 411 /* we finish all search space */ 412 if ((current_vref[pup] 413 [if_id] - second_step) == lim_vref[pup][if_id]) { 414 /* 415 * If we step to the end 416 * and didn't converge 417 * to some particular 418 * better Vref value 419 * define the pup as 420 * converge and step 421 * back to nominal 422 * Vref. 423 */ 424 pup_st[pup] 425 [if_id] = 426 VREF_CONVERGE; 427 algo_run_flag++; 428 429 interface_state 430 [if_id]++; 431 432 current_vref[pup] 433 [if_id] = 434 (current_vref[pup] 435 [if_id] - 436 second_step); 437 438 DEBUG_TRAINING_HW_ALG 439 (DEBUG_LEVEL_TRACE, 440 ("I/F[ %d ], pup[ %d ] VREF_CONVERGE - Vref = %X (%d)\n", 441 if_id, pup, 442 current_vref[pup] 443 [if_id], 444 __LINE__)); 445 } else 446 /* we finish all search space */ 447 if (current_vref[pup] 448 [if_id] == 449 lim_vref[pup] 450 [if_id]) { 451 /* 452 * If we step to the end 453 * and didn't converge 454 * to some particular 455 * better Vref value 456 * define the pup as 457 * converge and step 458 * back to nominal 459 * Vref. 460 */ 461 pup_st[pup] 462 [if_id] = 463 VREF_CONVERGE; 464 465 algo_run_flag++; 466 interface_state 467 [if_id]++; 468 DEBUG_TRAINING_HW_ALG 469 (DEBUG_LEVEL_TRACE, 470 ("I/F[ %d ], pup[ %d ] VREF_CONVERGE - Vref = %X (%d)\n", 471 if_id, pup, 472 current_vref[pup] 473 [if_id], 474 __LINE__)); 475 } else { 476 current_vref[pup] 477 [if_id] = 478 current_vref[pup] 479 [if_id] - 480 second_step; 481 } 482 483 /* Update the Vref for next stage */ 484 currrent_vref = 485 current_vref[pup] 486 [if_id]; 487 CHECK_STATUS 488 (ddr3_tip_bus_read 489 (dev_num, if_id, 490 ACCESS_TYPE_UNICAST, pup, 491 DDR_PHY_DATA, reg_addr, 492 &val)); 493 CHECK_STATUS 494 (ddr3_tip_bus_write 495 (dev_num, 496 ACCESS_TYPE_UNICAST, 497 if_id, 498 ACCESS_TYPE_UNICAST, pup, 499 DDR_PHY_DATA, reg_addr, 500 (val & (~0xf)) | 501 vref_map[currrent_vref])); 502 DEBUG_TRAINING_HW_ALG 503 (DEBUG_LEVEL_TRACE, 504 ("VREF config, IF[ %d ]pup[ %d ] - Vref = %X (%d)\n", 505 if_id, pup, 506 (val & (~0xf)) | 507 vref_map[currrent_vref], 508 __LINE__)); 509 } 510 } else { 511 /* we change state and change step */ 512 if (pup_st[pup][if_id] == VREF_STEP_1) { 513 pup_st[pup][if_id] = 514 VREF_STEP_2; 515 lim_vref[pup][if_id] = 516 current_vref[pup] 517 [if_id] - initial_step; 518 last_valid_window[pup] 519 [if_id] = 520 current_valid_window[pup] 521 [if_id]; 522 last_vref[pup][if_id] = 523 current_vref[pup] 524 [if_id]; 525 current_vref[pup][if_id] = 526 last_vref[pup][if_id] - 527 second_step; 528 529 /* Update the Vref for next stage */ 530 CHECK_STATUS 531 (ddr3_tip_bus_read 532 (dev_num, if_id, 533 ACCESS_TYPE_UNICAST, pup, 534 DDR_PHY_DATA, reg_addr, 535 &val)); 536 CHECK_STATUS 537 (ddr3_tip_bus_write 538 (dev_num, 539 ACCESS_TYPE_UNICAST, 540 if_id, 541 ACCESS_TYPE_UNICAST, pup, 542 DDR_PHY_DATA, reg_addr, 543 (val & (~0xf)) | 544 vref_map[current_vref[pup] 545 [if_id]])); 546 DEBUG_TRAINING_HW_ALG 547 (DEBUG_LEVEL_TRACE, 548 ("VREF config, IF[ %d ]pup[ %d ] - Vref = %X (%d)\n", 549 if_id, pup, 550 (val & (~0xf)) | 551 vref_map[current_vref[pup] 552 [if_id]], 553 __LINE__)); 554 555 } else if (pup_st[pup][if_id] == VREF_STEP_2) { 556 /* 557 * The last search was the max 558 * point set value and exit 559 */ 560 CHECK_STATUS 561 (ddr3_tip_bus_read 562 (dev_num, if_id, 563 ACCESS_TYPE_UNICAST, pup, 564 DDR_PHY_DATA, reg_addr, 565 &val)); 566 CHECK_STATUS 567 (ddr3_tip_bus_write 568 (dev_num, 569 ACCESS_TYPE_UNICAST, 570 if_id, 571 ACCESS_TYPE_UNICAST, pup, 572 DDR_PHY_DATA, reg_addr, 573 (val & (~0xf)) | 574 vref_map[last_vref[pup] 575 [if_id]])); 576 DEBUG_TRAINING_HW_ALG 577 (DEBUG_LEVEL_TRACE, 578 ("VREF config, IF[ %d ]pup[ %d ] - Vref = %X (%d)\n", 579 if_id, pup, 580 (val & (~0xf)) | 581 vref_map[last_vref[pup] 582 [if_id]], 583 __LINE__)); 584 pup_st[pup][if_id] = 585 VREF_CONVERGE; 586 algo_run_flag++; 587 interface_state[if_id]++; 588 DEBUG_TRAINING_HW_ALG 589 (DEBUG_LEVEL_TRACE, 590 ("I/F[ %d ], pup[ %d ] VREF_CONVERGE - Vref = %X (%d)\n", 591 if_id, pup, 592 current_vref[pup] 593 [if_id], __LINE__)); 594 } 595 } 596 } 597 } 598 } 599 600 for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) { 601 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id); 602 for (pup = 0; 603 pup < octets_per_if_num; pup++) { 604 VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup); 605 CHECK_STATUS(ddr3_tip_bus_read 606 (dev_num, if_id, 607 ACCESS_TYPE_UNICAST, pup, 608 DDR_PHY_DATA, reg_addr, &val)); 609 DEBUG_TRAINING_HW_ALG( 610 DEBUG_LEVEL_INFO, 611 ("FINAL values: I/F[ %d ], pup[ %d ] - Vref = %X (%d)\n", 612 if_id, pup, val, __LINE__)); 613 } 614 } 615 616 flow_result[if_id] = TEST_SUCCESS; 617 618 /* restore start/end pattern */ 619 start_pattern = copy_start_pattern; 620 end_pattern = copy_end_pattern; 621 622 return 0; 623 } 624 625 /* 626 * CK/CA Delay 627 */ 628 int ddr3_tip_cmd_addr_init_delay(u32 dev_num, u32 adll_tap) 629 { 630 u32 if_id = 0; 631 u32 ck_num_adll_tap = 0, ca_num_adll_tap = 0, data = 0; 632 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); 633 634 /* 635 * ck_delay_table is delaying the of the clock signal only. 636 * (to overcome timing issues between_c_k & command/address signals) 637 */ 638 /* 639 * ca_delay is delaying the of the entire command & Address signals 640 * (include Clock signal to overcome DGL error on the Clock versus 641 * the DQS). 642 */ 643 644 /* Calc ADLL Tap */ 645 if (ck_delay == PARAM_UNDEFINED) 646 DEBUG_TRAINING_HW_ALG( 647 DEBUG_LEVEL_ERROR, 648 ("ERROR: ck_delay is not initialized!\n")); 649 650 for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) { 651 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id); 652 653 /* Calc delay ps in ADLL tap */ 654 ck_num_adll_tap = ck_delay / adll_tap; 655 ca_num_adll_tap = ca_delay / adll_tap; 656 657 data = (ck_num_adll_tap & 0x3f) + 658 ((ca_num_adll_tap & 0x3f) << 10); 659 660 /* 661 * Set the ADLL number to the CK ADLL for Interfaces for 662 * all Pup 663 */ 664 DEBUG_TRAINING_HW_ALG( 665 DEBUG_LEVEL_TRACE, 666 ("ck_num_adll_tap %d ca_num_adll_tap %d adll_tap %d\n", 667 ck_num_adll_tap, ca_num_adll_tap, adll_tap)); 668 669 CHECK_STATUS(ddr3_tip_bus_write(dev_num, ACCESS_TYPE_UNICAST, 670 if_id, ACCESS_TYPE_MULTICAST, 671 PARAM_NOT_CARE, DDR_PHY_CONTROL, 672 0x0, data)); 673 } 674 675 return MV_OK; 676 } 677