return aclk_66;
}
+ int exynos5_set_epll_clk(unsigned long rate)
+ {
+ unsigned int epll_con, epll_con_k;
+ unsigned int i;
+ unsigned int lockcnt;
+ unsigned int start;
+ struct exynos5_clock *clk =
+ (struct exynos5_clock *)samsung_get_base_clock();
+
+ epll_con = readl(&clk->epll_con0);
+ epll_con &= ~((EPLL_CON0_LOCK_DET_EN_MASK <<
+ EPLL_CON0_LOCK_DET_EN_SHIFT) |
+ EPLL_CON0_MDIV_MASK << EPLL_CON0_MDIV_SHIFT |
+ EPLL_CON0_PDIV_MASK << EPLL_CON0_PDIV_SHIFT |
+ EPLL_CON0_SDIV_MASK << EPLL_CON0_SDIV_SHIFT);
+
+ for (i = 0; i < ARRAY_SIZE(exynos5_epll_div); i++) {
+ if (exynos5_epll_div[i].freq_out == rate)
+ break;
+ }
+
+ if (i == ARRAY_SIZE(exynos5_epll_div))
+ return -1;
+
+ epll_con_k = exynos5_epll_div[i].k_dsm << 0;
+ epll_con |= exynos5_epll_div[i].en_lock_det <<
+ EPLL_CON0_LOCK_DET_EN_SHIFT;
+ epll_con |= exynos5_epll_div[i].m_div << EPLL_CON0_MDIV_SHIFT;
+ epll_con |= exynos5_epll_div[i].p_div << EPLL_CON0_PDIV_SHIFT;
+ epll_con |= exynos5_epll_div[i].s_div << EPLL_CON0_SDIV_SHIFT;
+
+ /*
+ * Required period ( in cycles) to genarate a stable clock output.
+ * The maximum clock time can be up to 3000 * PDIV cycles of PLLs
+ * frequency input (as per spec)
+ */
+ lockcnt = 3000 * exynos5_epll_div[i].p_div;
+
+ writel(lockcnt, &clk->epll_lock);
+ writel(epll_con, &clk->epll_con0);
+ writel(epll_con_k, &clk->epll_con1);
+
+ start = get_timer(0);
+
+ while (!(readl(&clk->epll_con0) &
+ (0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT))) {
+ if (get_timer(start) > TIMEOUT_EPLL_LOCK) {
+ debug("%s: Timeout waiting for EPLL lock\n", __func__);
+ return -1;
+ }
+ }
+ return 0;
+ }
+
+ void exynos5_set_i2s_clk_source(void)
+ {
+ struct exynos5_clock *clk =
+ (struct exynos5_clock *)samsung_get_base_clock();
+
+ clrsetbits_le32(&clk->src_peric1, AUDIO1_SEL_MASK,
+ (CLK_SRC_SCLK_EPLL));
+ }
+
+ int exynos5_set_i2s_clk_prescaler(unsigned int src_frq,
+ unsigned int dst_frq)
+ {
+ struct exynos5_clock *clk =
+ (struct exynos5_clock *)samsung_get_base_clock();
+ unsigned int div;
+
+ if ((dst_frq == 0) || (src_frq == 0)) {
+ debug("%s: Invalid requency input for prescaler\n", __func__);
+ debug("src frq = %d des frq = %d ", src_frq, dst_frq);
+ return -1;
+ }
+
+ div = (src_frq / dst_frq);
+ if (div > AUDIO_1_RATIO_MASK) {
+ debug("%s: Frequency ratio is out of range\n", __func__);
+ debug("src frq = %d des frq = %d ", src_frq, dst_frq);
+ return -1;
+ }
+ clrsetbits_le32(&clk->div_peric4, AUDIO_1_RATIO_MASK,
+ (div & AUDIO_1_RATIO_MASK));
+ return 0;
+ }
+
+ /**
+ * Linearly searches for the most accurate main and fine stage clock scalars
+ * (divisors) for a specified target frequency and scalar bit sizes by checking
+ * all multiples of main_scalar_bits values. Will always return scalars up to or
+ * slower than target.
+ *
+ * @param main_scalar_bits Number of main scalar bits, must be > 0 and < 32
+ * @param fine_scalar_bits Number of fine scalar bits, must be > 0 and < 32
+ * @param input_freq Clock frequency to be scaled in Hz
+ * @param target_freq Desired clock frequency in Hz
+ * @param best_fine_scalar Pointer to store the fine stage divisor
+ *
+ * @return best_main_scalar Main scalar for desired frequency or -1 if none
+ * found
+ */
+ static int clock_calc_best_scalar(unsigned int main_scaler_bits,
+ unsigned int fine_scalar_bits, unsigned int input_rate,
+ unsigned int target_rate, unsigned int *best_fine_scalar)
+ {
+ int i;
+ int best_main_scalar = -1;
+ unsigned int best_error = target_rate;
+ const unsigned int cap = (1 << fine_scalar_bits) - 1;
+ const unsigned int loops = 1 << main_scaler_bits;
+
+ debug("Input Rate is %u, Target is %u, Cap is %u\n", input_rate,
+ target_rate, cap);
+
+ assert(best_fine_scalar != NULL);
+ assert(main_scaler_bits <= fine_scalar_bits);
+
+ *best_fine_scalar = 1;
+
+ if (input_rate == 0 || target_rate == 0)
+ return -1;
+
+ if (target_rate >= input_rate)
+ return 1;
+
+ for (i = 1; i <= loops; i++) {
+ const unsigned int effective_div = max(min(input_rate / i /
+ target_rate, cap), 1);
+ const unsigned int effective_rate = input_rate / i /
+ effective_div;
+ const int error = target_rate - effective_rate;
+
+ debug("%d|effdiv:%u, effrate:%u, error:%d\n", i, effective_div,
+ effective_rate, error);
+
+ if (error >= 0 && error <= best_error) {
+ best_error = error;
+ best_main_scalar = i;
+ *best_fine_scalar = effective_div;
+ }
+ }
+
+ return best_main_scalar;
+ }
+
+ static int exynos5_set_spi_clk(enum periph_id periph_id,
+ unsigned int rate)
+ {
+ struct exynos5_clock *clk =
+ (struct exynos5_clock *)samsung_get_base_clock();
+ int main;
+ unsigned int fine;
+ unsigned shift, pre_shift;
+ unsigned mask = 0xff;
+ u32 *reg;
+
+ main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
+ if (main < 0) {
+ debug("%s: Cannot set clock rate for periph %d",
+ __func__, periph_id);
+ return -1;
+ }
+ main = main - 1;
+ fine = fine - 1;
+
+ switch (periph_id) {
+ case PERIPH_ID_SPI0:
+ reg = &clk->div_peric1;
+ shift = 0;
+ pre_shift = 8;
+ break;
+ case PERIPH_ID_SPI1:
+ reg = &clk->div_peric1;
+ shift = 16;
+ pre_shift = 24;
+ break;
+ case PERIPH_ID_SPI2:
+ reg = &clk->div_peric2;
+ shift = 0;
+ pre_shift = 8;
+ break;
+ case PERIPH_ID_SPI3:
+ reg = &clk->sclk_div_isp;
+ shift = 0;
+ pre_shift = 4;
+ break;
+ case PERIPH_ID_SPI4:
+ reg = &clk->sclk_div_isp;
+ shift = 12;
+ pre_shift = 16;
+ break;
+ default:
+ debug("%s: Unsupported peripheral ID %d\n", __func__,
+ periph_id);
+ return -1;
+ }
+ clrsetbits_le32(reg, mask << shift, (main & mask) << shift);
+ clrsetbits_le32(reg, mask << pre_shift, (fine & mask) << pre_shift);
+
+ return 0;
++}
+
+++ static unsigned long exynos4_get_i2c_clk(void)
+++ {
+++ struct exynos4_clock *clk =
+++ (struct exynos4_clock *)samsung_get_base_clock();
+++ unsigned long sclk, aclk_100;
+++ unsigned int ratio;
+++
+++ sclk = get_pll_clk(APLL);
+++
+++ ratio = (readl(&clk->div_top)) >> 4;
+++ ratio &= 0xf;
+++ aclk_100 = sclk / (ratio + 1);
+++ return aclk_100;
+++ }
+++
unsigned long get_pll_clk(int pllreg)
{
if (cpu_is_exynos5())
case PERIPH_ID_I2C7:
exynos5_i2c_config(peripheral, flags);
break;
-- -static int exynos4_mmc_config(int peripheral, int flags)
-{
- struct exynos4_gpio_part2 *gpio2 =
- (struct exynos4_gpio_part2 *)samsung_get_base_gpio_part2();
- struct s5p_gpio_bank *bank, *bank_ext;
- int i;
-
- switch (peripheral) {
- case PERIPH_ID_SDMMC0:
- bank = &gpio2->k0;
- bank_ext = &gpio2->k1;
- break;
- case PERIPH_ID_SDMMC2:
- bank = &gpio2->k2;
- bank_ext = &gpio2->k3;
- break;
- default:
- return -1;
- }
- for (i = 0; i < 7; i++) {
- if (i == 2)
- continue;
- s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
- s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
- s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
- }
- if (flags & PINMUX_FLAG_8BIT_MODE) {
- for (i = 3; i < 7; i++) {
- s5p_gpio_cfg_pin(bank_ext, i, GPIO_FUNC(0x3));
- s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_NONE);
- s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X);
- }
- }
-
- return 0;
-}
-
-static int exynos4_pinmux_config(int peripheral, int flags)
-{
- switch (peripheral) {
- case PERIPH_ID_SDMMC0:
- case PERIPH_ID_SDMMC2:
- return exynos4_mmc_config(peripheral, flags);
- case PERIPH_ID_SDMMC1:
- case PERIPH_ID_SDMMC3:
- case PERIPH_ID_SDMMC4:
- printf("SDMMC device %d not implemented\n", peripheral);
- return -1;
- default:
- debug("%s: invalid peripheral %d", __func__, peripheral);
- return -1;
- }
-
- return 0;
-}
-
+ case PERIPH_ID_I2S1:
+ exynos5_i2s_config(peripheral);
+ break;
+ case PERIPH_ID_SPI0:
+ case PERIPH_ID_SPI1:
+ case PERIPH_ID_SPI2:
+ case PERIPH_ID_SPI3:
+ case PERIPH_ID_SPI4:
+ exynos5_spi_config(peripheral);
+ break;
+ default:
+ debug("%s: invalid peripheral %d", __func__, peripheral);
+ return -1;
+ }
+
+ return 0;
+ }
+
-- struct exynos4_gpio_part2 *gpio2 =
-- (struct exynos4_gpio_part2 *)samsung_get_base_gpio_part2();
-- struct s5p_gpio_bank *bank, *bank_ext;
-- int i;
+++ static void exynos4_i2c_config(int peripheral, int flags)
+ {
-- case PERIPH_ID_SDMMC0:
-- bank = &gpio2->k0;
-- bank_ext = &gpio2->k1;
+++ struct exynos4_gpio_part1 *gpio1 =
+++ (struct exynos4_gpio_part1 *) samsung_get_base_gpio_part1();
+
+ switch (peripheral) {
-- case PERIPH_ID_SDMMC2:
-- bank = &gpio2->k2;
-- bank_ext = &gpio2->k3;
+++ case PERIPH_ID_I2C0:
+++ s5p_gpio_cfg_pin(&gpio1->d1, 0, GPIO_FUNC(0x2));
+++ s5p_gpio_cfg_pin(&gpio1->d1, 1, GPIO_FUNC(0x2));
+ break;
-- default:
-- return -1;
-- }
-- for (i = 0; i < 7; i++) {
-- if (i == 2)
-- continue;
-- s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
-- s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
-- s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
-- }
-- if (flags & PINMUX_FLAG_8BIT_MODE) {
-- for (i = 3; i < 7; i++) {
-- s5p_gpio_cfg_pin(bank_ext, i, GPIO_FUNC(0x3));
-- s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_NONE);
-- s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X);
-- }
+++ case PERIPH_ID_I2C1:
+++ s5p_gpio_cfg_pin(&gpio1->d1, 2, GPIO_FUNC(0x2));
+++ s5p_gpio_cfg_pin(&gpio1->d1, 3, GPIO_FUNC(0x2));
+++ break;
+++ case PERIPH_ID_I2C2:
+++ s5p_gpio_cfg_pin(&gpio1->a0, 6, GPIO_FUNC(0x3));
+++ s5p_gpio_cfg_pin(&gpio1->a0, 7, GPIO_FUNC(0x3));
+++ break;
+++ case PERIPH_ID_I2C3:
+++ s5p_gpio_cfg_pin(&gpio1->a1, 2, GPIO_FUNC(0x3));
+++ s5p_gpio_cfg_pin(&gpio1->a1, 3, GPIO_FUNC(0x3));
+++ break;
+++ case PERIPH_ID_I2C4:
+++ s5p_gpio_cfg_pin(&gpio1->b, 2, GPIO_FUNC(0x3));
+++ s5p_gpio_cfg_pin(&gpio1->b, 3, GPIO_FUNC(0x3));
+++ break;
+++ case PERIPH_ID_I2C5:
+++ s5p_gpio_cfg_pin(&gpio1->b, 6, GPIO_FUNC(0x3));
+++ s5p_gpio_cfg_pin(&gpio1->b, 7, GPIO_FUNC(0x3));
+++ break;
+++ case PERIPH_ID_I2C6:
+++ s5p_gpio_cfg_pin(&gpio1->c1, 3, GPIO_FUNC(0x4));
+++ s5p_gpio_cfg_pin(&gpio1->c1, 4, GPIO_FUNC(0x4));
+++ break;
+++ case PERIPH_ID_I2C7:
+++ s5p_gpio_cfg_pin(&gpio1->d0, 2, GPIO_FUNC(0x3));
+++ s5p_gpio_cfg_pin(&gpio1->d0, 3, GPIO_FUNC(0x3));
+ break;
--
-- return 0;
+ }
-- case PERIPH_ID_SDMMC0:
-- case PERIPH_ID_SDMMC2:
-- return exynos4_mmc_config(peripheral, flags);
-- case PERIPH_ID_SDMMC1:
-- case PERIPH_ID_SDMMC3:
-- case PERIPH_ID_SDMMC4:
-- printf("SDMMC device %d not implemented\n", peripheral);
-- return -1;
+ }
+
+ static int exynos4_pinmux_config(int peripheral, int flags)
+ {
+ switch (peripheral) {
+++ 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:
+++ exynos4_i2c_config(peripheral, flags);
+++ break;
default:
debug("%s: invalid peripheral %d", __func__, peripheral);
return -1;
#define CONFIG_I2C_MULTI_BUS
#define CONFIG_MAX_I2C_NUM 8
#define CONFIG_SYS_I2C_SLAVE 0x0
+++ #define CONFIG_I2C_EDID
++
++ /* PMIC */
++ #define CONFIG_PMIC
++ #define CONFIG_PMIC_I2C
++ #define CONFIG_PMIC_MAX77686
++
++ /* SPI */
++ #define CONFIG_ENV_IS_IN_SPI_FLASH
++ #define CONFIG_SPI_FLASH
++
++ #ifdef CONFIG_SPI_FLASH
++ #define CONFIG_EXYNOS_SPI
++ #define CONFIG_CMD_SF
+++#define CONFIG_CMD_SPI
+++#define CONFIG_SPI_FLASH_WINBOND
+++#define CONFIG_SF_DEFAULT_MODE SPI_MODE_0
+++#define CONFIG_SF_DEFAULT_SPEED 50000000
+++#define EXYNOS5_SPI_NUM_CONTROLLERS 5
+++#endif
+++
+++#ifdef CONFIG_ENV_IS_IN_SPI_FLASH
+++#define CONFIG_ENV_SPI_MODE SPI_MODE_0
+++#define CONFIG_ENV_SECT_SIZE CONFIG_ENV_SIZE
+++#define CONFIG_ENV_SPI_BUS 1
+++#define CONFIG_ENV_SPI_MAX_HZ 50000000
+++#endif
++
+ ++/* PMIC */
+ ++#define CONFIG_POWER
+ ++#define CONFIG_POWER_I2C
+ ++#define CONFIG_POWER_MAX77686
+ ++
+ ++/* SPI */
+ ++#define CONFIG_ENV_IS_IN_SPI_FLASH
+ ++#define CONFIG_SPI_FLASH
+ ++
+ ++#ifdef CONFIG_SPI_FLASH
+ ++#define CONFIG_EXYNOS_SPI
+ ++#define CONFIG_CMD_SF
+ + #define CONFIG_CMD_SPI
+ + #define CONFIG_SPI_FLASH_WINBOND
+ + #define CONFIG_SF_DEFAULT_MODE SPI_MODE_0
+ + #define CONFIG_SF_DEFAULT_SPEED 50000000
+ + #define EXYNOS5_SPI_NUM_CONTROLLERS 5
+ + #endif
+ +
+ + #ifdef CONFIG_ENV_IS_IN_SPI_FLASH
+ + #define CONFIG_ENV_SPI_MODE SPI_MODE_0
+ + #define CONFIG_ENV_SECT_SIZE CONFIG_ENV_SIZE
+ + #define CONFIG_ENV_SPI_BUS 1
+ + #define CONFIG_ENV_SPI_MAX_HZ 50000000
+ + #endif
+
/* Ethernet Controllor Driver */
#ifdef CONFIG_CMD_NET
#define CONFIG_SMC911X