Skip to content

Commit

Permalink
ASoC: mediatek: mt8188: support audsys clock
Browse files Browse the repository at this point in the history
Add mt8188 audio cg clock control. Audio clock gates are registered to CCF
for reference count and clock parent management.

Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Link: https://lore.kernel.org/r/20230116034131.23943-4-trevor.wu@mediatek.com
Signed-off-by: Mark Brown <broonie@kernel.org>
  • Loading branch information
Trevor Wu authored and Mark Brown committed Jan 16, 2023
1 parent f90f0dd commit fdd4e1a
Show file tree
Hide file tree
Showing 3 changed files with 303 additions and 0 deletions.
205 changes: 205 additions & 0 deletions sound/soc/mediatek/mt8188/mt8188-audsys-clk.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
// SPDX-License-Identifier: GPL-2.0
/*
* mt8188-audsys-clk.c -- MediaTek 8188 audsys clock control
*
* Copyright (c) 2022 MediaTek Inc.
* Author: Chun-Chia Chiu <chun-chia.chiu@mediatek.com>
*/

#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/clkdev.h>
#include "mt8188-afe-common.h"
#include "mt8188-audsys-clk.h"
#include "mt8188-audsys-clkid.h"
#include "mt8188-reg.h"

struct afe_gate {
int id;
const char *name;
const char *parent_name;
int reg;
u8 bit;
const struct clk_ops *ops;
unsigned long flags;
u8 cg_flags;
};

#define GATE_AFE_FLAGS(_id, _name, _parent, _reg, _bit, _flags, _cgflags) {\
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.reg = _reg, \
.bit = _bit, \
.flags = _flags, \
.cg_flags = _cgflags, \
}

#define GATE_AFE(_id, _name, _parent, _reg, _bit) \
GATE_AFE_FLAGS(_id, _name, _parent, _reg, _bit, \
CLK_SET_RATE_PARENT, CLK_GATE_SET_TO_DISABLE)

#define GATE_AUD0(_id, _name, _parent, _bit) \
GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON0, _bit)

#define GATE_AUD1(_id, _name, _parent, _bit) \
GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON1, _bit)

#define GATE_AUD3(_id, _name, _parent, _bit) \
GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON3, _bit)

#define GATE_AUD4(_id, _name, _parent, _bit) \
GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON4, _bit)

#define GATE_AUD5(_id, _name, _parent, _bit) \
GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON5, _bit)

#define GATE_AUD6(_id, _name, _parent, _bit) \
GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON6, _bit)

