/* Mask the bits used by the VCO */ switch (icst->ctype) { case ICST_INTEGRATOR_AP_CM:
mask = INTEGRATOR_AP_CM_BITS;
val = vco.v & 0xFF; if (vco.v & 0x100)
pr_err("ICST error: tried to set bit 8 of VDW\n"); if (vco.s != 1)
pr_err("ICST error: tried to use VOD != 1\n"); if (vco.r != 22)
pr_err("ICST error: tried to use RDW != 22\n"); break; case ICST_INTEGRATOR_AP_SYS:
mask = INTEGRATOR_AP_SYS_BITS;
val = vco.v & 0xFF; if (vco.v & 0x100)
pr_err("ICST error: tried to set bit 8 of VDW\n"); if (vco.s != 3)
pr_err("ICST error: tried to use VOD != 1\n"); if (vco.r != 46)
pr_err("ICST error: tried to use RDW != 22\n"); break; case ICST_INTEGRATOR_CP_CM_CORE:
mask = INTEGRATOR_CP_CM_CORE_BITS; /* Uses 12 bits */
val = (vco.v & 0xFF) | vco.s << 8; if (vco.v & 0x100)
pr_err("ICST error: tried to set bit 8 of VDW\n"); if (vco.r != 22)
pr_err("ICST error: tried to use RDW != 22\n"); break; case ICST_INTEGRATOR_CP_CM_MEM:
mask = INTEGRATOR_CP_CM_MEM_BITS; /* Uses 12 bits */
val = ((vco.v & 0xFF) << 12) | (vco.s << 20); if (vco.v & 0x100)
pr_err("ICST error: tried to set bit 8 of VDW\n"); if (vco.r != 22)
pr_err("ICST error: tried to use RDW != 22\n"); break; default: /* Regular auxiliary oscillator */
mask = VERSATILE_AUX_OSC_BITS;
val = vco.v | (vco.r << 9) | (vco.s << 16); break;
}
pr_debug("ICST: new val = 0x%08x\n", val);
/* This magic unlocks the VCO so it can be controlled */
ret = regmap_write(icst->map, icst->lockreg_off, VERSATILE_LOCK_VAL); if (ret) return ret;
ret = regmap_update_bits(icst->map, icst->vcoreg_off, mask, val); if (ret) return ret; /* This locks the VCO again */
ret = regmap_write(icst->map, icst->lockreg_off, 0); if (ret) return ret; return0;
}
if (parent_rate)
icst->params->ref = parent_rate;
ret = vco_get(icst, &vco); if (ret) {
pr_err("ICST: could not get VCO setting\n"); return0;
}
icst->rate = icst_hz(icst->params, vco); return icst->rate;
}
if (icst->ctype == ICST_INTEGRATOR_AP_CM ||
icst->ctype == ICST_INTEGRATOR_CP_CM_CORE) { if (rate <= 12000000) return12000000; if (rate >= 160000000) return160000000; /* Slam to closest megahertz */ return DIV_ROUND_CLOSEST(rate, 1000000) * 1000000;
}
if (icst->ctype == ICST_INTEGRATOR_CP_CM_MEM) { if (rate <= 6000000) return6000000; if (rate >= 66000000) return66000000; /* Slam to closest 0.5 megahertz */ return DIV_ROUND_CLOSEST(rate, 500000) * 500000;
}
if (icst->ctype == ICST_INTEGRATOR_AP_SYS) { /* Divides between 3 and 50 MHz in steps of 0.25 MHz */ if (rate <= 3000000) return3000000; if (rate >= 50000000) return5000000; /* Slam to closest 0.25 MHz */ return DIV_ROUND_CLOSEST(rate, 250000) * 250000;
}
if (icst->ctype == ICST_INTEGRATOR_AP_PCI) { /* *Ifwe'rebeloworlessthanhalfwayfrom25to33MHz *select25MHz
*/ if (rate <= 25000000 || rate < 29000000) return25000000; /* Else just return the default frequency */ return33000000;
}
if (icst->ctype == ICST_INTEGRATOR_AP_PCI) { /* This clock is especially primitive */ unsignedint val; int ret;
if (rate == 25000000) {
val = 0;
} elseif (rate == 33000000) {
val = INTEGRATOR_AP_PCI_25_33_MHZ;
} else {
pr_err("ICST: cannot set PCI frequency %lu\n",
rate); return -EINVAL;
}
ret = regmap_write(icst->map, icst->lockreg_off,
VERSATILE_LOCK_VAL); if (ret) return ret;
ret = regmap_update_bits(icst->map, icst->vcoreg_off,
INTEGRATOR_AP_PCI_25_33_MHZ,
val); if (ret) return ret; /* This locks the VCO again */
ret = regmap_write(icst->map, icst->lockreg_off, 0); if (ret) return ret; return0;
}
/* We do not release this reference, we are using it perpetually */
parent = of_get_parent(np); if (!parent) {
pr_err("no parent node for syscon ICST clock\n"); return;
}
map = syscon_node_to_regmap(parent); if (IS_ERR(map)) {
pr_err("no regmap for syscon ICST clock parent\n"); return;
}
if (of_property_read_u32(np, "reg", &icst_desc.vco_offset) &&
of_property_read_u32(np, "vco-offset", &icst_desc.vco_offset)) {
pr_err("no VCO register offset for ICST clock\n"); return;
} if (of_property_read_u32(np, "lock-offset", &icst_desc.lock_offset)) {
pr_err("no lock register offset for ICST clock\n"); return;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.