Lines Matching refs:fll
3474 static int madera_find_fratio(struct madera_fll *fll, unsigned int fref,
3477 switch (fll->madera->type) {
3479 switch (fll->madera->rev) {
3488 fll->fout,
3500 return madera_find_main_fratio(fref, fll->fout, fratio);
3504 static int madera_calc_fratio(struct madera_fll *fll,
3524 init_ratio = madera_find_fratio(fll, fref, sync, &cfg->fratio);
3526 madera_fll_err(fll, "Unable to find FRATIO for fref=%uHz\n",
3534 switch (fll->madera->type) {
3536 switch (fll->madera->rev) {
3566 if (fll->fout % (ratio * fref)) {
3582 if (fll->fout % (ratio * fref)) {
3592 init_ratio = madera_find_fratio(fll, fref, sync, NULL);
3595 madera_fll_warn(fll, "Falling back to integer mode operation\n");
3600 static int madera_find_fll_gain(struct madera_fll *fll,
3616 madera_fll_err(fll, "Unable to find gain for fref=%uHz\n", fref);
3621 static int madera_calc_fll(struct madera_fll *fll,
3630 madera_fll_dbg(fll, "fref=%u Fout=%u fvco=%u\n",
3631 fref, fll->fout, fll->fout * MADERA_FLL_VCO_MULT);
3634 ratio = madera_calc_fratio(fll, cfg, fref, sync);
3641 cfg->n = fll->fout / (ratio * fref);
3643 if (fll->fout % (ratio * fref)) {
3644 gcd_fll = gcd(fll->fout, ratio * fref);
3645 madera_fll_dbg(fll, "GCD=%u\n", gcd_fll);
3647 cfg->theta = (fll->fout - (cfg->n * ratio * fref))
3665 switch (fll->madera->type) {
3667 switch (fll->madera->rev) {
3701 ret = madera_find_fll_gain(fll, cfg, fref, gains, n_gains);
3705 madera_fll_dbg(fll, "N=%d THETA=%d LAMBDA=%d\n",
3707 madera_fll_dbg(fll, "FRATIO=0x%x(%d) REFCLK_DIV=0x%x(%d)\n",
3709 madera_fll_dbg(fll, "GAIN=0x%x(%d)\n", cfg->gain, 1 << cfg->gain);
3771 static int madera_is_enabled_fll(struct madera_fll *fll, int base)
3773 struct madera *madera = fll->madera;
3780 madera_fll_err(fll, "Failed to read current state: %d\n", ret);
3787 static int madera_wait_for_fll(struct madera_fll *fll, bool requested)
3789 struct madera *madera = fll->madera;
3794 madera_fll_dbg(fll, "Waiting for FLL...\n");
3798 status = val & (MADERA_FLL1_LOCK_STS1 << (fll->id - 1));
3815 madera_fll_warn(fll, "Timed out waiting for lock\n");
3820 static bool madera_set_fll_phase_integrator(struct madera_fll *fll,
3833 regmap_update_bits_check(fll->madera->regmap,
3834 fll->base + MADERA_FLL_EFS_2_OFFS,
3842 static int madera_set_fll_clks_reg(struct madera_fll *fll, bool ena,
3846 struct madera *madera = fll->madera;
3853 madera_fll_err(fll, "Failed to read current source: %d\n",
3882 static inline int madera_set_fll_clks(struct madera_fll *fll, int base, bool ena)
3884 return madera_set_fll_clks_reg(fll, ena,
3890 static inline int madera_set_fllao_clks(struct madera_fll *fll, int base, bool ena)
3892 return madera_set_fll_clks_reg(fll, ena,
3898 static inline int madera_set_fllhj_clks(struct madera_fll *fll, int base, bool ena)
3900 return madera_set_fll_clks_reg(fll, ena,
3906 static void madera_disable_fll(struct madera_fll *fll)
3908 struct madera *madera = fll->madera;
3914 sync_base = fll->base + CS47L35_FLL_SYNCHRONISER_OFFS;
3917 sync_base = fll->base + MADERA_FLL_SYNCHRONISER_OFFS;
3921 madera_fll_dbg(fll, "Disabling FLL\n");
3924 fll->base + MADERA_FLL_CONTROL_1_OFFS,
3927 fll->base + MADERA_FLL_CONTROL_1_OFFS,
3933 fll->base + MADERA_FLL_CONTROL_1_OFFS,
3936 madera_wait_for_fll(fll, false);
3939 madera_set_fll_clks(fll, sync_base, false);
3942 madera_set_fll_clks(fll, fll->base, false);
3947 static int madera_enable_fll(struct madera_fll *fll)
3949 struct madera *madera = fll->madera;
3951 int already_enabled = madera_is_enabled_fll(fll, fll->base);
3961 if (fll->ref_src < 0 || fll->ref_freq == 0) {
3962 madera_fll_err(fll, "No REFCLK\n");
3967 madera_fll_dbg(fll, "Enabling FLL, initially %s\n",
3970 if (fll->fout < MADERA_FLL_MIN_FOUT ||
3971 fll->fout > MADERA_FLL_MAX_FOUT) {
3972 madera_fll_err(fll, "invalid fout %uHz\n", fll->fout);
3979 sync_base = fll->base + CS47L35_FLL_SYNCHRONISER_OFFS;
3982 sync_base = fll->base + MADERA_FLL_SYNCHRONISER_OFFS;
3986 sync_enabled = madera_is_enabled_fll(fll, sync_base);
3992 regmap_update_bits(fll->madera->regmap,
3993 fll->base + MADERA_FLL_CONTROL_1_OFFS,
3997 regmap_update_bits(fll->madera->regmap,
3998 fll->base + MADERA_FLL_CONTROL_7_OFFS,
4002 madera_set_fll_clks(fll, sync_base, false);
4003 madera_set_fll_clks(fll, fll->base, false);
4007 if (fll->sync_src >= 0) {
4008 ret = madera_calc_fll(fll, &cfg, fll->sync_freq, true);
4013 &cfg, fll->sync_src,
4019 madera_fll_warn(fll, "Synchroniser changed on active FLL\n");
4022 ret = madera_calc_fll(fll, &cfg, fll->ref_freq, false);
4030 switch (fll->madera->type) {
4032 switch (fll->madera->rev) {
4038 madera_set_fll_phase_integrator(fll, &cfg,
4052 fll_change |= madera_set_fll_phase_integrator(fll, &cfg,
4061 fll_change |= madera_write_fll(madera, fll->base,
4062 &cfg, fll->ref_src,
4069 if (have_sync && fll->sync_freq > 100000)
4083 madera_set_fll_clks(fll, sync_base, true);
4090 madera_set_fll_clks(fll, fll->base, true);
4092 fll->base + MADERA_FLL_CONTROL_1_OFFS,
4097 fll->base + MADERA_FLL_CONTROL_1_OFFS,
4101 madera_wait_for_fll(fll, true);
4107 madera_disable_fll(fll);
4112 static int madera_apply_fll(struct madera_fll *fll)
4114 if (fll->fout) {
4115 return madera_enable_fll(fll);
4117 madera_disable_fll(fll);
4122 int madera_set_fll_syncclk(struct madera_fll *fll, int source,
4131 if (fll->sync_src == source && fll->sync_freq == fref)
4134 fll->sync_src = source;
4135 fll->sync_freq = fref;
4137 return madera_apply_fll(fll);
4141 int madera_set_fll_refclk(struct madera_fll *fll, int source,
4146 if (fll->ref_src == source &&
4147 fll->ref_freq == fref && fll->fout == fout)
4154 if (fout && fout != fll->fout) {
4155 ret = madera_is_enabled_fll(fll, fll->base);
4160 madera_fll_err(fll, "Can't change Fout on active FLL\n");
4165 fll->ref_src = source;
4166 fll->ref_freq = fref;
4167 fll->fout = fout;
4169 return madera_apply_fll(fll);
4174 struct madera_fll *fll)
4176 fll->id = id;
4177 fll->base = base;
4178 fll->madera = madera;
4179 fll->ref_src = MADERA_FLL_SRC_NONE;
4180 fll->sync_src = MADERA_FLL_SRC_NONE;
4183 fll->base + MADERA_FLL_CONTROL_1_OFFS,
4239 static int madera_enable_fll_ao(struct madera_fll *fll,
4243 struct madera *madera = fll->madera;
4244 int already_enabled = madera_is_enabled_fll(fll, fll->base);
4254 madera_fll_dbg(fll, "Enabling FLL_AO, initially %s\n",
4258 regmap_update_bits(fll->madera->regmap,
4259 fll->base + MADERA_FLLAO_CONTROL_1_OFFS,
4263 madera_set_fllao_clks(fll, fll->base, false);
4268 /* modify the patch to apply fll->ref_src as input clock */
4271 val |= (fll->ref_src << MADERA_FLL_AO_REFCLK_SRC_SHIFT)
4278 madera_set_fllao_clks(fll, fll->base, true);
4281 fll->base + MADERA_FLLAO_CONTROL_1_OFFS,
4286 fll->base + MADERA_FLLAO_CONTROL_1_OFFS,
4290 madera_wait_for_fll(fll, true);
4295 static int madera_disable_fll_ao(struct madera_fll *fll)
4297 struct madera *madera = fll->madera;
4300 madera_fll_dbg(fll, "Disabling FLL_AO\n");
4303 fll->base + MADERA_FLLAO_CONTROL_1_OFFS,
4306 fll->base + MADERA_FLLAO_CONTROL_1_OFFS,
4309 madera_wait_for_fll(fll, false);
4320 fll->base + MADERA_FLLAO_CONTROL_2_OFFS,
4324 madera_set_fllao_clks(fll, fll->base, false);
4331 int madera_set_fll_ao_refclk(struct madera_fll *fll, int source,
4339 if (fll->ref_src == source &&
4340 fll->ref_freq == fin && fll->fout == fout)
4343 madera_fll_dbg(fll, "Change FLL_AO refclk to fin=%u fout=%u source=%d\n",
4346 if (fout && (fll->ref_freq != fin || fll->fout != fout)) {
4354 madera_fll_err(fll,
4363 fll->ref_src = source;
4364 fll->ref_freq = fin;
4365 fll->fout = fout;
4368 ret = madera_enable_fll_ao(fll, patch, patch_size);
4370 madera_disable_fll_ao(fll);
4376 static int madera_fllhj_disable(struct madera_fll *fll)
4378 struct madera *madera = fll->madera;
4381 madera_fll_dbg(fll, "Disabling FLL\n");
4390 fll->base + MADERA_FLL_CONTROL_11_OFFS,
4393 fll->base + MADERA_FLL_CONTROL_1_OFFS,
4396 fll->base + MADERA_FLL_CONTROL_1_OFFS,
4399 madera_wait_for_fll(fll, false);
4401 /* ctrl_up gates the writes to all the fll's registers, setting it to 0
4403 * enables the fll then ctrl_up is the last bit that is configured
4404 * by the fll enable code rather than the cache sync operation which
4405 * would have updated it much earlier before writing out all fll
4409 fll->base + MADERA_FLL_CONTROL_2_OFFS,
4413 madera_set_fllhj_clks(fll, fll->base, false);
4420 static int madera_fllhj_apply(struct madera_fll *fll, int fin)
4422 struct madera *madera = fll->madera;
4428 madera_fll_dbg(fll, "fin=%d, fout=%d\n", fin, fll->fout);
4440 fout = fll->fout;
4463 fout = fll->fout * 6;
4479 madera_fll_dbg(fll, "refdiv=%d, fref=%d, frac:%d\n",
4485 madera_fll_err(fll, "FBDIV (%d) must be >= 1\n", fbdiv);
4492 madera_fll_err(fll, "FBDIV (%u) >= 1024\n", fbdiv);
4497 madera_fll_dbg(fll, "lockdet=%d, hp=0x%x, fbdiv:%d\n",
4507 madera_fll_dbg(fll, "fll_n=%d, gcd=%d, theta=%d, lambda=%d\n",
4512 madera_fll_err(fll, "N not in valid %s mode range %d-%d: %d\n",
4518 madera_fll_err(fll, "Invalid fbdiv for %s mode (%u)\n",
4525 fll->base + MADERA_FLL_CONTROL_2_OFFS,
4528 fll->base + MADERA_FLL_CONTROL_3_OFFS,
4532 fll->base + MADERA_FLL_CONTROL_4_OFFS,
4536 fll->base + MADERA_FLL_CONTROL_5_OFFS,
4540 fll->base + MADERA_FLL_CONTROL_6_OFFS,
4544 fll->base + MADERA_FLL_GAIN_OFFS,
4550 fll->base + MADERA_FLL_CONTROL_10_OFFS,
4554 fll->base + MADERA_FLL_CONTROL_11_OFFS,
4558 fll->base + MADERA_FLL1_DIGITAL_TEST_1_OFFS,
4566 static int madera_fllhj_enable(struct madera_fll *fll)
4568 struct madera *madera = fll->madera;
4569 int already_enabled = madera_is_enabled_fll(fll, fll->base);
4578 madera_fll_dbg(fll, "Enabling FLL, initially %s\n",
4582 regmap_update_bits(fll->madera->regmap,
4583 fll->base + MADERA_FLL_CONTROL_1_OFFS,
4588 madera_set_fllhj_clks(fll, fll->base, false);
4591 ret = madera_fllhj_apply(fll, fll->ref_freq);
4593 madera_fll_err(fll, "Failed to set FLL: %d\n", ret);
4597 fll->base + MADERA_FLL_CONTROL_1_OFFS,
4599 fll->ref_src << CS47L92_FLL1_REFCLK_SRC_SHIFT);
4601 madera_set_fllhj_clks(fll, fll->base, true);
4604 fll->base + MADERA_FLL_CONTROL_1_OFFS,
4610 fll->base + MADERA_FLL_CONTROL_11_OFFS,
4615 fll->base + MADERA_FLL_CONTROL_2_OFFS,
4621 fll->base + MADERA_FLL_CONTROL_1_OFFS,
4626 madera_wait_for_fll(fll, true);
4631 static int madera_fllhj_validate(struct madera_fll *fll,
4636 madera_fll_err(fll, "fllout set without valid input clk\n");
4640 if (fll->fout && fout != fll->fout) {
4641 madera_fll_err(fll, "Can't change output on active FLL\n");
4646 madera_fll_err(fll, "Can't scale %dMHz to <=13MHz\n", ref_in);
4653 int madera_fllhj_set_refclk(struct madera_fll *fll, int source,
4660 * 2x the calculated fll out.
4665 if (fll->ref_src == source && fll->ref_freq == fin &&
4666 fll->fout == fout)
4669 if (fin && fout && madera_fllhj_validate(fll, fin, fout))
4672 fll->ref_src = source;
4673 fll->ref_freq = fin;
4674 fll->fout = fout;
4677 ret = madera_fllhj_enable(fll);
4679 madera_fllhj_disable(fll);