static const struct afe_gate aud_clks[CLK_AUD_NR_CLK] = {
/* AUD0 */
GATE_AUD0(CLK_AUD_AFE, "aud_afe", "top_a1sys_hp", 2),
GATE_AUD0(CLK_AUD_LRCK_CNT, "aud_lrck_cnt", "top_a1sys_hp", 4),
GATE_AUD0(CLK_AUD_SPDIFIN_TUNER_APLL, "aud_spdifin_tuner_apll", "top_apll4", 10),
GATE_AUD0(CLK_AUD_SPDIFIN_TUNER_DBG, "aud_spdifin_tuner_dbg", "top_apll4", 11),
GATE_AUD0(CLK_AUD_UL_TML, "aud_ul_tml", "top_a1sys_hp", 18),
GATE_AUD0(CLK_AUD_APLL1_TUNER, "aud_apll1_tuner", "top_apll1", 19),
GATE_AUD0(CLK_AUD_APLL2_TUNER, "aud_apll2_tuner", "top_apll2", 20),
GATE_AUD0(CLK_AUD_TOP0_SPDF, "aud_top0_spdf", "top_aud_iec_clk", 21),
GATE_AUD0(CLK_AUD_APLL, "aud_apll", "top_apll1", 23),
GATE_AUD0(CLK_AUD_APLL2, "aud_apll2", "top_apll2", 24),
GATE_AUD0(CLK_AUD_DAC, "aud_dac", "top_a1sys_hp", 25),
GATE_AUD0(CLK_AUD_DAC_PREDIS, "aud_dac_predis", "top_a1sys_hp", 26),
GATE_AUD0(CLK_AUD_TML, "aud_tml", "top_a1sys_hp", 27),
GATE_AUD0(CLK_AUD_ADC, "aud_adc", "top_a1sys_hp", 28),
GATE_AUD0(CLK_AUD_DAC_HIRES, "aud_dac_hires", "top_audio_h", 31),

/* AUD1 */
GATE_AUD1(CLK_AUD_A1SYS_HP, "aud_a1sys_hp", "top_a1sys_hp", 2),
GATE_AUD1(CLK_AUD_AFE_DMIC1, "aud_afe_dmic1", "top_a1sys_hp", 10),
GATE_AUD1(CLK_AUD_AFE_DMIC2, "aud_afe_dmic2", "top_a1sys_hp", 11),
GATE_AUD1(CLK_AUD_AFE_DMIC3, "aud_afe_dmic3", "top_a1sys_hp", 12),
GATE_AUD1(CLK_AUD_AFE_DMIC4, "aud_afe_dmic4", "top_a1sys_hp", 13),
GATE_AUD1(CLK_AUD_AFE_26M_DMIC_TM, "aud_afe_26m_dmic_tm", "top_a1sys_hp", 14),
GATE_AUD1(CLK_AUD_UL_TML_HIRES, "aud_ul_tml_hires", "top_audio_h", 16),
GATE_AUD1(CLK_AUD_ADC_HIRES, "aud_adc_hires", "top_audio_h", 17),

/* AUD3 */
GATE_AUD3(CLK_AUD_LINEIN_TUNER, "aud_linein_tuner", "top_apll5", 5),
GATE_AUD3(CLK_AUD_EARC_TUNER, "aud_earc_tuner", "top_apll3", 7),

/* AUD4 */
GATE_AUD4(CLK_AUD_I2SIN, "aud_i2sin", "top_a1sys_hp", 0),
GATE_AUD4(CLK_AUD_TDM_IN, "aud_tdm_in", "top_a1sys_hp", 1),
GATE_AUD4(CLK_AUD_I2S_OUT, "aud_i2s_out", "top_a1sys_hp", 6),
GATE_AUD4(CLK_AUD_TDM_OUT, "aud_tdm_out", "top_a1sys_hp", 7),
GATE_AUD4(CLK_AUD_HDMI_OUT, "aud_hdmi_out", "top_a1sys_hp", 8),
GATE_AUD4(CLK_AUD_ASRC11, "aud_asrc11", "top_a1sys_hp", 16),
GATE_AUD4(CLK_AUD_ASRC12, "aud_asrc12", "top_a1sys_hp", 17),
GATE_AUD4(CLK_AUD_MULTI_IN, "aud_multi_in", "mphone_slave_b", 19),
GATE_AUD4(CLK_AUD_INTDIR, "aud_intdir", "top_intdir", 20),
GATE_AUD4(CLK_AUD_A1SYS, "aud_a1sys", "top_a1sys_hp", 21),
GATE_AUD4(CLK_AUD_A2SYS, "aud_a2sys", "top_a2sys", 22),
GATE_AUD4(CLK_AUD_PCMIF, "aud_pcmif", "top_a1sys_hp", 24),
GATE_AUD4(CLK_AUD_A3SYS, "aud_a3sys", "top_a3sys", 30),
GATE_AUD4(CLK_AUD_A4SYS, "aud_a4sys", "top_a4sys", 31),

/* AUD5 */
GATE_AUD5(CLK_AUD_MEMIF_UL1, "aud_memif_ul1", "top_a1sys_hp", 0),
GATE_AUD5(CLK_AUD_MEMIF_UL2, "aud_memif_ul2", "top_a1sys_hp", 1),
GATE_AUD5(CLK_AUD_MEMIF_UL3, "aud_memif_ul3", "top_a1sys_hp", 2),
GATE_AUD5(CLK_AUD_MEMIF_UL4, "aud_memif_ul4", "top_a1sys_hp", 3),
GATE_AUD5(CLK_AUD_MEMIF_UL5, "aud_memif_ul5", "top_a1sys_hp", 4),
GATE_AUD5(CLK_AUD_MEMIF_UL6, "aud_memif_ul6", "top_a1sys_hp", 5),
GATE_AUD5(CLK_AUD_MEMIF_UL8, "aud_memif_ul8", "top_a1sys_hp", 7),
GATE_AUD5(CLK_AUD_MEMIF_UL9, "aud_memif_ul9", "top_a1sys_hp", 8),
GATE_AUD5(CLK_AUD_MEMIF_UL10, "aud_memif_ul10", "top_a1sys_hp", 9),
GATE_AUD5(CLK_AUD_MEMIF_DL2, "aud_memif_dl2", "top_a1sys_hp", 18),
GATE_AUD5(CLK_AUD_MEMIF_DL3, "aud_memif_dl3", "top_a1sys_hp", 19),
GATE_AUD5(CLK_AUD_MEMIF_DL6, "aud_memif_dl6", "top_a1sys_hp", 22),
GATE_AUD5(CLK_AUD_MEMIF_DL7, "aud_memif_dl7", "top_a1sys_hp", 23),
GATE_AUD5(CLK_AUD_MEMIF_DL8, "aud_memif_dl8", "top_a1sys_hp", 24),
GATE_AUD5(CLK_AUD_MEMIF_DL10, "aud_memif_dl10", "top_a1sys_hp", 26),
GATE_AUD5(CLK_AUD_MEMIF_DL11, "aud_memif_dl11", "top_a1sys_hp", 27),

/* AUD6 */
GATE_AUD6(CLK_AUD_GASRC0, "aud_gasrc0", "top_asm_h", 0),
GATE_AUD6(CLK_AUD_GASRC1, "aud_gasrc1", "top_asm_h", 1),
GATE_AUD6(CLK_AUD_GASRC2, "aud_gasrc2", "top_asm_h", 2),
GATE_AUD6(CLK_AUD_GASRC3, "aud_gasrc3", "top_asm_h", 3),
GATE_AUD6(CLK_AUD_GASRC4, "aud_gasrc4", "top_asm_h", 4),
GATE_AUD6(CLK_AUD_GASRC5, "aud_gasrc5", "top_asm_h", 5),
GATE_AUD6(CLK_AUD_GASRC6, "aud_gasrc6", "top_asm_h", 6),
GATE_AUD6(CLK_AUD_GASRC7, "aud_gasrc7", "top_asm_h", 7),
GATE_AUD6(CLK_AUD_GASRC8, "aud_gasrc8", "top_asm_h", 8),
GATE_AUD6(CLK_AUD_GASRC9, "aud_gasrc9", "top_asm_h", 9),
GATE_AUD6(CLK_AUD_GASRC10, "aud_gasrc10", "top_asm_h", 10),
GATE_AUD6(CLK_AUD_GASRC11, "aud_gasrc11", "top_asm_h", 11),
};

