|
@@ -58,3 +58,75 @@ static void __iomem *_cm_bases[OMAP4_MAX_PRCM_PARTITIONS];
|
|
|
* omap_cm_base_init - Populates the cm partitions
|
|
|
*
|
|
|
* Populates the base addresses of the _cm_bases
|
|
|
+ * array used for read/write of cm module registers.
|
|
|
+ */
|
|
|
+void omap_cm_base_init(void)
|
|
|
+{
|
|
|
+ _cm_bases[OMAP4430_PRM_PARTITION] = prm_base;
|
|
|
+ _cm_bases[OMAP4430_CM1_PARTITION] = cm_base;
|
|
|
+ _cm_bases[OMAP4430_CM2_PARTITION] = cm2_base;
|
|
|
+ _cm_bases[OMAP4430_PRCM_MPU_PARTITION] = prcm_mpu_base;
|
|
|
+}
|
|
|
+
|
|
|
+/* Private functions */
|
|
|
+
|
|
|
+/**
|
|
|
+ * _clkctrl_idlest - read a CM_*_CLKCTRL register; mask & shift IDLEST bitfield
|
|
|
+ * @part: PRCM partition ID that the CM_CLKCTRL register exists in
|
|
|
+ * @inst: CM instance register offset (*_INST macro)
|
|
|
+ * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
|
|
|
+ * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
|
|
|
+ *
|
|
|
+ * Return the IDLEST bitfield of a CM_*_CLKCTRL register, shifted down to
|
|
|
+ * bit 0.
|
|
|
+ */
|
|
|
+static u32 _clkctrl_idlest(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs)
|
|
|
+{
|
|
|
+ u32 v = omap4_cminst_read_inst_reg(part, inst, clkctrl_offs);
|
|
|
+ v &= OMAP4430_IDLEST_MASK;
|
|
|
+ v >>= OMAP4430_IDLEST_SHIFT;
|
|
|
+ return v;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * _is_module_ready - can module registers be accessed without causing an abort?
|
|
|
+ * @part: PRCM partition ID that the CM_CLKCTRL register exists in
|
|
|
+ * @inst: CM instance register offset (*_INST macro)
|
|
|
+ * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
|
|
|
+ * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
|
|
|
+ *
|
|
|
+ * Returns true if the module's CM_*_CLKCTRL.IDLEST bitfield is either
|
|
|
+ * *FUNCTIONAL or *INTERFACE_IDLE; false otherwise.
|
|
|
+ */
|
|
|
+static bool _is_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs)
|
|
|
+{
|
|
|
+ u32 v;
|
|
|
+
|
|
|
+ v = _clkctrl_idlest(part, inst, cdoffs, clkctrl_offs);
|
|
|
+
|
|
|
+ return (v == CLKCTRL_IDLEST_FUNCTIONAL ||
|
|
|
+ v == CLKCTRL_IDLEST_INTERFACE_IDLE) ? true : false;
|
|
|
+}
|
|
|
+
|
|
|
+/* Public functions */
|
|
|
+
|
|
|
+/* Read a register in a CM instance */
|
|
|
+u32 omap4_cminst_read_inst_reg(u8 part, s16 inst, u16 idx)
|
|
|
+{
|
|
|
+ BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS ||
|
|
|
+ part == OMAP4430_INVALID_PRCM_PARTITION ||
|
|
|
+ !_cm_bases[part]);
|
|
|
+ return __raw_readl(_cm_bases[part] + inst + idx);
|
|
|
+}
|
|
|
+
|
|
|
+/* Write into a register in a CM instance */
|
|
|
+void omap4_cminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx)
|
|
|
+{
|
|
|
+ BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS ||
|
|
|
+ part == OMAP4430_INVALID_PRCM_PARTITION ||
|
|
|
+ !_cm_bases[part]);
|
|
|
+ __raw_writel(val, _cm_bases[part] + inst + idx);
|
|
|
+}
|
|
|
+
|
|
|
+/* Read-modify-write a register in CM1. Caller must lock */
|
|
|
+u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, s16 inst,
|