/** * Set bit field * @param[in] data raw data * @param[in] mask bit field mask * @param[in] value new value * @return new raw data */ static uint32_t set(uint32_t data, uint32_t mask, uint32_t value) { return ((value << first_bit_set(mask)) & mask) | (data & ~mask); }
/* * __do_dqs_gw_calib: do DQS gating window calibration. * @cbs: pointer to the print_callbacks structure. * Return error code. */ static int __do_dqs_gw_calib(print_callbacks *cbs) { int err; int i, c, f, cnt, max; err = -1; dqs_gw_coarse = 0; dqs_gw_fine = 0; for (i = 0; i < DQS_GW_COARSE_MAX; i++) { dqs_gw[i] = 0; } memset((void *)&cur_pwin, 0, sizeof(struct dqs_gw_pass_win)); memset((void *)&max_pwin, 0, sizeof(struct dqs_gw_pass_win)); /* enable DQS gating window counter */ *(volatile unsigned int *)DRAMC_SPCMD |= (1 << 8); if (ETT_TUNING_FACTOR_NUMS(dqs_gw_tuning_factors) > 0) { ett_recursive_factor_tuning(ETT_TUNING_FACTOR_NUMS(dqs_gw_tuning_factors)-1, dqs_gw_tuning_factors, cbs); } if (max_pwin.size > 0) { /* * DQS GW calibration rule 2: From the lastest pass-index, * decrease 0.5T (i.e; coarse value - 1), * check continuous 4 passed window. */ #if 0 print("max pass-window: coarse_end = %d, fine_end = %d\n", max_pwin.coarse_end, max_pwin.fine_end); #endif c = max_pwin.coarse_end; for (cnt = 0, f = max_pwin.fine_end; cnt < DQS_GW_FINE_CHK_RANGE && f >= 0; cnt++, f--) { if (!(dqs_gw[c - 1] & (1 << f))) { break; } #if 0 print("dqs_gw[%d][%d] = 1'b1\n", c - 1, f); #endif if (f == 0) { if (c == 0) { break; } else { f = DQS_GW_FINE_MAX - 1; c--; } } } if (cnt == DQS_GW_FINE_CHK_RANGE) { print("coarse = %s\n", dqsi_gw_dly_coarse_tbl[max_pwin.coarse_end - 1]); print("fine = %s\n", dqsi_gw_dly_fine_tbl[max_pwin.fine_end]); dqsi_gw_dly_coarse_factor_handler(dqsi_gw_dly_coarse_tbl[max_pwin.coarse_end - 1]); dqsi_gw_dly_fine_factor_handler(dqsi_gw_dly_fine_tbl[max_pwin.fine_end]); err = 0; goto __do_dqs_gw_calib_exit; } /* * DQS GW calibration rule 3: Select a coarse value with the max passed window. * Select a fine value from the middle of the passed window. */ c = 0; for (i = 0; i < DQS_GW_COARSE_MAX; i++) { cnt = nr_bit_set(dqs_gw[i]); #if 0 print("nr_bit_set(dqs_gw[%d]) = %d\n", i, cnt); #endif if (cnt >= max) { max = cnt; c = i; } } cnt = nr_bit_set(dqs_gw[c]); if (cnt) { f = first_bit_set(dqs_gw[c]) + cnt / 2; print("coarse = %s\n", dqsi_gw_dly_coarse_tbl[c]); print("fine = %s\n", dqsi_gw_dly_fine_tbl[f]); dqsi_gw_dly_coarse_factor_handler(dqsi_gw_dly_coarse_tbl[c]); dqsi_gw_dly_fine_factor_handler(dqsi_gw_dly_fine_tbl[f]); err = 0; } } else { print("Cannot find any pass-window\n"); } __do_dqs_gw_calib_exit: return err; }
/** * Get bit field * @param[in] data raw data * @param[in] mask bit field mask * @return bit field value */ static uint32_t get(uint32_t data, uint32_t mask) { return (data & mask) >> first_bit_set(mask); }