int mt8188_audsys_clk_register(struct mtk_base_afe *afe)
{
struct mt8188_afe_private *afe_priv = afe->platform_priv;
struct clk *clk;
struct clk_lookup *cl;
int i;

afe_priv->lookup = devm_kcalloc(afe->dev, CLK_AUD_NR_CLK,
sizeof(*afe_priv->lookup),
GFP_KERNEL);

if (!afe_priv->lookup)
return -ENOMEM;

for (i = 0; i < ARRAY_SIZE(aud_clks); i++) {
const struct afe_gate *gate = &aud_clks[i];

clk = clk_register_gate(afe->dev, gate->name, gate->parent_name,
gate->flags, afe->base_addr + gate->reg,
gate->bit, gate->cg_flags, NULL);

if (IS_ERR(clk)) {
dev_err(afe->dev, "Failed to register clk %s: %ld\n",
gate->name, PTR_ERR(clk));
continue;
}

/* add clk_lookup for devm_clk_get(SND_SOC_DAPM_CLOCK_SUPPLY) */
cl = kzalloc(sizeof(*cl), GFP_KERNEL);
if (!cl)
return -ENOMEM;

cl->clk = clk;
cl->con_id = gate->name;
cl->dev_id = dev_name(afe->dev);
cl->clk_hw = NULL;
clkdev_add(cl);

afe_priv->lookup[i] = cl;
}

return 0;
}

