OLD | NEW |
(Empty) | |
| 1 /* linux/drivers/media/video/samsung/tv20/tv_clock_s5pv210.c |
| 2 * |
| 3 * Copyright (c) 2010 Samsung Electronics Co., Ltd. |
| 4 * http://www.samsung.com/ |
| 5 * |
| 6 * S5PV210 - clock raw ftn file for Samsung TVOut driver |
| 7 * |
| 8 * This program is free software; you can redistribute it and/or modify |
| 9 * it under the terms of the GNU General Public License version 2 as |
| 10 * published by the Free Software Foundation. |
| 11 */ |
| 12 |
| 13 #include <linux/module.h> |
| 14 #include <linux/kernel.h> |
| 15 #include <linux/delay.h> |
| 16 #include <linux/platform_device.h> |
| 17 #include <linux/clk.h> |
| 18 |
| 19 #include <linux/uaccess.h> |
| 20 #include <linux/io.h> |
| 21 |
| 22 #include <mach/map.h> |
| 23 #include <mach/regs-clock.h> |
| 24 |
| 25 #include "tv_out_s5pv210.h" |
| 26 #include <mach/regs-hdmi_clock.h> |
| 27 |
| 28 #ifdef CONFIG_TVOUT_RAW_DBG |
| 29 #define S5P_TVOUT_CLK_DEBUG 1 |
| 30 #endif |
| 31 |
| 32 #ifdef S5P_TVOUT_CLK_DEBUG |
| 33 #define TVCLKPRINTK(fmt, args...) \ |
| 34 printk(KERN_INFO "\t\t[TVCLK] %s: " fmt, __func__ , ## args) |
| 35 #else |
| 36 #define TVCLKPRINTK(fmt, args...) |
| 37 #endif |
| 38 |
| 39 |
| 40 void tv_clk_init_hpll(unsigned int lock_time, |
| 41 bool vsel, |
| 42 unsigned int mdiv, |
| 43 unsigned int pdiv, |
| 44 unsigned int sdiv) |
| 45 { |
| 46 u32 temp; |
| 47 |
| 48 TVCLKPRINTK("%d,%d,%d,%d\n\r", lock_time, mdiv, pdiv, sdiv); |
| 49 |
| 50 temp = readl(S5P_VPLL_CON); |
| 51 |
| 52 temp &= ~VPLL_ENABLE; |
| 53 |
| 54 writel(temp, S5P_VPLL_CON); |
| 55 |
| 56 temp = 0; |
| 57 |
| 58 if (vsel) |
| 59 temp |= VCO_FREQ_SEL; |
| 60 |
| 61 temp |= VPLL_ENABLE; |
| 62 temp |= MDIV(mdiv) | PDIV(pdiv) | SDIV(sdiv); |
| 63 |
| 64 writel(VPLL_LOCKTIME(lock_time), S5P_VPLL_LOCK); |
| 65 writel(temp, S5P_VPLL_CON); |
| 66 |
| 67 while (!VPLL_LOCKED(readl(S5P_VPLL_CON))) |
| 68 ; |
| 69 |
| 70 TVCLKPRINTK("0x%08x,0x%08x\n\r", |
| 71 readl(S5P_VPLL_LOCK), readl(S5P_VPLL_CON)); |
| 72 } |
| 73 |
| 74 /* prevent hdmi hang-up when reboot */ |
| 75 int tv_clk_change_internal(void) |
| 76 { |
| 77 u32 reg = readl(S5P_CLK_SRC1); |
| 78 /* set to SCLK_DAC */ |
| 79 reg &= HDMI_SEL_MASK; |
| 80 /* set to SCLK_PIXEL */ |
| 81 reg &= VMIXER_SEL_MASK; |
| 82 |
| 83 writel(reg, S5P_CLK_SRC1); |
| 84 |
| 85 return 0; |
| 86 } |
| 87 |
| 88 enum s5p_tv_clk_err tv_clk_init_mout_hpll(enum s5p_tv_clk_mout_hpll mout_hpll) |
| 89 { |
| 90 TVCLKPRINTK("(%d)\n\r", mout_hpll); |
| 91 |
| 92 writel(readl(S5P_CLK_SRC1) | HDMI_SEL_HDMIPHY, S5P_CLK_SRC1); |
| 93 |
| 94 TVCLKPRINTK("S5P_CLK_SRC1 :0x%08x\n", readl(S5P_CLK_SRC1)); |
| 95 return S5P_TV_CLK_ERR_NO_ERROR; |
| 96 } |
| 97 |
| 98 enum s5p_tv_clk_err tv_clk_init_video_mixer( |
| 99 enum s5p_tv_clk_vmiexr_srcclk src_clk) |
| 100 { |
| 101 switch (src_clk) { |
| 102 |
| 103 /* for analog tv out 0:SCLK_DAC */ |
| 104 case TVOUT_CLK_VMIXER_SRCCLK_VCLK_54: |
| 105 writel(readl(S5P_CLK_SRC1) & VMIXER_SEL_MASK, S5P_CLK_SRC1); |
| 106 break; |
| 107 |
| 108 /* for digital hdmi_phy 1: SCLK_HDMI */ |
| 109 case TVOUT_CLK_VMIXER_SRCCLK_MOUT_HPLL: |
| 110 writel(readl(S5P_CLK_SRC1) | VMIXER_SEL_MOUT_VPLL, |
| 111 S5P_CLK_SRC1); |
| 112 break; |
| 113 |
| 114 default: |
| 115 TVCLKPRINTK("[ERR] invalid src_clk parameter = %d\n", src_clk); |
| 116 return S5P_TV_CLK_ERR_INVALID_PARAM; |
| 117 } |
| 118 |
| 119 TVCLKPRINTK("S5P_CLK_SRC1 :0x%08x\n", readl(S5P_CLK_SRC1)); |
| 120 |
| 121 return S5P_TV_CLK_ERR_NO_ERROR; |
| 122 } |
| 123 |
| 124 void tv_clk_init_hdmi_ratio(unsigned int clk_div) |
| 125 { |
| 126 TVCLKPRINTK("(%d)\n\r", clk_div); |
| 127 |
| 128 writel((readl(S5P_CLK_DIV1) & HDMI_DIV_RATIO_MASK) | |
| 129 HDMI_DIV_RATIO(clk_div), S5P_CLK_DIV1); |
| 130 |
| 131 TVCLKPRINTK("(0x%08x)\n\r", readl(S5P_CLK_DIV3)); |
| 132 } |
| 133 |
OLD | NEW |