//////////////////////////////////////////////////// // 功能: 开打声音设备 // 输入: // 输出: // 返回: // 说明: //////////////////////////////////////////////////// void MediaSysInit() { // Start AIC and DMA Clock // Clock gate Bits. Controls the clock supplies to some peripherals. If set, // clock supplies to associated devices are stopped, and registers of the // device cannot be accessed also //CLRREG32(A_CPM_CLKGR, CLKGR_STOP_AIC_PCLK | CLKGR_STOP_DMAC); __cpm_start_aic1(); //clear CPM_CLKGR_AIC1 __cpm_start_aic2(); //clear CPM_CLKGR_AIC2 __cpm_start_dmac(); //clear CPM_CLKGR_DMAC // I2S device clock divider Register (I2SCDR) is a 32-bit read/write register that specifies the divider of // I2S device clock . This register is initialized to 0x00000004 only by any reset. Only word access can // be used on I2SCDR //OUTREG32(A_CPM_I2SCDR, 0x00); REG_CPM_I2SCDR = 0x00; // change enable. If CE is 1, writes on CDIV, HDIV, PDIV, MDIV, UDIV, // PXDIV or LDIV will start a frequency changing sequence immediately. // When CE is 0, writes on CDIV, HDIV, PDIV, MDIV, UDIV, PXDIV and // LDIV will not start a frequency changing sequence immediately. The // division ratio is actually updated in PLL multiple ratio changing sequence // or PLL Disable Sequence. // 0: Division ratios are updated in PLL multiple ratio changing sequence or // PLL Disable Sequence // 1: Division ratios are updated immediately //SETREG32(A_CPM_CPCCR, CPCCR_CHANGE_EN); __cpm_enable_pll_change(); // I2SCR contains bits to control BIT_CLK stop, audio sample size, I2S or MSB-justified selection in // I2S/MSB-justified. It is valid only in I2S/MSB-justified format. //OUTREG32(A_AIC_I2SCR, 0x00); REG_AIC_I2SCR = 0; // AIC Init // AICFR contains bits to control FIFO threshold, AC-link or I2S/MSB-justified selection, AIC reset, // master/slave selection, and AIC enable. // Play ZERO sample when TX FIFO underflow or Play last sample when TX FIFO underflow REG_AIC_FR = AIC_FR_LSMP; // Internal CODEC //OUTREG32(A_AIC_AICFR, AICFR_CODEC_INT | AICFR_LSMP_LAST_SAMPLE); __aic_internal_codec(); // 0 Select AC-link format // 1 Select I2S/MSB-justified format //SETREG32(A_AIC_AICFR, AICFR_I2S); __aic_select_i2s(); //Enable SYSCLK output. When this bit is 1, the SYSCLK outputs to chip //outside is enabled. Else, the clock is disabled. __i2s_select_i2s(); // OUTREG32(A_AIC_I2SCR, I2SCR_I2S); // SETREG32(A_AIC_AICFR, AICFR_BCKD_IN | AICFR_SYNCD_IN); __i2s_as_slave(); // SETREG32(A_AIC_AICFR, AICFR_ENABLE); __aic_enable(); // AIC Configure //SETREG32(A_AIC_AICFR, AICFR_RFTH(16) | AICFR_TFTH(24)); // Receive FIFO threshold for interrupt or DMA request. The RFTH valid // value is 0 ~ 15 __i2s_set_receive_trigger((16/2) - 1); // Transmit FIFO threshold for interrupt or DMA request __i2s_set_transmit_trigger(24/2); //OUTREG32(A_AIC_AICCR, AICCR_OSS_16BIT | AICCR_ISS_16BIT); // Output Sample Size. These bits reflect output sample data size from // memory or register. The data sizes supported are: 8, 16, 18, 20 and 24 // bits. The sample data is LSB-justified in memory/register __i2s_set_oss_sample_size(16); // Input Sample Size. These bits reflect input sample data size to memory or // register. The data sizes supported are: 8, 16, 18, 20 and 24 bits. The // sample data is LSB-justified in memory/register. __i2s_set_iss_sample_size(16); //SETREG32(A_AIC_AICCR, AICCR_RDMS | AICCR_TDMS | AICCR_FLUSH_FIFO); // Transmit DMA enable. This bit is used to enable or disable the DMA // during transmit audio data __i2s_enable_transmit_dma(); // Receive DMA enable. This bit is used to enable or disable the DMA during // receiving audio data __i2s_enable_receive_dma(); //SETREG32(AIC_CR, AIC_CR_FLUSH_FIFO); // JZ4750 D8 == FIFO Flush. Write 1 to this bit flush transmit/receive FIFOs to empty.Writing 0 to this bit has no effect and this bit is always reading 0. // JZ4755 D7 == Receive FIFO Flush. Write 1 to this bit flush receive FIFOs to empty // D8 == Transmit FIFO Flush. Write 1 to this bit flush transmit FIFOs to empty. // __aic_flush_fifo(); REG_AIC_CR |= (1<<7); // I2SCR contains bits to control BIT_CLK stop, audio sample size, I2S or MSB-justified selection in // I2S/MSB-justified. It is valid only in I2S/MSB-justified format. OUTREG32(A_AIC_AICSR, 0x00000000); //CLRREG32(A_AIC_AICFR, AICFR_LSMP_LAST_SAMPLE); __aic_clr_esclk(); #ifdef KPRINTF_DEF kprintf("AICFR[0x%x]\n", INREG32(AIC_FR)); kprintf("AICCR[0x%x]\n", INREG32(AIC_CR)); kprintf("AICSR[0x%x]\n", INREG32(AIC_SR)); #endif fDeviceStatus = DEVICE_CLOSE_STATUS; OpenMediaCodecDevice(); }
/* * Init PLL. * * PLL output clock = EXTAL * NF / (NR * NO) * * NF = FD + 2, NR = RD + 2 * NO = 1 (if OD = 0), NO = 2 (if OD = 1 or 2), NO = 4 (if OD = 3) */ void init_pll(void) { register unsigned int cfcr, plcr1, plcr2; int n2FR[9] = { 0, 0, 1, 2, 3, 0, 4, 0, 5 }; /** divisors, * for jz4760 ,I:H:H2:P:M:S. * DIV should be one of [1, 2, 3, 4, 6, 8] */ int div[6] = {1, 2, 4, 4, 4, 4}; //int div[6] = {1, 2, 2, 2, 2, 2}; int pllout2; cfcr = CPM_CPCCR_PCS | (n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) | (n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) | (n2FR[div[2]] << CPM_CPCCR_H2DIV_BIT) | (n2FR[div[3]] << CPM_CPCCR_PDIV_BIT) | (n2FR[div[4]] << CPM_CPCCR_MDIV_BIT) | (n2FR[div[5]] << CPM_CPCCR_SDIV_BIT); // write REG_DDRC_CTRL 8 times to clear ddr fifo REG_DDRC_CTRL = 0; REG_DDRC_CTRL = 0; REG_DDRC_CTRL = 0; REG_DDRC_CTRL = 0; REG_DDRC_CTRL = 0; REG_DDRC_CTRL = 0; REG_DDRC_CTRL = 0; REG_DDRC_CTRL = 0; if (CFG_EXTAL > 16000000) cfcr |= CPM_CPCCR_ECS; else cfcr &= ~CPM_CPCCR_ECS; /* set CPM_CPCCR_MEM only for ddr1 or ddr2 */ #if (defined(CONFIG_SDRAM_DDR1) || defined(CONFIG_SDRAM_DDR2)) cfcr |= CPM_CPCCR_MEM; #else /* mddr or sdram */ cfcr &= ~CPM_CPCCR_MEM; #endif cfcr |= CPM_CPCCR_CE; pllout2 = (cfcr & CPM_CPCCR_PCS) ? CFG_CPU_SPEED : (CFG_CPU_SPEED / 2); plcr1 = CPCCR_M_N_OD; plcr1 |= (0x20 << CPM_CPPCR_PLLST_BIT) /* PLL stable time */ | CPM_CPPCR_PLLEN; /* enable PLL */ /* * Init USB Host clock, pllout2 must be n*48MHz * For JZ4760 UHC - River. */ REG_CPM_UHCCDR = pllout2 / 48000000 - 1; /* init PLL */ REG_CPM_CPCCR = cfcr; REG_CPM_CPPCR = plcr1; /*wait for pll output stable ...*/ while (!(REG_CPM_CPPCR & CPM_CPPCR_PLLS)); /* set CPM_CPCCR_MEM only for ddr1 or ddr2 */ plcr2 = CPCCR1_M_N_OD | CPM_CPPCR1_PLL1EN; /* init PLL_1 , source clock is extal clock */ REG_CPM_CPPCR1 = plcr2; __cpm_enable_pll_change(); /*wait for pll_1 output stable ...*/ while (!(REG_CPM_CPPCR1 & CPM_CPPCR1_PLL1S)); /* serial_puts("REG_CPM_CPCCR = "); serial_put_hex(REG_CPM_CPCCR); serial_puts("REG_CPM_CPPCR = "); serial_put_hex(REG_CPM_CPPCR); */ }