static struct clk *_rcg_clk_get_parent(struct rcg_clk *rcg, int has_mnd) { u32 n_regval = 0, m_regval = 0, d_regval = 0; u32 cfg_regval; struct clk_freq_tbl *freq; u32 cmd_rcgr_regval; cmd_rcgr_regval = readl_relaxed(CMD_RCGR_REG(rcg)); if (cmd_rcgr_regval & CMD_RCGR_CONFIG_DIRTY_MASK) return NULL; if (has_mnd) { m_regval = readl_relaxed(M_REG(rcg)); n_regval = readl_relaxed(N_REG(rcg)); d_regval = readl_relaxed(D_REG(rcg)); n_regval |= (n_regval >> 8) ? BM(31, 16) : BM(31, 8); d_regval |= (d_regval >> 8) ? BM(31, 16) : BM(31, 8); } cfg_regval = readl_relaxed(CFG_RCGR_REG(rcg)); cfg_regval &= CFG_RCGR_SRC_SEL_MASK | CFG_RCGR_DIV_MASK | MND_MODE_MASK; has_mnd = (has_mnd) && ((cfg_regval & MND_MODE_MASK) == MND_DUAL_EDGE_MODE_BVAL); cfg_regval &= ~MND_MODE_MASK; for (freq = rcg->freq_tbl; freq->freq_hz != FREQ_END; freq++) { if (freq->div_src_val != cfg_regval) continue; if (has_mnd) { if (freq->m_val != m_regval) continue; if (freq->n_val != n_regval) continue; if (freq->d_val != d_regval) continue; } break; } if (freq->freq_hz == FREQ_END) return NULL; rcg->current_freq = freq; return freq->src_clk; }
static int cxd2850_rd_regs(struct cxd2850_dev *cxd2850, u32 addr, u8 *data, int len) { const struct cxd2850_config *cfg = cxd2850->config; struct i2c_msg msg[2]; int ret; u8 *buf = cxd2850->buf; u8 reg = M_REG(addr); u8 bank = M_BANK(addr); BUG_ON(len > 256); if (bank != cxd2850->bank) { buf[0] = 0x00; buf[1] = bank; msg[0].addr = cfg->dmd_addr; msg[0].flags = 0; msg[0].len = 2; msg[0].buf = buf; ret = i2c_transfer(cxd2850->i2c, &msg[0], 1); if (ret == 1) { ret = 0; } else { dprintk(FE_ERROR, 1, "i2c transfer failed, ret:%d reg:0x%02x", ret, reg); ret = -EREMOTEIO; } cxd2850->bank = bank; } buf[0] = reg; msg[0].addr = cfg->dmd_addr; msg[0].flags = 0; msg[0].len = 1; msg[0].buf = buf; msg[1].addr = cfg->dmd_addr; msg[1].flags = I2C_M_RD; msg[1].len = len; msg[1].buf = buf; ret = i2c_transfer(cxd2850->i2c, msg, 2); if (ret != 2) { dprintk(FE_ERROR, 1, "RD failed ret:%d reg:%02x len:%d", ret, reg, len); ret = -EREMOTEIO; } else { memcpy(data, buf, len); ret = 0; } return ret; }
/* RCG set rate function for clocks with MND & Half Integer Dividers. */ void set_rate_mnd(struct rcg_clk *rcg, struct clk_freq_tbl *nf) { u32 cfg_regval; writel_relaxed(nf->m_val, M_REG(rcg)); writel_relaxed(nf->n_val, N_REG(rcg)); writel_relaxed(nf->d_val, D_REG(rcg)); cfg_regval = readl_relaxed(CFG_RCGR_REG(rcg)); cfg_regval &= ~(CFG_RCGR_DIV_MASK | CFG_RCGR_SRC_SEL_MASK); cfg_regval |= nf->div_src_val; /* Activate or disable the M/N:D divider as necessary */ cfg_regval &= ~MND_MODE_MASK; if (nf->n_val != 0) cfg_regval |= MND_DUAL_EDGE_MODE_BVAL; writel_relaxed(cfg_regval, CFG_RCGR_REG(rcg)); rcg_update_config(rcg); }
void set_rate_mnd(struct rcg_clk *rcg, struct clk_freq_tbl *nf) { u32 cfg_regval; unsigned long flags; spin_lock_irqsave(&local_clock_reg_lock, flags); cfg_regval = readl_relaxed(CFG_RCGR_REG(rcg)); writel_relaxed(nf->m_val, M_REG(rcg)); writel_relaxed(nf->n_val, N_REG(rcg)); writel_relaxed(nf->d_val, D_REG(rcg)); cfg_regval = readl_relaxed(CFG_RCGR_REG(rcg)); cfg_regval &= ~(CFG_RCGR_DIV_MASK | CFG_RCGR_SRC_SEL_MASK); cfg_regval |= nf->div_src_val; cfg_regval &= ~MND_MODE_MASK; if (nf->n_val != 0) cfg_regval |= MND_DUAL_EDGE_MODE_BVAL; writel_relaxed(cfg_regval, CFG_RCGR_REG(rcg)); rcg_update_config(rcg); spin_unlock_irqrestore(&local_clock_reg_lock, flags); }
static struct clk *_rcg_clk_get_parent(struct rcg_clk *rcg, int has_mnd) { u32 n_regval = 0, m_regval = 0, d_regval = 0; u32 cfg_regval; struct clk_freq_tbl *freq; u32 cmd_rcgr_regval; /* Is there a pending configuration? */ cmd_rcgr_regval = readl_relaxed(CMD_RCGR_REG(rcg)); if (cmd_rcgr_regval & CMD_RCGR_CONFIG_DIRTY_MASK) return NULL; /* Get values of m, n, d, div and src_sel registers. */ if (has_mnd) { m_regval = readl_relaxed(M_REG(rcg)); n_regval = readl_relaxed(N_REG(rcg)); d_regval = readl_relaxed(D_REG(rcg)); /* * The n and d values stored in the frequency tables are sign * extended to 32 bits. The n and d values in the registers are * sign extended to 8 or 16 bits. Sign extend the values read * from the registers so that they can be compared to the * values in the frequency tables. */ n_regval |= (n_regval >> 8) ? BM(31, 16) : BM(31, 8); d_regval |= (d_regval >> 8) ? BM(31, 16) : BM(31, 8); } cfg_regval = readl_relaxed(CFG_RCGR_REG(rcg)); cfg_regval &= CFG_RCGR_SRC_SEL_MASK | CFG_RCGR_DIV_MASK | MND_MODE_MASK; /* If mnd counter is present, check if it's in use. */ has_mnd = (has_mnd) && ((cfg_regval & MND_MODE_MASK) == MND_DUAL_EDGE_MODE_BVAL); /* * Clear out the mn counter mode bits since we now want to compare only * the source mux selection and pre-divider values in the registers. */ cfg_regval &= ~MND_MODE_MASK; /* Figure out what rate the rcg is running at */ for (freq = rcg->freq_tbl; freq->freq_hz != FREQ_END; freq++) { if (freq->div_src_val != cfg_regval) continue; if (has_mnd) { if (freq->m_val != m_regval) continue; if (freq->n_val != n_regval) continue; if (freq->d_val != d_regval) continue; } break; } /* No known frequency found */ if (freq->freq_hz == FREQ_END) return NULL; rcg->current_freq = freq; return freq->src_clk; }