dss.c 21 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037
  1. /*
  2. * linux/drivers/video/omap2/dss/dss.c
  3. *
  4. * Copyright (C) 2009 Nokia Corporation
  5. * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
  6. *
  7. * Some code and ideas taken from drivers/video/omap/ driver
  8. * by Imre Deak.
  9. *
  10. * This program is free software; you can redistribute it and/or modify it
  11. * under the terms of the GNU General Public License version 2 as published by
  12. * the Free Software Foundation.
  13. *
  14. * This program is distributed in the hope that it will be useful, but WITHOUT
  15. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  16. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  17. * more details.
  18. *
  19. * You should have received a copy of the GNU General Public License along with
  20. * this program. If not, see <http://www.gnu.org/licenses/>.
  21. */
  22. #define DSS_SUBSYS_NAME "DSS"
  23. #include <linux/kernel.h>
  24. #include <linux/io.h>
  25. #include <linux/err.h>
  26. #include <linux/delay.h>
  27. #include <linux/interrupt.h>
  28. #include <linux/seq_file.h>
  29. #include <linux/clk.h>
  30. #include <plat/display.h>
  31. #include <plat/clock.h>
  32. #include "dss.h"
  33. #define DSS_SZ_REGS SZ_512
  34. struct dss_reg {
  35. u16 idx;
  36. };
  37. #define DSS_REG(idx) ((const struct dss_reg) { idx })
  38. #define DSS_REVISION DSS_REG(0x0000)
  39. #define DSS_SYSCONFIG DSS_REG(0x0010)
  40. #define DSS_SYSSTATUS DSS_REG(0x0014)
  41. #define DSS_IRQSTATUS DSS_REG(0x0018)
  42. #define DSS_CONTROL DSS_REG(0x0040)
  43. #define DSS_SDI_CONTROL DSS_REG(0x0044)
  44. #define DSS_PLL_CONTROL DSS_REG(0x0048)
  45. #define DSS_SDI_STATUS DSS_REG(0x005C)
  46. #define REG_GET(idx, start, end) \
  47. FLD_GET(dss_read_reg(idx), start, end)
  48. #define REG_FLD_MOD(idx, val, start, end) \
  49. dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end))
  50. static struct {
  51. struct platform_device *pdev;
  52. void __iomem *base;
  53. int ctx_id;
  54. struct clk *dpll4_m4_ck;
  55. struct clk *dss_ick;
  56. struct clk *dss1_fck;
  57. struct clk *dss2_fck;
  58. struct clk *dss_54m_fck;
  59. struct clk *dss_96m_fck;
  60. unsigned num_clks_enabled;
  61. unsigned long cache_req_pck;
  62. unsigned long cache_prate;
  63. struct dss_clock_info cache_dss_cinfo;
  64. struct dispc_clock_info cache_dispc_cinfo;
  65. enum dss_clk_source dsi_clk_source;
  66. enum dss_clk_source dispc_clk_source;
  67. u32 ctx[DSS_SZ_REGS / sizeof(u32)];
  68. int dss_irq;
  69. } dss;
  70. static void dss_clk_enable_all_no_ctx(void);
  71. static void dss_clk_disable_all_no_ctx(void);
  72. static void dss_clk_enable_no_ctx(enum dss_clock clks);
  73. static void dss_clk_disable_no_ctx(enum dss_clock clks);
  74. static int _omap_dss_wait_reset(void);
  75. static inline void dss_write_reg(const struct dss_reg idx, u32 val)
  76. {
  77. __raw_writel(val, dss.base + idx.idx);
  78. }
  79. static inline u32 dss_read_reg(const struct dss_reg idx)
  80. {
  81. return __raw_readl(dss.base + idx.idx);
  82. }
  83. #define SR(reg) \
  84. dss.ctx[(DSS_##reg).idx / sizeof(u32)] = dss_read_reg(DSS_##reg)
  85. #define RR(reg) \
  86. dss_write_reg(DSS_##reg, dss.ctx[(DSS_##reg).idx / sizeof(u32)])
  87. void dss_save_context(void)
  88. {
  89. if (cpu_is_omap24xx())
  90. return;
  91. SR(SYSCONFIG);
  92. SR(CONTROL);
  93. #ifdef CONFIG_OMAP2_DSS_SDI
  94. SR(SDI_CONTROL);
  95. SR(PLL_CONTROL);
  96. #endif
  97. }
  98. void dss_restore_context(void)
  99. {
  100. if (_omap_dss_wait_reset())
  101. DSSERR("DSS not coming out of reset after sleep\n");
  102. RR(SYSCONFIG);
  103. RR(CONTROL);
  104. #ifdef CONFIG_OMAP2_DSS_SDI
  105. RR(SDI_CONTROL);
  106. RR(PLL_CONTROL);
  107. #endif
  108. }
  109. #undef SR
  110. #undef RR
  111. void dss_sdi_init(u8 datapairs)
  112. {
  113. u32 l;
  114. BUG_ON(datapairs > 3 || datapairs < 1);
  115. l = dss_read_reg(DSS_SDI_CONTROL);
  116. l = FLD_MOD(l, 0xf, 19, 15); /* SDI_PDIV */
  117. l = FLD_MOD(l, datapairs-1, 3, 2); /* SDI_PRSEL */
  118. l = FLD_MOD(l, 2, 1, 0); /* SDI_BWSEL */
  119. dss_write_reg(DSS_SDI_CONTROL, l);
  120. l = dss_read_reg(DSS_PLL_CONTROL);
  121. l = FLD_MOD(l, 0x7, 25, 22); /* SDI_PLL_FREQSEL */
  122. l = FLD_MOD(l, 0xb, 16, 11); /* SDI_PLL_REGN */
  123. l = FLD_MOD(l, 0xb4, 10, 1); /* SDI_PLL_REGM */
  124. dss_write_reg(DSS_PLL_CONTROL, l);
  125. }
  126. int dss_sdi_enable(void)
  127. {
  128. unsigned long timeout;
  129. dispc_pck_free_enable(1);
  130. /* Reset SDI PLL */
  131. REG_FLD_MOD(DSS_PLL_CONTROL, 1, 18, 18); /* SDI_PLL_SYSRESET */
  132. udelay(1); /* wait 2x PCLK */
  133. /* Lock SDI PLL */
  134. REG_FLD_MOD(DSS_PLL_CONTROL, 1, 28, 28); /* SDI_PLL_GOBIT */
  135. /* Waiting for PLL lock request to complete */
  136. timeout = jiffies + msecs_to_jiffies(500);
  137. while (dss_read_reg(DSS_SDI_STATUS) & (1 << 6)) {
  138. if (time_after_eq(jiffies, timeout)) {
  139. DSSERR("PLL lock request timed out\n");
  140. goto err1;
  141. }
  142. }
  143. /* Clearing PLL_GO bit */
  144. REG_FLD_MOD(DSS_PLL_CONTROL, 0, 28, 28);
  145. /* Waiting for PLL to lock */
  146. timeout = jiffies + msecs_to_jiffies(500);
  147. while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 5))) {
  148. if (time_after_eq(jiffies, timeout)) {
  149. DSSERR("PLL lock timed out\n");
  150. goto err1;
  151. }
  152. }
  153. dispc_lcd_enable_signal(1);
  154. /* Waiting for SDI reset to complete */
  155. timeout = jiffies + msecs_to_jiffies(500);
  156. while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 2))) {
  157. if (time_after_eq(jiffies, timeout)) {
  158. DSSERR("SDI reset timed out\n");
  159. goto err2;
  160. }
  161. }
  162. return 0;
  163. err2:
  164. dispc_lcd_enable_signal(0);
  165. err1:
  166. /* Reset SDI PLL */
  167. REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
  168. dispc_pck_free_enable(0);
  169. return -ETIMEDOUT;
  170. }
  171. void dss_sdi_disable(void)
  172. {
  173. dispc_lcd_enable_signal(0);
  174. dispc_pck_free_enable(0);
  175. /* Reset SDI PLL */
  176. REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
  177. }
  178. void dss_dump_clocks(struct seq_file *s)
  179. {
  180. unsigned long dpll4_ck_rate;
  181. unsigned long dpll4_m4_ck_rate;
  182. dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
  183. dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
  184. dpll4_m4_ck_rate = clk_get_rate(dss.dpll4_m4_ck);
  185. seq_printf(s, "- DSS -\n");
  186. seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
  187. if (cpu_is_omap3630())
  188. seq_printf(s, "dss1_alwon_fclk = %lu / %lu = %lu\n",
  189. dpll4_ck_rate,
  190. dpll4_ck_rate / dpll4_m4_ck_rate,
  191. dss_clk_get_rate(DSS_CLK_FCK));
  192. else
  193. seq_printf(s, "dss1_alwon_fclk = %lu / %lu * 2 = %lu\n",
  194. dpll4_ck_rate,
  195. dpll4_ck_rate / dpll4_m4_ck_rate,
  196. dss_clk_get_rate(DSS_CLK_FCK));
  197. dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
  198. }
  199. void dss_dump_regs(struct seq_file *s)
  200. {
  201. #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r))
  202. dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
  203. DUMPREG(DSS_REVISION);
  204. DUMPREG(DSS_SYSCONFIG);
  205. DUMPREG(DSS_SYSSTATUS);
  206. DUMPREG(DSS_IRQSTATUS);
  207. DUMPREG(DSS_CONTROL);
  208. DUMPREG(DSS_SDI_CONTROL);
  209. DUMPREG(DSS_PLL_CONTROL);
  210. DUMPREG(DSS_SDI_STATUS);
  211. dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
  212. #undef DUMPREG
  213. }
  214. void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
  215. {
  216. int b;
  217. BUG_ON(clk_src != DSS_SRC_DSI1_PLL_FCLK &&
  218. clk_src != DSS_SRC_DSS1_ALWON_FCLK);
  219. b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1;
  220. if (clk_src == DSS_SRC_DSI1_PLL_FCLK)
  221. dsi_wait_dsi1_pll_active();
  222. REG_FLD_MOD(DSS_CONTROL, b, 0, 0); /* DISPC_CLK_SWITCH */
  223. dss.dispc_clk_source = clk_src;
  224. }
  225. void dss_select_dsi_clk_source(enum dss_clk_source clk_src)
  226. {
  227. int b;
  228. BUG_ON(clk_src != DSS_SRC_DSI2_PLL_FCLK &&
  229. clk_src != DSS_SRC_DSS1_ALWON_FCLK);
  230. b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1;
  231. if (clk_src == DSS_SRC_DSI2_PLL_FCLK)
  232. dsi_wait_dsi2_pll_active();
  233. REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */
  234. dss.dsi_clk_source = clk_src;
  235. }
  236. enum dss_clk_source dss_get_dispc_clk_source(void)
  237. {
  238. return dss.dispc_clk_source;
  239. }
  240. enum dss_clk_source dss_get_dsi_clk_source(void)
  241. {
  242. return dss.dsi_clk_source;
  243. }
  244. /* calculate clock rates using dividers in cinfo */
  245. int dss_calc_clock_rates(struct dss_clock_info *cinfo)
  246. {
  247. unsigned long prate;
  248. if (cinfo->fck_div > (cpu_is_omap3630() ? 32 : 16) ||
  249. cinfo->fck_div == 0)
  250. return -EINVAL;
  251. prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
  252. cinfo->fck = prate / cinfo->fck_div;
  253. return 0;
  254. }
  255. int dss_set_clock_div(struct dss_clock_info *cinfo)
  256. {
  257. unsigned long prate;
  258. int r;
  259. if (cpu_is_omap34xx()) {
  260. prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
  261. DSSDBG("dpll4_m4 = %ld\n", prate);
  262. r = clk_set_rate(dss.dpll4_m4_ck, prate / cinfo->fck_div);
  263. if (r)
  264. return r;
  265. }
  266. DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div);
  267. return 0;
  268. }
  269. int dss_get_clock_div(struct dss_clock_info *cinfo)
  270. {
  271. cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK);
  272. if (cpu_is_omap34xx()) {
  273. unsigned long prate;
  274. prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
  275. if (cpu_is_omap3630())
  276. cinfo->fck_div = prate / (cinfo->fck);
  277. else
  278. cinfo->fck_div = prate / (cinfo->fck / 2);
  279. } else {
  280. cinfo->fck_div = 0;
  281. }
  282. return 0;
  283. }
  284. unsigned long dss_get_dpll4_rate(void)
  285. {
  286. if (cpu_is_omap34xx())
  287. return clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
  288. else
  289. return 0;
  290. }
  291. int dss_calc_clock_div(bool is_tft, unsigned long req_pck,
  292. struct dss_clock_info *dss_cinfo,
  293. struct dispc_clock_info *dispc_cinfo)
  294. {
  295. unsigned long prate;
  296. struct dss_clock_info best_dss;
  297. struct dispc_clock_info best_dispc;
  298. unsigned long fck;
  299. u16 fck_div;
  300. int match = 0;
  301. int min_fck_per_pck;
  302. prate = dss_get_dpll4_rate();
  303. fck = dss_clk_get_rate(DSS_CLK_FCK);
  304. if (req_pck == dss.cache_req_pck &&
  305. ((cpu_is_omap34xx() && prate == dss.cache_prate) ||
  306. dss.cache_dss_cinfo.fck == fck)) {
  307. DSSDBG("dispc clock info found from cache.\n");
  308. *dss_cinfo = dss.cache_dss_cinfo;
  309. *dispc_cinfo = dss.cache_dispc_cinfo;
  310. return 0;
  311. }
  312. min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK;
  313. if (min_fck_per_pck &&
  314. req_pck * min_fck_per_pck > DISPC_MAX_FCK) {
  315. DSSERR("Requested pixel clock not possible with the current "
  316. "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning "
  317. "the constraint off.\n");
  318. min_fck_per_pck = 0;
  319. }
  320. retry:
  321. memset(&best_dss, 0, sizeof(best_dss));
  322. memset(&best_dispc, 0, sizeof(best_dispc));
  323. if (cpu_is_omap24xx()) {
  324. struct dispc_clock_info cur_dispc;
  325. /* XXX can we change the clock on omap2? */
  326. fck = dss_clk_get_rate(DSS_CLK_FCK);
  327. fck_div = 1;
  328. dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc);
  329. match = 1;
  330. best_dss.fck = fck;
  331. best_dss.fck_div = fck_div;
  332. best_dispc = cur_dispc;
  333. goto found;
  334. } else if (cpu_is_omap34xx()) {
  335. for (fck_div = (cpu_is_omap3630() ? 32 : 16);
  336. fck_div > 0; --fck_div) {
  337. struct dispc_clock_info cur_dispc;
  338. if (cpu_is_omap3630())
  339. fck = prate / fck_div;
  340. else
  341. fck = prate / fck_div * 2;
  342. if (fck > DISPC_MAX_FCK)
  343. continue;
  344. if (min_fck_per_pck &&
  345. fck < req_pck * min_fck_per_pck)
  346. continue;
  347. match = 1;
  348. dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc);
  349. if (abs(cur_dispc.pck - req_pck) <
  350. abs(best_dispc.pck - req_pck)) {
  351. best_dss.fck = fck;
  352. best_dss.fck_div = fck_div;
  353. best_dispc = cur_dispc;
  354. if (cur_dispc.pck == req_pck)
  355. goto found;
  356. }
  357. }
  358. } else {
  359. BUG();
  360. }
  361. found:
  362. if (!match) {
  363. if (min_fck_per_pck) {
  364. DSSERR("Could not find suitable clock settings.\n"
  365. "Turning FCK/PCK constraint off and"
  366. "trying again.\n");
  367. min_fck_per_pck = 0;
  368. goto retry;
  369. }
  370. DSSERR("Could not find suitable clock settings.\n");
  371. return -EINVAL;
  372. }
  373. if (dss_cinfo)
  374. *dss_cinfo = best_dss;
  375. if (dispc_cinfo)
  376. *dispc_cinfo = best_dispc;
  377. dss.cache_req_pck = req_pck;
  378. dss.cache_prate = prate;
  379. dss.cache_dss_cinfo = best_dss;
  380. dss.cache_dispc_cinfo = best_dispc;
  381. return 0;
  382. }
  383. static irqreturn_t dss_irq_handler_omap2(int irq, void *arg)
  384. {
  385. dispc_irq_handler();
  386. return IRQ_HANDLED;
  387. }
  388. static irqreturn_t dss_irq_handler_omap3(int irq, void *arg)
  389. {
  390. u32 irqstatus;
  391. irqstatus = dss_read_reg(DSS_IRQSTATUS);
  392. if (irqstatus & (1<<0)) /* DISPC_IRQ */
  393. dispc_irq_handler();
  394. #ifdef CONFIG_OMAP2_DSS_DSI
  395. if (irqstatus & (1<<1)) /* DSI_IRQ */
  396. dsi_irq_handler();
  397. #endif
  398. return IRQ_HANDLED;
  399. }
  400. static int _omap_dss_wait_reset(void)
  401. {
  402. int t = 0;
  403. while (REG_GET(DSS_SYSSTATUS, 0, 0) == 0) {
  404. if (++t > 1000) {
  405. DSSERR("soft reset failed\n");
  406. return -ENODEV;
  407. }
  408. udelay(1);
  409. }
  410. return 0;
  411. }
  412. static int _omap_dss_reset(void)
  413. {
  414. /* Soft reset */
  415. REG_FLD_MOD(DSS_SYSCONFIG, 1, 1, 1);
  416. return _omap_dss_wait_reset();
  417. }
  418. void dss_set_venc_output(enum omap_dss_venc_type type)
  419. {
  420. int l = 0;
  421. if (type == OMAP_DSS_VENC_TYPE_COMPOSITE)
  422. l = 0;
  423. else if (type == OMAP_DSS_VENC_TYPE_SVIDEO)
  424. l = 1;
  425. else
  426. BUG();
  427. /* venc out selection. 0 = comp, 1 = svideo */
  428. REG_FLD_MOD(DSS_CONTROL, l, 6, 6);
  429. }
  430. void dss_set_dac_pwrdn_bgz(bool enable)
  431. {
  432. REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */
  433. }
  434. static int dss_init(bool skip_init)
  435. {
  436. int r;
  437. u32 rev;
  438. struct resource *dss_mem;
  439. dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
  440. if (!dss_mem) {
  441. DSSERR("can't get IORESOURCE_MEM DSS\n");
  442. r = -EINVAL;
  443. goto fail0;
  444. }
  445. dss.base = ioremap(dss_mem->start, resource_size(dss_mem));
  446. if (!dss.base) {
  447. DSSERR("can't ioremap DSS\n");
  448. r = -ENOMEM;
  449. goto fail0;
  450. }
  451. if (!skip_init) {
  452. /* disable LCD and DIGIT output. This seems to fix the synclost
  453. * problem that we get, if the bootloader starts the DSS and
  454. * the kernel resets it */
  455. omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440);
  456. /* We need to wait here a bit, otherwise we sometimes start to
  457. * get synclost errors, and after that only power cycle will
  458. * restore DSS functionality. I have no idea why this happens.
  459. * And we have to wait _before_ resetting the DSS, but after
  460. * enabling clocks.
  461. */
  462. msleep(50);
  463. _omap_dss_reset();
  464. }
  465. /* autoidle */
  466. REG_FLD_MOD(DSS_SYSCONFIG, 1, 0, 0);
  467. /* Select DPLL */
  468. REG_FLD_MOD(DSS_CONTROL, 0, 0, 0);
  469. #ifdef CONFIG_OMAP2_DSS_VENC
  470. REG_FLD_MOD(DSS_CONTROL, 1, 4, 4); /* venc dac demen */
  471. REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */
  472. REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */
  473. #endif
  474. dss.dss_irq = platform_get_irq(dss.pdev, 0);
  475. if (dss.dss_irq < 0) {
  476. DSSERR("omap2 dss: platform_get_irq failed\n");
  477. r = -ENODEV;
  478. goto fail1;
  479. }
  480. r = request_irq(dss.dss_irq,
  481. cpu_is_omap24xx()
  482. ? dss_irq_handler_omap2
  483. : dss_irq_handler_omap3,
  484. 0, "OMAP DSS", NULL);
  485. if (r < 0) {
  486. DSSERR("omap2 dss: request_irq failed\n");
  487. goto fail1;
  488. }
  489. if (cpu_is_omap34xx()) {
  490. dss.dpll4_m4_ck = clk_get(NULL, "dpll4_m4_ck");
  491. if (IS_ERR(dss.dpll4_m4_ck)) {
  492. DSSERR("Failed to get dpll4_m4_ck\n");
  493. r = PTR_ERR(dss.dpll4_m4_ck);
  494. goto fail2;
  495. }
  496. }
  497. dss.dsi_clk_source = DSS_SRC_DSS1_ALWON_FCLK;
  498. dss.dispc_clk_source = DSS_SRC_DSS1_ALWON_FCLK;
  499. dss_save_context();
  500. rev = dss_read_reg(DSS_REVISION);
  501. printk(KERN_INFO "OMAP DSS rev %d.%d\n",
  502. FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
  503. return 0;
  504. fail2:
  505. free_irq(dss.dss_irq, NULL);
  506. fail1:
  507. iounmap(dss.base);
  508. fail0:
  509. return r;
  510. }
  511. static void dss_exit(void)
  512. {
  513. if (cpu_is_omap34xx())
  514. clk_put(dss.dpll4_m4_ck);
  515. free_irq(dss.dss_irq, NULL);
  516. iounmap(dss.base);
  517. }
  518. /* CONTEXT */
  519. static int dss_get_ctx_id(void)
  520. {
  521. struct omap_display_platform_data *pdata = dss.pdev->dev.platform_data;
  522. int r;
  523. if (!pdata->board_data->get_last_off_on_transaction_id)
  524. return 0;
  525. r = pdata->board_data->get_last_off_on_transaction_id(&dss.pdev->dev);
  526. if (r < 0) {
  527. dev_err(&dss.pdev->dev, "getting transaction ID failed, "
  528. "will force context restore\n");
  529. r = -1;
  530. }
  531. return r;
  532. }
  533. int dss_need_ctx_restore(void)
  534. {
  535. int id = dss_get_ctx_id();
  536. if (id < 0 || id != dss.ctx_id) {
  537. DSSDBG("ctx id %d -> id %d\n",
  538. dss.ctx_id, id);
  539. dss.ctx_id = id;
  540. return 1;
  541. } else {
  542. return 0;
  543. }
  544. }
  545. static void save_all_ctx(void)
  546. {
  547. DSSDBG("save context\n");
  548. dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK);
  549. dss_save_context();
  550. dispc_save_context();
  551. #ifdef CONFIG_OMAP2_DSS_DSI
  552. dsi_save_context();
  553. #endif
  554. dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK);
  555. }
  556. static void restore_all_ctx(void)
  557. {
  558. DSSDBG("restore context\n");
  559. dss_clk_enable_all_no_ctx();
  560. dss_restore_context();
  561. dispc_restore_context();
  562. #ifdef CONFIG_OMAP2_DSS_DSI
  563. dsi_restore_context();
  564. #endif
  565. dss_clk_disable_all_no_ctx();
  566. }
  567. static int dss_get_clock(struct clk **clock, const char *clk_name)
  568. {
  569. struct clk *clk;
  570. clk = clk_get(&dss.pdev->dev, clk_name);
  571. if (IS_ERR(clk)) {
  572. DSSERR("can't get clock %s", clk_name);
  573. return PTR_ERR(clk);
  574. }
  575. *clock = clk;
  576. DSSDBG("clk %s, rate %ld\n", clk_name, clk_get_rate(clk));
  577. return 0;
  578. }
  579. static int dss_get_clocks(void)
  580. {
  581. int r;
  582. dss.dss_ick = NULL;
  583. dss.dss1_fck = NULL;
  584. dss.dss2_fck = NULL;
  585. dss.dss_54m_fck = NULL;
  586. dss.dss_96m_fck = NULL;
  587. r = dss_get_clock(&dss.dss_ick, "ick");
  588. if (r)
  589. goto err;
  590. r = dss_get_clock(&dss.dss1_fck, "fck");
  591. if (r)
  592. goto err;
  593. r = dss_get_clock(&dss.dss2_fck, "sys_clk");
  594. if (r)
  595. goto err;
  596. r = dss_get_clock(&dss.dss_54m_fck, "tv_clk");
  597. if (r)
  598. goto err;
  599. r = dss_get_clock(&dss.dss_96m_fck, "video_clk");
  600. if (r)
  601. goto err;
  602. return 0;
  603. err:
  604. if (dss.dss_ick)
  605. clk_put(dss.dss_ick);
  606. if (dss.dss1_fck)
  607. clk_put(dss.dss1_fck);
  608. if (dss.dss2_fck)
  609. clk_put(dss.dss2_fck);
  610. if (dss.dss_54m_fck)
  611. clk_put(dss.dss_54m_fck);
  612. if (dss.dss_96m_fck)
  613. clk_put(dss.dss_96m_fck);
  614. return r;
  615. }
  616. static void dss_put_clocks(void)
  617. {
  618. if (dss.dss_96m_fck)
  619. clk_put(dss.dss_96m_fck);
  620. clk_put(dss.dss_54m_fck);
  621. clk_put(dss.dss1_fck);
  622. clk_put(dss.dss2_fck);
  623. clk_put(dss.dss_ick);
  624. }
  625. unsigned long dss_clk_get_rate(enum dss_clock clk)
  626. {
  627. switch (clk) {
  628. case DSS_CLK_ICK:
  629. return clk_get_rate(dss.dss_ick);
  630. case DSS_CLK_FCK:
  631. return clk_get_rate(dss.dss1_fck);
  632. case DSS_CLK_SYSCK:
  633. return clk_get_rate(dss.dss2_fck);
  634. case DSS_CLK_TVFCK:
  635. return clk_get_rate(dss.dss_54m_fck);
  636. case DSS_CLK_VIDFCK:
  637. return clk_get_rate(dss.dss_96m_fck);
  638. }
  639. BUG();
  640. return 0;
  641. }
  642. static unsigned count_clk_bits(enum dss_clock clks)
  643. {
  644. unsigned num_clks = 0;
  645. if (clks & DSS_CLK_ICK)
  646. ++num_clks;
  647. if (clks & DSS_CLK_FCK)
  648. ++num_clks;
  649. if (clks & DSS_CLK_SYSCK)
  650. ++num_clks;
  651. if (clks & DSS_CLK_TVFCK)
  652. ++num_clks;
  653. if (clks & DSS_CLK_VIDFCK)
  654. ++num_clks;
  655. return num_clks;
  656. }
  657. static void dss_clk_enable_no_ctx(enum dss_clock clks)
  658. {
  659. unsigned num_clks = count_clk_bits(clks);
  660. if (clks & DSS_CLK_ICK)
  661. clk_enable(dss.dss_ick);
  662. if (clks & DSS_CLK_FCK)
  663. clk_enable(dss.dss1_fck);
  664. if (clks & DSS_CLK_SYSCK)
  665. clk_enable(dss.dss2_fck);
  666. if (clks & DSS_CLK_TVFCK)
  667. clk_enable(dss.dss_54m_fck);
  668. if (clks & DSS_CLK_VIDFCK)
  669. clk_enable(dss.dss_96m_fck);
  670. dss.num_clks_enabled += num_clks;
  671. }
  672. void dss_clk_enable(enum dss_clock clks)
  673. {
  674. bool check_ctx = dss.num_clks_enabled == 0;
  675. dss_clk_enable_no_ctx(clks);
  676. if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore())
  677. restore_all_ctx();
  678. }
  679. static void dss_clk_disable_no_ctx(enum dss_clock clks)
  680. {
  681. unsigned num_clks = count_clk_bits(clks);
  682. if (clks & DSS_CLK_ICK)
  683. clk_disable(dss.dss_ick);
  684. if (clks & DSS_CLK_FCK)
  685. clk_disable(dss.dss1_fck);
  686. if (clks & DSS_CLK_SYSCK)
  687. clk_disable(dss.dss2_fck);
  688. if (clks & DSS_CLK_TVFCK)
  689. clk_disable(dss.dss_54m_fck);
  690. if (clks & DSS_CLK_VIDFCK)
  691. clk_disable(dss.dss_96m_fck);
  692. dss.num_clks_enabled -= num_clks;
  693. }
  694. void dss_clk_disable(enum dss_clock clks)
  695. {
  696. if (cpu_is_omap34xx()) {
  697. unsigned num_clks = count_clk_bits(clks);
  698. BUG_ON(dss.num_clks_enabled < num_clks);
  699. if (dss.num_clks_enabled == num_clks)
  700. save_all_ctx();
  701. }
  702. dss_clk_disable_no_ctx(clks);
  703. }
  704. static void dss_clk_enable_all_no_ctx(void)
  705. {
  706. enum dss_clock clks;
  707. clks = DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_SYSCK | DSS_CLK_TVFCK;
  708. if (cpu_is_omap34xx())
  709. clks |= DSS_CLK_VIDFCK;
  710. dss_clk_enable_no_ctx(clks);
  711. }
  712. static void dss_clk_disable_all_no_ctx(void)
  713. {
  714. enum dss_clock clks;
  715. clks = DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_SYSCK | DSS_CLK_TVFCK;
  716. if (cpu_is_omap34xx())
  717. clks |= DSS_CLK_VIDFCK;
  718. dss_clk_disable_no_ctx(clks);
  719. }
  720. #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
  721. /* CLOCKS */
  722. static void core_dump_clocks(struct seq_file *s)
  723. {
  724. int i;
  725. struct clk *clocks[5] = {
  726. dss.dss_ick,
  727. dss.dss1_fck,
  728. dss.dss2_fck,
  729. dss.dss_54m_fck,
  730. dss.dss_96m_fck
  731. };
  732. seq_printf(s, "- CORE -\n");
  733. seq_printf(s, "internal clk count\t\t%u\n", dss.num_clks_enabled);
  734. for (i = 0; i < 5; i++) {
  735. if (!clocks[i])
  736. continue;
  737. seq_printf(s, "%-15s\t%lu\t%d\n",
  738. clocks[i]->name,
  739. clk_get_rate(clocks[i]),
  740. clocks[i]->usecount);
  741. }
  742. }
  743. #endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */
  744. /* DEBUGFS */
  745. #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
  746. void dss_debug_dump_clocks(struct seq_file *s)
  747. {
  748. core_dump_clocks(s);
  749. dss_dump_clocks(s);
  750. dispc_dump_clocks(s);
  751. #ifdef CONFIG_OMAP2_DSS_DSI
  752. dsi_dump_clocks(s);
  753. #endif
  754. }
  755. #endif
  756. /* DSS HW IP initialisation */
  757. static int omap_dsshw_probe(struct platform_device *pdev)
  758. {
  759. int r;
  760. int skip_init = 0;
  761. dss.pdev = pdev;
  762. r = dss_get_clocks();
  763. if (r)
  764. goto err_clocks;
  765. dss_clk_enable_all_no_ctx();
  766. dss.ctx_id = dss_get_ctx_id();
  767. DSSDBG("initial ctx id %u\n", dss.ctx_id);
  768. #ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT
  769. /* DISPC_CONTROL */
  770. if (omap_readl(0x48050440) & 1) /* LCD enabled? */
  771. skip_init = 1;
  772. #endif
  773. r = dss_init(skip_init);
  774. if (r) {
  775. DSSERR("Failed to initialize DSS\n");
  776. goto err_dss;
  777. }
  778. dss_clk_disable_all_no_ctx();
  779. return 0;
  780. err_dss:
  781. dss_clk_disable_all_no_ctx();
  782. dss_put_clocks();
  783. err_clocks:
  784. return r;
  785. }
  786. static int omap_dsshw_remove(struct platform_device *pdev)
  787. {
  788. dss_exit();
  789. /*
  790. * As part of hwmod changes, DSS is not the only controller of dss
  791. * clocks; hwmod framework itself will also enable clocks during hwmod
  792. * init for dss, and autoidle is set in h/w for DSS. Hence, there's no
  793. * need to disable clocks if their usecounts > 1.
  794. */
  795. WARN_ON(dss.num_clks_enabled > 0);
  796. dss_put_clocks();
  797. return 0;
  798. }
  799. static struct platform_driver omap_dsshw_driver = {
  800. .probe = omap_dsshw_probe,
  801. .remove = omap_dsshw_remove,
  802. .driver = {
  803. .name = "omapdss_dss",
  804. .owner = THIS_MODULE,
  805. },
  806. };
  807. int dss_init_platform_driver(void)
  808. {
  809. return platform_driver_register(&omap_dsshw_driver);
  810. }
  811. void dss_uninit_platform_driver(void)
  812. {
  813. return platform_driver_unregister(&omap_dsshw_driver);
  814. }