diff options
author | Alan Hourihane <alanh@fairlite.demon.co.uk> | 2007-05-08 03:39:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-08 14:15:32 -0400 |
commit | dbe7e429fedb3fbc93b496cc1c3eb4fc28333ac0 (patch) | |
tree | 9f88a999af677f65beb7041604c3a5d63bfc58db /drivers/video/vermilion/cr_pll.c | |
parent | 249bdbbf0dbab5554a4bfe55639e324d4758da96 (diff) |
vmlfb: framebuffer driver for Intel Vermilion Range
Add the Intel Vermilion Range framebuffer support.
Signed-off-by: Alan Hourihane <alanh@tungstengraphics.com>
Signed-off-by: Antonino Daplas <adaplas@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video/vermilion/cr_pll.c')
-rw-r--r-- | drivers/video/vermilion/cr_pll.c | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/drivers/video/vermilion/cr_pll.c b/drivers/video/vermilion/cr_pll.c new file mode 100644 index 000000000000..ebc6e6e0dd0f --- /dev/null +++ b/drivers/video/vermilion/cr_pll.c | |||
@@ -0,0 +1,208 @@ | |||
1 | /* | ||
2 | * Copyright (c) Intel Corp. 2007. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to | ||
6 | * develop this driver. | ||
7 | * | ||
8 | * This file is part of the Carillo Ranch video subsystem driver. | ||
9 | * The Carillo Ranch video subsystem driver is free software; | ||
10 | * you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * The Carillo Ranch video subsystem driver is distributed | ||
16 | * in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this driver; if not, write to the Free Software | ||
23 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
24 | * | ||
25 | * Authors: | ||
26 | * Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> | ||
27 | * Alan Hourihane <alanh-at-tungstengraphics-dot-com> | ||
28 | */ | ||
29 | |||
30 | #include <linux/module.h> | ||
31 | #include <linux/kernel.h> | ||
32 | #include <linux/pci.h> | ||
33 | #include <linux/errno.h> | ||
34 | #include <linux/fb.h> | ||
35 | #include "vermilion.h" | ||
36 | |||
37 | /* The PLL Clock register sits on Host bridge */ | ||
38 | #define CRVML_DEVICE_MCH 0x5001 | ||
39 | #define CRVML_REG_MCHBAR 0x44 | ||
40 | #define CRVML_REG_MCHEN 0x54 | ||
41 | #define CRVML_MCHEN_BIT (1 << 28) | ||
42 | #define CRVML_MCHMAP_SIZE 4096 | ||
43 | #define CRVML_REG_CLOCK 0xc3c | ||
44 | #define CRVML_CLOCK_SHIFT 8 | ||
45 | #define CRVML_CLOCK_MASK 0x00000f00 | ||
46 | |||
47 | static struct pci_dev *mch_dev; | ||
48 | static u32 mch_bar; | ||
49 | static void __iomem *mch_regs_base; | ||
50 | static u32 saved_clock; | ||
51 | |||
52 | static const unsigned crvml_clocks[] = { | ||
53 | 6750, | ||
54 | 13500, | ||
55 | 27000, | ||
56 | 29700, | ||
57 | 37125, | ||
58 | 54000, | ||
59 | 59400, | ||
60 | 74250, | ||
61 | 120000 | ||
62 | /* | ||
63 | * There are more clocks, but they are disabled on the CR board. | ||
64 | */ | ||
65 | }; | ||
66 | |||
67 | static const u32 crvml_clock_bits[] = { | ||
68 | 0x0a, | ||
69 | 0x09, | ||
70 | 0x08, | ||
71 | 0x07, | ||
72 | 0x06, | ||
73 | 0x05, | ||
74 | 0x04, | ||
75 | 0x03, | ||
76 | 0x0b | ||
77 | }; | ||
78 | |||
79 | static const unsigned crvml_num_clocks = ARRAY_SIZE(crvml_clocks); | ||
80 | |||
81 | static int crvml_sys_restore(struct vml_sys *sys) | ||
82 | { | ||
83 | void __iomem *clock_reg = mch_regs_base + CRVML_REG_CLOCK; | ||
84 | |||
85 | iowrite32(saved_clock, clock_reg); | ||
86 | ioread32(clock_reg); | ||
87 | |||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | static int crvml_sys_save(struct vml_sys *sys) | ||
92 | { | ||
93 | void __iomem *clock_reg = mch_regs_base + CRVML_REG_CLOCK; | ||
94 | |||
95 | saved_clock = ioread32(clock_reg); | ||
96 | |||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | static int crvml_nearest_index(const struct vml_sys *sys, int clock) | ||
101 | { | ||
102 | int i; | ||
103 | int cur_index = 0; | ||
104 | int cur_diff; | ||
105 | int diff; | ||
106 | |||
107 | cur_diff = clock - crvml_clocks[0]; | ||
108 | cur_diff = (cur_diff < 0) ? -cur_diff : cur_diff; | ||
109 | for (i = 1; i < crvml_num_clocks; ++i) { | ||
110 | diff = clock - crvml_clocks[i]; | ||
111 | diff = (diff < 0) ? -diff : diff; | ||
112 | if (diff < cur_diff) { | ||
113 | cur_index = i; | ||
114 | cur_diff = diff; | ||
115 | } | ||
116 | } | ||
117 | return cur_index; | ||
118 | } | ||
119 | |||
120 | static int crvml_nearest_clock(const struct vml_sys *sys, int clock) | ||
121 | { | ||
122 | return crvml_clocks[crvml_nearest_index(sys, clock)]; | ||
123 | } | ||
124 | |||
125 | static int crvml_set_clock(struct vml_sys *sys, int clock) | ||
126 | { | ||
127 | void __iomem *clock_reg = mch_regs_base + CRVML_REG_CLOCK; | ||
128 | int index; | ||
129 | u32 clock_val; | ||
130 | |||
131 | index = crvml_nearest_index(sys, clock); | ||
132 | |||
133 | if (crvml_clocks[index] != clock) | ||
134 | return -EINVAL; | ||
135 | |||
136 | clock_val = ioread32(clock_reg) & ~CRVML_CLOCK_MASK; | ||
137 | clock_val = crvml_clock_bits[index] << CRVML_CLOCK_SHIFT; | ||
138 | iowrite32(clock_val, clock_reg); | ||
139 | ioread32(clock_reg); | ||
140 | |||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | static struct vml_sys cr_pll_ops = { | ||
145 | .name = "Carillo Ranch", | ||
146 | .save = crvml_sys_save, | ||
147 | .restore = crvml_sys_restore, | ||
148 | .set_clock = crvml_set_clock, | ||
149 | .nearest_clock = crvml_nearest_clock, | ||
150 | }; | ||
151 | |||
152 | static int __init cr_pll_init(void) | ||
153 | { | ||
154 | int err; | ||
155 | u32 dev_en; | ||
156 | |||
157 | mch_dev = pci_get_device(PCI_VENDOR_ID_INTEL, | ||
158 | CRVML_DEVICE_MCH, NULL); | ||
159 | if (!mch_dev) { | ||
160 | printk(KERN_ERR | ||
161 | "Could not find Carillo Ranch MCH device.\n"); | ||
162 | return -ENODEV; | ||
163 | } | ||
164 | |||
165 | pci_read_config_dword(mch_dev, CRVML_REG_MCHEN, &dev_en); | ||
166 | if (!(dev_en & CRVML_MCHEN_BIT)) { | ||
167 | printk(KERN_ERR | ||
168 | "Carillo Ranch MCH device was not enabled.\n"); | ||
169 | pci_dev_put(mch_dev); | ||
170 | return -ENODEV; | ||
171 | } | ||
172 | |||
173 | pci_read_config_dword(mch_dev, CRVML_REG_MCHBAR, | ||
174 | &mch_bar); | ||
175 | mch_regs_base = | ||
176 | ioremap_nocache(mch_bar, CRVML_MCHMAP_SIZE); | ||
177 | if (!mch_regs_base) { | ||
178 | printk(KERN_ERR | ||
179 | "Carillo Ranch MCH device was not enabled.\n"); | ||
180 | pci_dev_put(mch_dev); | ||
181 | return -ENODEV; | ||
182 | } | ||
183 | |||
184 | err = vmlfb_register_subsys(&cr_pll_ops); | ||
185 | if (err) { | ||
186 | printk(KERN_ERR | ||
187 | "Carillo Ranch failed to initialize vml_sys.\n"); | ||
188 | pci_dev_put(mch_dev); | ||
189 | return err; | ||
190 | } | ||
191 | |||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | static void __exit cr_pll_exit(void) | ||
196 | { | ||
197 | vmlfb_unregister_subsys(&cr_pll_ops); | ||
198 | |||
199 | iounmap(mch_regs_base); | ||
200 | pci_dev_put(mch_dev); | ||
201 | } | ||
202 | |||
203 | module_init(cr_pll_init); | ||
204 | module_exit(cr_pll_exit); | ||
205 | |||
206 | MODULE_AUTHOR("Tungsten Graphics Inc."); | ||
207 | MODULE_DESCRIPTION("Carillo Ranch PLL Driver"); | ||
208 | MODULE_LICENSE("GPL"); | ||