static int lpa_check_llb_clear(struct lpa_drv *lpa) { u32 val; val = LPA_REG_READL(lpa, LPA_OBUF_STATUS); return !(val & LPA_OBUF_STATUS_LLB_CLR_BMSK); }
static void lpa_reset(struct lpa_drv *lpa) { u32 status; struct clk *adsp_clk; /* Need to make sure not disable clock while other device is enabled */ adsp_clk = clk_get(NULL, "adsp_clk"); if (!adsp_clk) { MM_ERR("failed to get adsp clk\n"); goto error; } clk_prepare_enable(adsp_clk); lpa_enable_codec(lpa, 0); LPA_REG_WRITEL(lpa, (LPA_OBUF_RESETS_MISR_RESET | LPA_OBUF_RESETS_OVERALL_RESET), LPA_OBUF_RESETS); do { status = LPA_REG_READL(lpa, LPA_OBUF_STATUS); } while (!(status & LPA_OBUF_STATUS_RESET_DONE)); LPA_REG_WRITEL(lpa, LPA_OBUF_ACK_RESET_DONE_BMSK, LPA_OBUF_ACK); mb(); clk_disable_unprepare(adsp_clk); clk_put(adsp_clk); error: return; }
static void lpa_enable_mixing(struct lpa_drv *lpa, bool enable) { u32 val; val = LPA_REG_READL(lpa, LPA_OBUF_CONTROL); val = (enable ? val | LPA_OBUF_CONTROL_LLB_EN_BMSK : val & ~LPA_OBUF_CONTROL_LLB_EN_BMSK); LPA_REG_WRITEL(lpa, val, LPA_OBUF_CONTROL); }
static void lpa_enable_codec(struct lpa_drv *lpa, bool enable) { u32 val; val = LPA_REG_READL(lpa, LPA_OBUF_CODEC); val = enable ? (val | LPA_OBUF_CODEC_CODEC_INTF_EN_BMSK) : (val & ~LPA_OBUF_CODEC_CODEC_INTF_EN_BMSK); val |= LPA_OBUF_CODEC_LOAD_BMSK; LPA_REG_WRITEL(lpa, val, LPA_OBUF_CODEC); }
static void lpa_powerup_mem_bank(struct lpa_drv *lpa, struct lpa_mem_bank_select *bank) { u32 status, val; status = LPA_REG_READL(lpa, LPA_OBUF_MEMORY_CONTROL); val = ((*((u32 *) bank)) << LPA_OBUF_MEM_CTL_PWRUP_SHFT) & LPA_OBUF_MEM_CTL_PWRUP_BMSK; val |= status; LPA_REG_WRITEL(lpa, val, LPA_OBUF_MEMORY_CONTROL); }
static void lpa_clear_llb(struct lpa_drv *lpa) { u32 val; val = LPA_REG_READL(lpa, LPA_OBUF_CONTROL); LPA_REG_WRITEL(lpa, (val | LPA_OBUF_CONTROL_LLB_CLR_CMD_BMSK), LPA_OBUF_CONTROL); lpa_enable_obuf(lpa, LPA_BUF_ID_LLB, 0); while (!lpa_check_llb_clear(lpa)) udelay(100); LPA_REG_WRITEL(lpa, val, LPA_OBUF_CONTROL); }
static void lpa_enable_hlb_wmark(struct lpa_drv *lpa, u32 wmark_ctrl, u32 cpu_id) { u32 val; val = LPA_REG_READL(lpa, LPA_OBUF_WMARK_HLB); val &= ~LPA_OBUF_HLB_WMARK_CTRL_BMSK; val &= ~LPA_OBUF_HLB_WMARK_MAP_BMSK; val |= (wmark_ctrl << LPA_OBUF_HLB_WMARK_CTRL_SHFT) & LPA_OBUF_HLB_WMARK_CTRL_BMSK; val |= (cpu_id << LPA_OBUF_HLB_WMARK_MAP_SHFT) & LPA_OBUF_HLB_WMARK_MAP_BMSK; LPA_REG_WRITEL(lpa, val, LPA_OBUF_WMARK_HLB); }
static void lpa_enable_llb_wmark(struct lpa_drv *lpa, u32 wmark_ctrl, u32 wmark_id, u32 cpu_id) { u32 val; wmark_id = (wmark_id > 3) ? 0 : wmark_id; val = LPA_REG_READL(lpa, LPA_OBUF_WMARK_n_LLB_ADDR(wmark_id)); val &= ~LPA_OBUF_LLB_WMARK_CTRL_BMSK; val &= ~LPA_OBUF_LLB_WMARK_MAP_BMSK; val |= (wmark_ctrl << LPA_OBUF_LLB_WMARK_CTRL_SHFT) & LPA_OBUF_LLB_WMARK_CTRL_BMSK; val |= (cpu_id << LPA_OBUF_LLB_WMARK_MAP_SHFT) & LPA_OBUF_LLB_WMARK_MAP_BMSK; LPA_REG_WRITEL(lpa, val, LPA_OBUF_WMARK_n_LLB_ADDR(wmark_id)); }
int lpa_cmd_enable_codec(struct lpa_drv *lpa, bool enable) { u32 val; struct lpa_mem_bank_select mem_bank; MM_DBG(" %s\n", (enable ? "enable" : "disable")); if (!lpa) return -EINVAL; val = LPA_REG_READL(lpa, LPA_OBUF_CODEC); if (enable) { if (val & LPA_OBUF_CODEC_CODEC_INTF_EN_BMSK) return -EBUSY; /* Power up all memory bank for now */ mem_bank.b0 = 1; mem_bank.b1 = 1; mem_bank.b2 = 1; mem_bank.b3 = 1; mem_bank.b4 = 1; mem_bank.b5 = 1; mem_bank.b6 = 1; mem_bank.b7 = 1; mem_bank.b8 = 1; mem_bank.b9 = 1; mem_bank.b10 = 1; mem_bank.llb = 1; lpa_powerup_mem_bank(lpa, &mem_bank); /*clear LLB*/ lpa_clear_llb(lpa); lpa_enable_codec(lpa, 1); MM_DBG("LPA codec is enabled\n"); } else { if (val & LPA_OBUF_CODEC_CODEC_INTF_EN_BMSK) { lpa_enable_codec(lpa, 0); MM_DBG("LPA codec is disabled\n"); } else MM_ERR("LPA codec is already disable\n"); } mb(); return 0; }
static void lpa_enable_mixer_saturation(struct lpa_drv *lpa, u32 buf_id, bool enable) { u32 val; val = LPA_REG_READL(lpa, LPA_OBUF_CONTROL); switch (buf_id) { case LPA_BUF_ID_LLB: val = enable ? (val | LPA_OBUF_CONTROL_LLB_SAT_EN_BMSK) : (val & ~LPA_OBUF_CONTROL_LLB_SAT_EN_BMSK); break; case LPA_BUF_ID_SB: val = enable ? (val | LPA_OBUF_CONTROL_SB_SAT_EN_BMSK) : (val & ~LPA_OBUF_CONTROL_SB_SAT_EN_BMSK); break; } LPA_REG_WRITEL(lpa, val, LPA_OBUF_CONTROL); }
static u8 lpa_req_wmark_id(struct lpa_drv *lpa) { return (u8) (LPA_REG_READL(lpa, LPA_OBUF_WMARK_ASSIGN) & LPA_OBUF_WMARK_ASSIGN_BMSK); }