📄 lh7a400_csc_driver.c
字号:
* Disable DMA on a particular channel
*
* Processing:
* Clears the bit corresponding to the DMA channel to be disabled
* in the PWRCNT register. The bit number is computed from the
* argument passed by adding an offset to it.
*
* Parameters: channel - enumerated type identifying the DMA channel
* to be disabled
*
* Outputs: None
* Returns: Nothing
*********************************************************************/
void csc_disable_dma(dma_channel_t channel)
{
CLKSC->pwrcnt &= ~_BIT((UNS_32)channel + PWRCNT_DMA_FIELD_OFFSET);
}
/*********************************************************************
* Function: csc_reset_usb_control
* Purpose:
* Resets the control side of the USB
*
* Processing:
* Sets the bit in the USB reset register to reset the
* USB control side
*
* Parameters: None
* Outputs: None
* Returns: Nothing
*********************************************************************/
void csc_reset_usb_control(void)
{
CLKSC->usbreset |= USBRESET_APB;
}
/*********************************************************************
* Function: csc_reset_usb_io
* Purpose:
* Resets the I/O side of the USB
*
* Processing:
* Sets the bit in the USB reset register to reset the
* USB I/O side
*
* Parameters: None
* Outputs: None
* Returns: Nothing
*********************************************************************/
void csc_reset_usb_io(void)
{
CLKSC->usbreset |= USBRESET_IO;
}
/*********************************************************************
* Function: csc_no_apb_wait
* Purpose:
* Determine whether APB peripheral writes inserts wait states
* on the AHB
*
* Processing:
* Reads the APBWAIT register in the CSC
*
* Parameters: None
* Outputs: None
* Returns: 0 if the APB bridge inserts waits on APB writes
1 if the APB bridge does not insert waits on APB writes
*********************************************************************/
UNS_32 csc_no_apb_wait(void)
{
return(~(CLKSC->apbwait));
}
/*********************************************************************
* Function: csc_apb_wait
* Purpose:
* Control the APB wait state insertion
*
* Processing:
* Sets or resets the NO_WRITE_WAIT field in the APBWAIT
* register based on the argument passed
*
* Parameters: wait - 1 if no wait is desired
* 0 if it is desired that the APB bridge insert
* wait states on the AHB for (peripheral writes
* Outputs: None
* Returns: Nothing
*********************************************************************/
void csc_apb_wait(UNS_32 wait)
{
if (wait)
{
CLKSC->apbwait = 0;
}
else
{
CLKSC->apbwait = APB_NO_WRITE_WAIT;
}
}
/**********************************************************************
*
* Function: void LH7A400_clock_set (UNS_32 clkset_register_setting)
*
* Author: barnetth
*
* Purpose:
* To set the RCPC Prescale registers in the proper order
*
* Processing:
* For the desired clock setting, set the CpuClkPrescale and
* then set the HCLKClkPrescale.
*
* Parameters:
* UNS_32 clkset_register_setting - A value selected from the
* following constants:
*
* CLKSET_33_33_8
* CLKSET_33_33_16
* CLKSET_50_50_12
* CLKSET_50_50_25
* CLKSET_66_33_8
* CLKSET_66_33_16
* CLKSET_66_66_16
* CLKSET_66_66_33
* CLKSET_75_75_19
* CLKSET_75_75_37
* CLKSET_100_50_12
* CLKSET_100_50_25
* CLKSET_100_100_12
* CLKSET_100_100_50
* CLKSET_132_33_8
* CLKSET_132_33_16
* CLKSET_132_66_16
* CLKSET_132_66_33
* CLKSET_150_75_19
* CLKSET_150_75_37
* CLKSET_166_42_21
* CLKSET_166_83_21
* CLKSET_166_83_42
* CLKSET_175_44_22
* CLKSET_175_87_43
* CLKSET_184_46_23
* CLKSET_190_48_24
* CLKSET_200_50_25
* CLKSET_200_100_25
* CLKSET_200_100_50
*
* See LH7A400_evb.h
*
* Outputs: None
*
* Returns: None
*
* Notes:
* (1) DEFAULT is to set the core to 200 MHz, the AHB to 50 MHz
*
**********************************************************************/
void LH7A400_clock_set (UNS_32 clkset_register_setting)
{
switch (clkset_register_setting)
{
/* case CLKSET_33_33_8:
CLKSC->clkset = CLKSET_33_33_8;
__asm__( \
"NOP\n" \
"NOP\n" \
"NOP\n" \
"NOP\n" \
"NOP\n" \
"MRC p15, 0, r1, c1, c0, 0\n" \
"AND r1, r1, #0\n" \
"MCR MMU_CP, 0, r1, c1, c0, 0\n"
);
break;*/
case CLKSET_100_50_25:
__asm__(
"MRC p15, 0, r1, c1, c0, 0\n"
"MOV r2, #0x60000000\n" \
"AND r1, r1, #0x7fffffff\n" \
"ORR r1, r1, r2\n" \
"MCR p15, 0, r1, c1, c0, 0\n" \
);
CLKSC->clkset = CLKSET_100_50_25;
__asm__( \
"NOP\n" \
"NOP\n" \
"NOP\n" \
"NOP\n" \
"NOP\n" \
);
break;
case CLKSET_200_50_25:
__asm__( \
"MRC p15, 0, r1, c1, c0, 0\n" \
"MOV r2, #0x60000000\n" \
"AND r1, r1, #0x7fffffff\n"
"ORR r1, r1, r2\n" \
"MCR p15, 0, r1, c1, c0, 0\n" \
);
CLKSC->clkset = CLKSET_200_50_25;
__asm__( \
"NOP\n" \
"NOP\n" \
"NOP\n" \
"NOP\n" \
"NOP\n" \
);
break;
case CLKSET_200_100_25:
__asm__( \
"MRC p15, 0, r1, c1, c0, 0\n" \
"MOV r2, #0x60000000\n" \
"AND r1, r1, #0x7fffffff\n"
"ORR r1, r1, r2\n" \
"MCR p15, 0, r1, c1, c0, 0\n" \
);
CLKSC->clkset = CLKSET_200_100_25;
__asm__( \
"NOP\n" \
"NOP\n" \
"NOP\n" \
"NOP\n" \
"NOP\n" \
);
break;
case CLKSET_200_100_50:
__asm__( \
"MRC p15, 0, r1, c1, c0, 0\n" \
"MOV r2, #0x60000000\n" \
"AND r1, r1, #0x7fffffff\n" \
"ORR r1, r1, r2\n" \
"MCR p15, 0, r1, c1, c0, 0\n" \
);
CLKSC->clkset = CLKSET_200_100_50;
__asm__( \
"NOP\n" \
"NOP\n" \
"NOP\n" \
"NOP\n" \
"NOP\n" \
);
break;
default:
__asm__( \
"MRC p15, 0, r1, c1, c0, 0\n" \
"MOV r2, #0x60000000\n" \
"AND r1, r1, #0x7fffffff\n" \
"ORR r1, r1, r2\n" \
"MCR p15, 0, r1, c1, c0, 0\n" \
);
CLKSC->clkset = CLKSET_DEFAULT;
__asm__( \
"NOP\n" \
"NOP\n" \
"NOP\n" \
"NOP\n" \
"NOP\n" \
);
break;
}
}
/*********************************************************************
* Function: csc_get_cpuclk
* Purpose:
* Compute the current CPU value from the settings in the
* CLKSET register
*
* Processing:
* Extract the various variables from the CLKSET register and
use them in the equation described in the LH7A400
Programmers Manual to reverse compute the clock frequency.
*
* Parameters: None
* Outputs: None
* Returns: The current CPU frequency
*********************************************************************/
UNS_32 csc_get_cpuclk(void)
{
UNS_32 m1;
UNS_32 m2;
UNS_32 p;
UNS_32 ps;
register UNS_32 tmp;
tmp = CLKSC->clkset;
__asm__( \
"NOP\n" \
"NOP\n" \
"NOP\n" \
"NOP\n" \
"NOP\n" \
);
m1 = (tmp >> 7) & 0x0F;
m2 = (tmp >> 11) & 0x1F;
p = (tmp >> 2) & 0x1F;
ps = (tmp >> 18) & 0x03;
return (((((m2 + 2) * LH7A400_BASE_CLOCK) >> ps) / (p + 2)) \
* (m1 + 2));
}
/**********************************************************************
*
* Function: UNS_32 LH7A400_get_hclk
*
* Author: KovitzP
*
* Purpose:
* To calculate and return the programmed value of HCLK
*
* Parameters:
* None
*
* Returns:
* Current programmed frequency of HCLK
*
* Notes:
* Useful for configuring the refresh rate of SDRAM, or LCD timing,
* ect...
*
**********************************************************************/
UNS_32 LH7A400_get_hclk(void)
{
UNS_32 m1;
UNS_32 m2;
UNS_32 p;
UNS_32 ps_pow;
UNS_32 hclkdiv;
UNS_32 gclk;
UNS_32 hclk;
/* compute hclk based on current system clock settings
see InfoStream Programming Manual page 12-13 */
m1 = (CLKSC->clkset >> 7) & 0xf;
m2 = (CLKSC->clkset >> 11) & 0x1f;
p = (CLKSC->clkset >> 2) & 0x1f;
ps_pow = 1 << ( (CLKSC->clkset >> 18) & 0x3);
hclkdiv = CLKSC->clkset & 0x3;
gclk = ((m1 + 2) * (m2 + 2) * (LH7A400_BASE_CLOCK / 100) / ((p+2)
* ps_pow))* 100 ;
hclk = gclk / (hclkdiv + 1);
return hclk;
}
/*********************************************************************
* Function: csc_get_pclk
* Purpose:
* Compute the current PCLK value from the settings in the
* CLKSET register
*
* Processing:
* Compute PCLK from the AHB clock and the APB divider.
*
* Parameters: None
* Outputs: None
* Returns: The current PCLK frequency
*********************************************************************/
UNS_32 csc_get_pclk(void)
{
register UNS_32 tmp;
UNS_32 pdiv;
tmp = CLKSC->clkset;
pdiv = 2 ^ ((tmp >> 16) & 0x3);
return (LH7A400_get_hclk () / pdiv);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -