rockchip: rk3399: Add support i2s
This patch enable and configure the clocks and IOMUX for i2s audio path, and the i2s0 clock is from CPLL. Please refer to TRM V0.3 Part 1 Chapter 3 CRU, P126/P128/P144/P154/P155 for the i2s clock div and gate setting. BRANCH=none BUG=chrome-os-partner:52172 TEST=boot kevin rev1, press ctrl+u and hear the beep voice. Change-Id: Id00baac965c8b9213270ba5516e1ca684e4304a6 Signed-off-by: Martin Roth <martinroth@chromium.org> Original-Commit-Id: 9c58fa7 Original-Change-Id: I130a874a0400712317e5e7a8b3b10a6f04586f68 Original-Signed-off-by: Xing Zheng <zhengxing@rock-chips.com> Original-Reviewed-on: https://chromium-review.googlesource.com/347526 Original-Commit-Ready: Wonjoon Lee <woojoo.lee@samsung.com> Original-Reviewed-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://review.coreboot.org/15034 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh <furquan@google.com>
This commit is contained in:
parent
8f8cf4d336
commit
96fbc31027
|
@ -92,6 +92,23 @@ static void configure_sdmmc(void)
|
||||||
write32(&rk3399_grf->iomux_sdmmc, IOMUX_SDMMC);
|
write32(&rk3399_grf->iomux_sdmmc, IOMUX_SDMMC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void configure_codec(void)
|
||||||
|
{
|
||||||
|
write32(&rk3399_grf->iomux_i2s0, IOMUX_I2S0);
|
||||||
|
write32(&rk3399_grf->iomux_i2sclk, IOMUX_I2SCLK);
|
||||||
|
|
||||||
|
/* AUDIO IO domain 1.8V voltage selection */
|
||||||
|
write32(&rk3399_grf->io_vsel, RK_SETBITS(1 << 1));
|
||||||
|
|
||||||
|
/* CPU1_P1.8V_AUDIO_PWREN for P1.8_AUDIO */
|
||||||
|
gpio_output(GPIO(0, A, 2), 1);
|
||||||
|
|
||||||
|
/* set CPU1_SPK_PA_EN output */
|
||||||
|
gpio_output(GPIO(1, A, 2), 0);
|
||||||
|
|
||||||
|
rkclk_configure_i2s(12288000);
|
||||||
|
}
|
||||||
|
|
||||||
static void configure_display(void)
|
static void configure_display(void)
|
||||||
{
|
{
|
||||||
/* set pinmux for edp HPD*/
|
/* set pinmux for edp HPD*/
|
||||||
|
@ -105,6 +122,7 @@ static void mainboard_init(device_t dev)
|
||||||
{
|
{
|
||||||
configure_sdmmc();
|
configure_sdmmc();
|
||||||
configure_emmc();
|
configure_emmc();
|
||||||
|
configure_codec();
|
||||||
configure_display();
|
configure_display();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -686,6 +686,50 @@ uint32_t rkclk_i2c_clock_for_bus(unsigned bus)
|
||||||
return freq;
|
return freq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32 clk_gcd(u32 a, u32 b)
|
||||||
|
{
|
||||||
|
while (b != 0) {
|
||||||
|
int r = b;
|
||||||
|
b = a % b;
|
||||||
|
a = r;
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rkclk_configure_i2s(unsigned int hz)
|
||||||
|
{
|
||||||
|
int n, d;
|
||||||
|
int v;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clk_i2s0_sel: divider ouput from fraction
|
||||||
|
* clk_i2s0_pll_sel source clock: cpll
|
||||||
|
* clk_i2s0_div_con: 1 (div+1)
|
||||||
|
*/
|
||||||
|
write32(&cru_ptr->clksel_con[28],
|
||||||
|
RK_CLRSETBITS(3 << 8 | 1 << 7 | 0x7f << 0,
|
||||||
|
1 << 8 | 0 << 7 | 0 << 0));
|
||||||
|
|
||||||
|
/* make sure and enable i2s0 path gates */
|
||||||
|
write32(&cru_ptr->clkgate_con[8],
|
||||||
|
RK_CLRBITS(1 << 12 | 1 << 5 | 1 << 4 | 1 << 3));
|
||||||
|
|
||||||
|
/* set frac divider */
|
||||||
|
v = clk_gcd(CPLL_HZ, hz);
|
||||||
|
n = (CPLL_HZ / v) & (0xffff);
|
||||||
|
d = (hz / v) & (0xffff);
|
||||||
|
assert(hz == CPLL_HZ / n * d);
|
||||||
|
write32(&cru_ptr->clksel_con[96], d << 16 | n);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clk_i2sout_sel clk_i2s
|
||||||
|
* clk_i2s_ch_sel: clk_i2s0
|
||||||
|
*/
|
||||||
|
write32(&cru_ptr->clksel_con[31],
|
||||||
|
RK_CLRSETBITS(1 << 2 | 3 << 0,
|
||||||
|
0 << 2 | 0 << 0));
|
||||||
|
}
|
||||||
|
|
||||||
void rkclk_configure_saradc(unsigned int hz)
|
void rkclk_configure_saradc(unsigned int hz)
|
||||||
{
|
{
|
||||||
int src_clk_div;
|
int src_clk_div;
|
||||||
|
|
|
@ -107,6 +107,7 @@ int rkclk_configure_vop_dclk(u32 vop_id, u32 dclk_hz);
|
||||||
void rkclk_configure_cpu(enum apll_l_frequencies apll_l_freq);
|
void rkclk_configure_cpu(enum apll_l_frequencies apll_l_freq);
|
||||||
void rkclk_configure_ddr(unsigned int hz);
|
void rkclk_configure_ddr(unsigned int hz);
|
||||||
void rkclk_configure_emmc(void);
|
void rkclk_configure_emmc(void);
|
||||||
|
void rkclk_configure_i2s(unsigned int hz);
|
||||||
void rkclk_configure_saradc(unsigned int hz);
|
void rkclk_configure_saradc(unsigned int hz);
|
||||||
void rkclk_configure_spi(unsigned int bus, unsigned int hz);
|
void rkclk_configure_spi(unsigned int bus, unsigned int hz);
|
||||||
void rkclk_configure_tsadc(unsigned int hz);
|
void rkclk_configure_tsadc(unsigned int hz);
|
||||||
|
|
|
@ -131,8 +131,14 @@ struct rk3399_grf_regs {
|
||||||
u32 gpio3a_iomux;
|
u32 gpio3a_iomux;
|
||||||
u32 gpio3b_iomux;
|
u32 gpio3b_iomux;
|
||||||
u32 gpio3c_iomux;
|
u32 gpio3c_iomux;
|
||||||
|
union {
|
||||||
|
u32 iomux_i2s0;
|
||||||
u32 gpio3d_iomux;
|
u32 gpio3d_iomux;
|
||||||
|
};
|
||||||
|
union {
|
||||||
|
u32 iomux_i2sclk;
|
||||||
u32 gpio4a_iomux;
|
u32 gpio4a_iomux;
|
||||||
|
};
|
||||||
union {
|
union {
|
||||||
u32 iomux_sdmmc;
|
u32 iomux_sdmmc;
|
||||||
u32 iomux_uart2a;
|
u32 iomux_uart2a;
|
||||||
|
@ -346,6 +352,11 @@ static struct rk3399_pmusgrf_regs * const rk3399_pmusgrf = (void *)PMUSGRF_BASE;
|
||||||
1 << 4 | 1 << 2 | 1 << 0)
|
1 << 4 | 1 << 2 | 1 << 0)
|
||||||
#define IOMUX_I2C0_SCL RK_CLRSETBITS(3 << 0, 2 << 0)
|
#define IOMUX_I2C0_SCL RK_CLRSETBITS(3 << 0, 2 << 0)
|
||||||
#define IOMUX_I2C0_SDA RK_CLRSETBITS(3 << 14, 2 << 14)
|
#define IOMUX_I2C0_SDA RK_CLRSETBITS(3 << 14, 2 << 14)
|
||||||
|
|
||||||
|
#define IOMUX_I2S0 RK_SETBITS(1 << 14 | 1 << 12 | 1 << 10 | 1 << 8 |\
|
||||||
|
1 << 6 | 1 << 4 | 1 << 2 | 1 << 0)
|
||||||
|
#define IOMUX_I2SCLK RK_SETBITS(1 << 0)
|
||||||
|
|
||||||
#define IOMUX_PWM_0 RK_SETBITS(1 << 4)
|
#define IOMUX_PWM_0 RK_SETBITS(1 << 4)
|
||||||
#define IOMUX_PWM_1 RK_SETBITS(1 << 12)
|
#define IOMUX_PWM_1 RK_SETBITS(1 << 12)
|
||||||
#define IOMUX_PWM_2 RK_SETBITS(1 << 6)
|
#define IOMUX_PWM_2 RK_SETBITS(1 << 6)
|
||||||
|
|
Loading…
Reference in New Issue