void mt8188_audsys_clk_unregister(struct mtk_base_afe *afe)
{
struct mt8188_afe_private *afe_priv = afe->platform_priv;
struct clk *clk;
struct clk_lookup *cl;
int i;

if (!afe_priv)
return;

for (i = 0; i < CLK_AUD_NR_CLK; i++) {
cl = afe_priv->lookup[i];
if (!cl)
continue;

clk = cl->clk;
clk_unregister_gate(clk);

clkdev_drop(cl);
}
}
15 changes: 15 additions & 0 deletions sound/soc/mediatek/mt8188/mt8188-audsys-clk.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* mt8188-audsys-clk.h -- MediaTek 8188 audsys clock definition
*
* Copyright (c) 2022 MediaTek Inc.
* Author: Chun-Chia Chiu <chun-chia.chiu@mediatek.com>
*/

#ifndef _MT8188_AUDSYS_CLK_H_
#define _MT8188_AUDSYS_CLK_H_

int mt8188_audsys_clk_register(struct mtk_base_afe *afe);
void mt8188_audsys_clk_unregister(struct mtk_base_afe *afe);

#endif
83 changes: 83 additions & 0 deletions sound/soc/mediatek/mt8188/mt8188-audsys-clkid.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* mt8188-audsys-clkid.h -- MediaTek 8188 audsys clock id definition
*
* Copyright (c) 2022 MediaTek Inc.
* Author: Chun-Chia Chiu <chun-chia.chiu@mediatek.com>
*/

#ifndef _MT8188_AUDSYS_CLKID_H_
#define _MT8188_AUDSYS_CLKID_H_

enum{
CLK_AUD_AFE,
CLK_AUD_LRCK_CNT,
CLK_AUD_SPDIFIN_TUNER_APLL,
CLK_AUD_SPDIFIN_TUNER_DBG,
CLK_AUD_UL_TML,
CLK_AUD_APLL1_TUNER,
CLK_AUD_APLL2_TUNER,
CLK_AUD_TOP0_SPDF,
CLK_AUD_APLL,
CLK_AUD_APLL2,
CLK_AUD_DAC,
CLK_AUD_DAC_PREDIS,
CLK_AUD_TML,
CLK_AUD_ADC,
CLK_AUD_DAC_HIRES,
CLK_AUD_A1SYS_HP,
CLK_AUD_AFE_DMIC1,
CLK_AUD_AFE_DMIC2,
CLK_AUD_AFE_DMIC3,
CLK_AUD_AFE_DMIC4,
CLK_AUD_AFE_26M_DMIC_TM,
CLK_AUD_UL_TML_HIRES,
CLK_AUD_ADC_HIRES,
CLK_AUD_LINEIN_TUNER,
CLK_AUD_EARC_TUNER,
CLK_AUD_I2SIN,
CLK_AUD_TDM_IN,
CLK_AUD_I2S_OUT,
CLK_AUD_TDM_OUT,
CLK_AUD_HDMI_OUT,
CLK_AUD_ASRC11,
CLK_AUD_ASRC12,
CLK_AUD_MULTI_IN,
CLK_AUD_INTDIR,
CLK_AUD_A1SYS,
CLK_AUD_A2SYS,
CLK_AUD_PCMIF,
CLK_AUD_A3SYS,
CLK_AUD_A4SYS,
CLK_AUD_MEMIF_UL1,
CLK_AUD_MEMIF_UL2,
CLK_AUD_MEMIF_UL3,
CLK_AUD_MEMIF_UL4,
CLK_AUD_MEMIF_UL5,
CLK_AUD_MEMIF_UL6,
CLK_AUD_MEMIF_UL8,
CLK_AUD_MEMIF_UL9,
CLK_AUD_MEMIF_UL10,
CLK_AUD_MEMIF_DL2,
CLK_AUD_MEMIF_DL3,
CLK_AUD_MEMIF_DL6,
CLK_AUD_MEMIF_DL7,
CLK_AUD_MEMIF_DL8,
CLK_AUD_MEMIF_DL10,
CLK_AUD_MEMIF_DL11,
CLK_AUD_GASRC0,
CLK_AUD_GASRC1,
CLK_AUD_GASRC2,
CLK_AUD_GASRC3,
CLK_AUD_GASRC4,
CLK_AUD_GASRC5,
CLK_AUD_GASRC6,
CLK_AUD_GASRC7,
CLK_AUD_GASRC8,
CLK_AUD_GASRC9,
CLK_AUD_GASRC10,
CLK_AUD_GASRC11,
CLK_AUD_NR_CLK,
};

#endif

0 comments on commit fdd4e1a

Please sign in to comment.