#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 },
        return fout;
 }
 
+static unsigned long exynos5_get_periph_rate(int peripheral)
+{
+       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;
+
+       switch (src) {
+       case EXYNOS_SRC_MPLL:
+               sclk = exynos5_get_pll_clk(MPLL);
+               break;
+       case EXYNOS_SRC_EPLL:
+               sclk = exynos5_get_pll_clk(EPLL);
+               break;
+       case EXYNOS_SRC_VPLL:
+               sclk = exynos5_get_pll_clk(VPLL);
+               break;
+       default:
+               return 0;
+       }
+
+       /* 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(int peripheral)
+{
+       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)
 {