
On 28/02/13 19:59, Akshay Saraswat wrote:
Add generic api to get the frequency of the required peripherial. This
typo. peripherial -> peripheral
API gets the source clock frequency and returns the required frequency by dividing with first and second dividers based on the requirement.
Test with command "sf probe 1:0; time sf read 40008000 0 1000". Try with different numbers of bytes and see that sane values are obtained Build and boot U-boot with this patch, backlight works properly.
Signed-off-by: Padmavathi Venna padma.v@samsung.com Signed-off-by: Akshay Saraswat akshay.s@samsung.com
Changes since v1: - Fixed few nits.
arch/arm/cpu/armv7/exynos/clock.c | 138 +++++++++++++++++++++++++++++++++ arch/arm/include/asm/arch-exynos/clk.h | 17 ++++ 2 files changed, 155 insertions(+)
diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c index 956427c..cc101c2 100644 --- a/arch/arm/cpu/armv7/exynos/clock.c +++ b/arch/arm/cpu/armv7/exynos/clock.c @@ -27,6 +27,49 @@ #include <asm/arch/clk.h> #include <asm/arch/periph.h>
+/* *
- This structure is to store the src bit, div bit and prediv bit
- positions of the peripheral clocks of the src and div registers
- */
+struct clk_bit_info {
- int8_t src_bit;
- int8_t div_bit;
- int8_t prediv_bit;
+};
+/* src_bit div_bit prediv_bit */ +static struct clk_bit_info clk_bit_info[PERIPH_ID_COUNT] = {
- {0, 0, -1},
- {4, 4, -1},
- {8, 8, -1},
- {12, 12, -1},
- {0, 0, 8},
- {4, 16, 24},
- {8, 0, 8},
- {12, 16, 24},
- {-1, -1, -1},
- {16, 0, 8},
- {20, 16, 24},
- {24, 0, 8},
- {0, 0, 4},
- {4, 12, 16},
- {-1, -1, -1},
- {-1, -1, -1},
- {-1, 24, 0},
- {-1, 24, 0},
- {-1, 24, 0},
- {-1, 24, 0},
- {-1, 24, 0},
- {-1, 24, 0},
- {-1, 24, 0},
- {-1, 24, 0},
- {24, 0, -1},
- {24, 0, -1},
- {24, 0, -1},
- {24, 0, -1},
- {24, 0, -1},
+};
/* Epll Clock division values to achive different frequency output */ static struct set_epll_con_val exynos5_epll_div[] = { { 192000000, 0, 48, 3, 1, 0 }, @@ -201,6 +244,101 @@ static unsigned long exynos5_get_pll_clk(int pllreg) return fout; }
+unsigned long exynos5_get_periph_rate(enum periph_id peripheral)
static? please int instead of enum periph_id.
+{
- struct clk_bit_info *bit_info = &clk_bit_info[peripheral];
- unsigned long sclk, sub_clk;
- unsigned int src, div, sub_div;
- struct exynos5_clock *clk =
(struct exynos5_clock *)samsung_get_base_clock();
- switch (peripheral) {
- case PERIPH_ID_UART0:
- case PERIPH_ID_UART1:
- case PERIPH_ID_UART2:
- case PERIPH_ID_UART3:
src = readl(&clk->src_peric0);
div = readl(&clk->div_peric0);
break;
- case PERIPH_ID_PWM0:
- case PERIPH_ID_PWM1:
- case PERIPH_ID_PWM2:
- case PERIPH_ID_PWM3:
- case PERIPH_ID_PWM4:
src = readl(&clk->src_peric0);
div = readl(&clk->div_peric3);
break;
- case PERIPH_ID_SPI0:
- case PERIPH_ID_SPI1:
src = readl(&clk->src_peric1);
div = readl(&clk->div_peric1);
break;
- case PERIPH_ID_SPI2:
src = readl(&clk->src_peric1);
div = readl(&clk->div_peric2);
break;
- case PERIPH_ID_SPI3:
- case PERIPH_ID_SPI4:
src = readl(&clk->sclk_src_isp);
div = readl(&clk->sclk_div_isp);
break;
- case PERIPH_ID_SDMMC0:
- case PERIPH_ID_SDMMC1:
- case PERIPH_ID_SDMMC2:
- case PERIPH_ID_SDMMC3:
src = readl(&clk->src_fsys);
div = readl(&clk->div_fsys1);
break;
- case PERIPH_ID_I2C0:
- case PERIPH_ID_I2C1:
- case PERIPH_ID_I2C2:
- case PERIPH_ID_I2C3:
- case PERIPH_ID_I2C4:
- case PERIPH_ID_I2C5:
- case PERIPH_ID_I2C6:
- case PERIPH_ID_I2C7:
sclk = exynos5_get_pll_clk(MPLL);
sub_div = ((readl(&clk->div_top1) >> bit_info->div_bit)
& 0x7) + 1;
div = ((readl(&clk->div_top0) >> bit_info->prediv_bit)
& 0x7) + 1;
return (sclk / sub_div) / div;
- default:
debug("%s: invalid peripheral %d", __func__, peripheral);
return -1;
- };
- src = (src >> bit_info->src_bit) & 0xf;
please add a blank line here.
- if (src == EXYNOS_SRC_MPLL)
sclk = exynos5_get_pll_clk(MPLL);
- else if (src == EXYNOS_SRC_EPLL)
sclk = exynos5_get_pll_clk(EPLL);
- else if (src == EXYNOS_SRC_VPLL)
sclk = exynos5_get_pll_clk(VPLL);
- else
return 0;
why don't you use switch..case?
- /* Ratio clock division for this peripheral */
- sub_div = (div >> bit_info->div_bit) & 0xf;
- sub_clk = sclk / (sub_div + 1);
- /* Pre-ratio clock division for SDMMC0 and 2 */
- if (peripheral == PERIPH_ID_SDMMC0 || peripheral == PERIPH_ID_SDMMC2) {
div = (div >> bit_info->prediv_bit) & 0xff;
return sub_clk / (div + 1);
- }
- return sub_clk;
+}
+unsigned long clock_get_periph_rate(enum periph_id peripheral)
please int instead of enum periph_id.
+{
- if (cpu_is_exynos5())
return exynos5_get_periph_rate(peripheral);
- else
return 0;
+}
/* exynos4: return ARM clock frequency */ static unsigned long exynos4_get_arm_clk(void) { diff --git a/arch/arm/include/asm/arch-exynos/clk.h b/arch/arm/include/asm/arch-exynos/clk.h index 1935b0b..b72c90e 100644 --- a/arch/arm/include/asm/arch-exynos/clk.h +++ b/arch/arm/include/asm/arch-exynos/clk.h @@ -22,6 +22,8 @@ #ifndef __ASM_ARM_ARCH_CLK_H_ #define __ASM_ARM_ARCH_CLK_H_
+#include <asm/arch/periph.h>
I don't want got a dependency with other header file. please remove it.
#define APLL 0 #define MPLL 1 #define EPLL 2 @@ -29,6 +31,12 @@ #define VPLL 4 #define BPLL 5
+enum pll_src_bit {
- EXYNOS_SRC_MPLL = 6,
- EXYNOS_SRC_EPLL,
- EXYNOS_SRC_VPLL,
+};
unsigned long get_pll_clk(int pllreg); unsigned long get_arm_clk(void); unsigned long get_i2c_clk(void); @@ -44,4 +52,13 @@ int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq); int set_epll_clk(unsigned long rate); int set_spi_clk(int periph_id, unsigned int rate);
+/**
- get the clk frequency of the required peripherial
- @param peripherial Peripherial id
- @return frequency of the peripherial clk
- */
typo. peripherial -> peripheral
+unsigned long clock_get_periph_rate(enum periph_id peripheral);
Please clock_get_periph_rate(int periph_id);
#endif
Thanks, Minkyu Kang.