driver_framebuffer.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  1. // (C) 2024 Victor Suarez Rovere <suarezvictor@gmail.com>
  2. // SPDX-License-Identifier: AGPL-3.0-only
  3. #include <stdio.h>
  4. #include "ioregs.h"
  5. #include "sys.h"
  6. void dump_reg(uintptr_t addr)
  7. {
  8. //printf("REGISTER at 0x%x: 0x%x\r\n", addr, io_read32(addr));
  9. }
  10. void fb_probe(void)
  11. {
  12. /*
  13. #define CCU_pll_video0_ctrl (CCU + 0x40) // PLL_VIDEO0 Control Register ()
  14. #define CCU_pll_video0_ctrl_OFFSET 0x40
  15. #define CCU_pll_video0_ctrl_pll_en (0x1 << 31)
  16. #define CCU_pll_video0_ctrl_pll_en_SHIFT 31
  17. #define CCU_pll_video0_ctrl_pll_ldo_en (0x1 << 30)
  18. #define CCU_pll_video0_ctrl_pll_ldo_en_SHIFT 30
  19. #define CCU_pll_video0_ctrl_lock_enable (0x1 << 29)
  20. #define CCU_pll_video0_ctrl_lock_enable_SHIFT 29
  21. #define CCU_pll_video0_ctrl_lock (0x1 << 28)
  22. #define CCU_pll_video0_ctrl_lock_SHIFT 28
  23. #define CCU_pll_video0_ctrl_pll_output_gate (0x1 << 27)
  24. #define CCU_pll_video0_ctrl_pll_output_gate_SHIFT 27
  25. #define CCU_pll_video0_ctrl_pll_sdm_en (0x1 << 24)
  26. #define CCU_pll_video0_ctrl_pll_sdm_en_SHIFT 24
  27. #define CCU_pll_video0_ctrl_pll_n (0xff << 8)
  28. #define CCU_pll_video0_ctrl_pll_n_SHIFT 8
  29. #define CCU_pll_video0_ctrl_pll_unlock_mdsel (0x3 << 6)
  30. #define CCU_pll_video0_ctrl_pll_unlock_mdsel_SHIFT 6
  31. #define CCU_pll_video0_ctrl_pll_lock_mdsel (0x1 << 5)
  32. #define CCU_pll_video0_ctrl_pll_lock_mdsel_SHIFT 5
  33. #define CCU_pll_video0_ctrl_pll_input_div2 (0x1 << 1)
  34. #define CCU_pll_video0_ctrl_pll_input_div2_SHIFT 1
  35. #define CCU_pll_video0_ctrl_pll_output_div2 0x1
  36. #define CCU_pll_video0_ctrl_pll_output_div2_SHIFT 0
  37. // Enable PLL_VIDEO0. Fin=24M N=27 M=2 Fout(4X)=324M
  38. // Aiming to exceed the 297MHz requirement for DE while being
  39. // a multiply of 9MHz to generate 9M pixel clock.
  40. // Though maybe DE needs to be exactly 297, or less than 297...
  41. ccu.pll_video0_ctrl.write(|w| unsafe {
  42. w.pll_output_div2().clear_bit()
  43. .pll_input_div2().set_bit()
  44. .pll_n().bits(27 - 1)
  45. .pll_output_gate().clear_bit()
  46. .lock_enable().clear_bit()
  47. .pll_ldo_en().set_bit()
  48. .pll_en().set_bit()
  49. });
  50. */
  51. io_write32(CCU_pll_video0_ctrl, 0
  52. | (0 << CCU_pll_video0_ctrl_pll_output_div2_SHIFT)
  53. | (1 << CCU_pll_video0_ctrl_pll_input_div2_SHIFT)
  54. | ((27-1) << CCU_pll_video0_ctrl_pll_n_SHIFT)
  55. | (0 << CCU_pll_video0_ctrl_pll_output_gate_SHIFT)
  56. | (0 << CCU_pll_video0_ctrl_lock_enable_SHIFT)
  57. | (1 << CCU_pll_video0_ctrl_pll_ldo_en_SHIFT)
  58. | (1 << CCU_pll_video0_ctrl_pll_en_SHIFT)
  59. );
  60. dump_reg(CCU_pll_video0_ctrl); //0xC0001A02
  61. /*
  62. ccu.pll_video0_ctrl.modify(|_, w| w.lock_enable().set_bit());
  63. while ccu.pll_video0_ctrl.read().lock().is_unlocked() {}
  64. unsafe { riscv::asm::delay(20_000) };
  65. */
  66. io_write32(CCU_pll_video0_ctrl, io_read32(CCU_pll_video0_ctrl) | CCU_pll_video0_ctrl_lock_enable);
  67. dump_reg(CCU_pll_video0_ctrl);
  68. while(!(io_read32(CCU_pll_video0_ctrl) & CCU_pll_video0_ctrl_lock));
  69. delay_us(20);
  70. dump_reg(CCU_pll_video0_ctrl);
  71. /*
  72. ccu.pll_video0_ctrl.modify(|_, w| w.pll_output_gate().set_bit());
  73. */
  74. io_write32(CCU_pll_video0_ctrl, io_read32(CCU_pll_video0_ctrl) | CCU_pll_video0_ctrl_pll_output_gate);
  75. dump_reg(CCU_pll_video0_ctrl); //OK: REGISTER at 0x02001040: 0xF8001A02
  76. /*
  77. #define CCU_tconlcd_clk (CCU + 0xb60) // TCONLCD Clock Register ()
  78. #define CCU_tconlcd_clk_OFFSET 0xb60
  79. #define CCU_tconlcd_clk_clk_gating (0x1 << 31)
  80. #define CCU_tconlcd_clk_clk_gating_SHIFT 31
  81. #define CCU_tconlcd_clk_clk_src_sel (0x7 << 24)
  82. #define CCU_tconlcd_clk_clk_src_sel_SHIFT 24
  83. #define CCU_tconlcd_clk_factor_n (0x3 << 8)
  84. #define CCU_tconlcd_clk_factor_n_SHIFT 8
  85. #define CCU_tconlcd_clk_factor_m 0xf
  86. #define CCU_tconlcd_clk_factor_m_SHIFT 0
  87. // Set TCON_LCD to PLL_VIDEO0(4X) and enable.
  88. ccu.tconlcd_clk.write(|w| unsafe {
  89. w.clk_gating().on()
  90. .clk_src_sel().pll_video0_4x()
  91. .factor_n().n1()
  92. .factor_m().bits(0)
  93. });
  94. "clk-mux@0x02001b60": {
  95. "parent": [
  96. { "name": "pll-video0", "value": 0 },
  97. { "name": "pll-video0-4x", "value": 1 },
  98. { "name": "pll-video1", "value": 2 },
  99. { "name": "pll-video1-4x", "value": 3 },
  100. { "name": "pll-periph0-2x", "value": 4 },
  101. { "name": "pll-audio1-div2", "value": 5 }
  102. ],
  103. "name": "mux-tconlcd", "shift": 24, "width": 3,
  104. "default": { "parent": "pll-video0-4x" }
  105. },
  106. */
  107. const int CCU_tconlcd_clk_select_pll_video0_4x = 1;
  108. io_write32(CCU_tconlcd_clk, 0
  109. | CCU_tconlcd_clk_clk_gating
  110. | (CCU_tconlcd_clk_select_pll_video0_4x << CCU_tconlcd_clk_clk_src_sel_SHIFT)
  111. | ((1-1) << CCU_tconlcd_clk_factor_n_SHIFT)
  112. | (0 << CCU_tconlcd_clk_factor_m_SHIFT)
  113. );
  114. dump_reg(CCU_tconlcd_clk); //REGISTER at 0x02001B60: 0x81000000
  115. /*
  116. #define CCU_tconlcd_bgr (CCU + 0xb7c) // TCONLCD Bus Gating Reset Register ()
  117. #define CCU_tconlcd_bgr_OFFSET 0xb7c
  118. #define CCU_tconlcd_bgr_rst (0x1 << 16)
  119. #define CCU_tconlcd_bgr_rst_SHIFT 16
  120. #define CCU_tconlcd_bgr_gating 0x1
  121. #define CCU_tconlcd_bgr_gating_SHIFT 0
  122. ccu.tconlcd_bgr.write(|w| w.rst().deassert().gating().pass());
  123. */
  124. io_write32(CCU_tconlcd_bgr, CCU_tconlcd_bgr_rst | CCU_tconlcd_bgr_gating);
  125. dump_reg(CCU_tconlcd_bgr);
  126. /*
  127. #define CCU_de_clk (CCU + 0x600) // DE Clock Register ()
  128. #define CCU_de_clk_OFFSET 0x600
  129. #define CCU_de_clk_clk_gating (0x1 << 31)
  130. #define CCU_de_clk_clk_gating_SHIFT 31
  131. #define CCU_de_clk_clk_src_sel (0x7 << 24)
  132. #define CCU_de_clk_clk_src_sel_SHIFT 24
  133. #define CCU_de_clk_factor_m 0x1f
  134. #define CCU_de_clk_factor_m_SHIFT 0
  135. // Enable Display Engine clock with VIDEO0(4X)=324MHz and bring out of reset.
  136. // FACTOR_M=0 for M=1 for DE_CLK=CLK_SRC/1.
  137. ccu.de_clk.write(|w| w.clk_gating().on().clk_src_sel().pll_video0_4x());
  138. "clk-mux@0x02001600": {
  139. "parent": [
  140. { "name": "pll-periph0-2x", "value": 0 },
  141. { "name": "pll-video0-4x", "value": 1 },
  142. { "name": "pll-video1-4x", "value": 2 },
  143. { "name": "pll-audio1-div2", "value": 3 }
  144. ],
  145. */
  146. const int CCU_de_clk_select_pll_video0_4x = 1;
  147. io_write32(CCU_de_clk, CCU_de_clk_clk_gating | (CCU_de_clk_select_pll_video0_4x << CCU_de_clk_clk_src_sel_SHIFT));
  148. dump_reg(CCU_de_clk);
  149. /*
  150. #define CCU_de_bgr (CCU + 0x60c) // DE Bus Gating Reset Register ()
  151. #define CCU_de_bgr_OFFSET 0x60c
  152. #define CCU_de_bgr_rst (0x1 << 16)
  153. #define CCU_de_bgr_rst_SHIFT 16
  154. #define CCU_de_bgr_gating 0x1
  155. #define CCU_de_bgr_gating_SHIFT 0
  156. ccu.de_bgr.write(|w| w.rst().deassert().gating().pass());
  157. */
  158. io_write32(CCU_de_bgr, CCU_de_bgr_rst | CCU_de_bgr_gating);
  159. dump_reg(CCU_de_bgr);
  160. /*
  161. #define GPIO_pd_cfg0 (GPIO + 0x90) // PD Configure Register 0 ()
  162. #define GPIO_pd_cfg0_OFFSET 0x90
  163. #define GPIO_pd_cfg0_pd7_select (0xf << 28)
  164. #define GPIO_pd_cfg0_pd7_select_SHIFT 28
  165. #define GPIO_pd_cfg0_pd6_select (0xf << 24)
  166. #define GPIO_pd_cfg0_pd6_select_SHIFT 24
  167. #define GPIO_pd_cfg0_pd5_select (0xf << 20)
  168. #define GPIO_pd_cfg0_pd5_select_SHIFT 20
  169. #define GPIO_pd_cfg0_pd4_select (0xf << 16)
  170. #define GPIO_pd_cfg0_pd4_select_SHIFT 16
  171. #define GPIO_pd_cfg0_pd3_select (0xf << 12)
  172. #define GPIO_pd_cfg0_pd3_select_SHIFT 12
  173. #define GPIO_pd_cfg0_pd2_select (0xf << 8)
  174. #define GPIO_pd_cfg0_pd2_select_SHIFT 8
  175. #define GPIO_pd_cfg0_pd1_select (0xf << 4)
  176. #define GPIO_pd_cfg0_pd1_select_SHIFT 4
  177. #define GPIO_pd_cfg0_pd0_select 0xf
  178. #define GPIO_pd_cfg0_pd0_select_SHIFT 0
  179. // Set PD0-21 to LCD functions, and PD22 (LCD backlight PWM) to output.
  180. gpio.pd_cfg0.write(|w|
  181. w.pd0_select().lcd0_d2()
  182. .pd1_select().lcd0_d3()
  183. .pd2_select().lcd0_d4()
  184. .pd3_select().lcd0_d5()
  185. .pd4_select().lcd0_d6()
  186. .pd5_select().lcd0_d7()
  187. .pd6_select().lcd0_d10()
  188. .pd7_select().lcd0_d11());
  189. gpio.pd_cfg1.write(|w|
  190. w.pd8_select().lcd0_d12()
  191. .pd9_select().lcd0_d13()
  192. .pd10_select().lcd0_d14()
  193. .pd11_select().lcd0_d15()
  194. .pd12_select().lcd0_d18()
  195. .pd13_select().lcd0_d19()
  196. .pd14_select().lcd0_d20()
  197. .pd15_select().lcd0_d21());
  198. gpio.pd_cfg2.write(|w|
  199. w.pd16_select().lcd0_d22()
  200. .pd17_select().lcd0_d23()
  201. .pd18_select().lcd0_clk()
  202. .pd19_select().lcd0_de()
  203. .pd20_select().lcd0_hsync()
  204. .pd21_select().lcd0_vsync()
  205. .pd22_select().output());
  206. */
  207. io_write32(GPIO_pd_cfg0, 0
  208. | (2 << GPIO_pd_cfg0_pd0_select_SHIFT) //d2
  209. | (2 << GPIO_pd_cfg0_pd1_select_SHIFT) //d3
  210. | (2 << GPIO_pd_cfg0_pd2_select_SHIFT) //d4
  211. | (2 << GPIO_pd_cfg0_pd3_select_SHIFT) //d5
  212. | (2 << GPIO_pd_cfg0_pd4_select_SHIFT) //d6
  213. | (2 << GPIO_pd_cfg0_pd5_select_SHIFT) //d7
  214. | (2 << GPIO_pd_cfg0_pd6_select_SHIFT) //d10
  215. | (2 << GPIO_pd_cfg0_pd7_select_SHIFT) //d11
  216. );
  217. dump_reg(GPIO_pd_cfg0);
  218. io_write32(GPIO_pd_cfg1, 0
  219. | (2 << GPIO_pd_cfg1_pd8_select_SHIFT) //d12
  220. | (2 << GPIO_pd_cfg1_pd9_select_SHIFT) //d13
  221. | (2 << GPIO_pd_cfg1_pd10_select_SHIFT) //d14
  222. | (2 << GPIO_pd_cfg1_pd11_select_SHIFT) //d15
  223. | (2 << GPIO_pd_cfg1_pd12_select_SHIFT) //d18
  224. | (2 << GPIO_pd_cfg1_pd13_select_SHIFT) //d19
  225. | (2 << GPIO_pd_cfg1_pd14_select_SHIFT) //d20
  226. | (2 << GPIO_pd_cfg1_pd15_select_SHIFT) //d21
  227. );
  228. dump_reg(GPIO_pd_cfg1);
  229. io_write32(GPIO_pd_cfg2, 0
  230. | (2 << GPIO_pd_cfg2_pd16_select_SHIFT) //d22
  231. | (2 << GPIO_pd_cfg2_pd17_select_SHIFT) //d23
  232. | (2 << GPIO_pd_cfg2_pd18_select_SHIFT) //clk
  233. | (2 << GPIO_pd_cfg2_pd19_select_SHIFT) //de
  234. | (2 << GPIO_pd_cfg2_pd20_select_SHIFT) //hsync
  235. | (2 << GPIO_pd_cfg2_pd21_select_SHIFT) //vsync
  236. | (1 << GPIO_pd_cfg2_pd22_select_SHIFT) //OUTPUT (PWM / led)
  237. );
  238. dump_reg(GPIO_pd_cfg2);
  239. /*
  240. // Turn on LCD backlight (PWM can come later).
  241. gpio.pd_dat.write(|w| unsafe { w.bits(1<<22) });
  242. dump_reg(&gpio.pd_dat);
  243. */
  244. io_write32(GPIO_pd_dat, 1<<22);
  245. dump_reg(GPIO_pd_dat);
  246. /*
  247. #define TCON_LCD0 0x05461000
  248. #define TCON_LCD0_lcd_gctl (TCON_LCD0 + 0x0) // LCD Global Control Register ()
  249. #define TCON_LCD0_lcd_gctl_OFFSET 0x0
  250. #define TCON_LCD0_lcd_gctl_lcd_en (0x1 << 31)
  251. #define TCON_LCD0_lcd_gctl_lcd_en_SHIFT 31
  252. #define TCON_LCD0_lcd_gctl_lcd_gamma_en (0x1 << 30)
  253. #define TCON_LCD0_lcd_gctl_lcd_gamma_en_SHIFT 30
  254. // Configure TCON for RGB operation:
  255. // TCON_EN / LCD_EN
  256. lcd0.lcd_gctl_reg.write(|w| unsafe { w.bits(1 << 31) });
  257. */
  258. io_write32(TCON_LCD0_lcd_gctl, TCON_LCD0_lcd_gctl_lcd_en);
  259. dump_reg(TCON_LCD0_lcd_gctl);
  260. /*
  261. #define TCON_LCD0_lcd_ctl (TCON_LCD0 + 0x40) // LCD Control Register ()
  262. #define TCON_LCD0_lcd_ctl_OFFSET 0x40
  263. #define TCON_LCD0_lcd_ctl_lcd_en (0x1 << 31)
  264. #define TCON_LCD0_lcd_ctl_lcd_en_SHIFT 31
  265. #define TCON_LCD0_lcd_ctl_lcd_if (0x3 << 24)
  266. #define TCON_LCD0_lcd_ctl_lcd_if_SHIFT 24
  267. #define TCON_LCD0_lcd_ctl_lcd_rb_swap (0x1 << 23)
  268. #define TCON_LCD0_lcd_ctl_lcd_rb_swap_SHIFT 23
  269. #define TCON_LCD0_lcd_ctl_lcd_fifo1_rst (0x1 << 21)
  270. #define TCON_LCD0_lcd_ctl_lcd_fifo1_rst_SHIFT 21
  271. #define TCON_LCD0_lcd_ctl_lcd_interlace_en (0x1 << 20)
  272. #define TCON_LCD0_lcd_ctl_lcd_interlace_en_SHIFT 20
  273. #define TCON_LCD0_lcd_ctl_lcd_start_dly (0x1f << 4)
  274. #define TCON_LCD0_lcd_ctl_lcd_start_dly_SHIFT 4
  275. #define TCON_LCD0_lcd_ctl_lcd_src_sel 0x7
  276. #define TCON_LCD0_lcd_ctl_lcd_src_sel_SHIFT 0
  277. // Configure TCON_LCD in RGB666 mode for our 480x272 LCD.
  278. lcd0.lcd_ctl_reg.write(|w| unsafe { w.bits(
  279. // LCD_CTL_REG.LCD_EN=0 to disable
  280. (0 << 31)
  281. // LCD_CTL_REG.LCD_IF=0 for HV(Sync+DE)
  282. | (0 << 24)
  283. // Delay is VT-VD=292-272=20 (max 30)
  284. | (22 << 4) //VFP+VBP+sync (((33+10+2)/2)0x1f)
  285. // LCD_CTL_REG.LCD_SRC_SEL=000 for Display Engine source.
  286. // Try 0b001 for color check or 0b111 for grid check.
  287. | (0b000 << 0)
  288. )});
  289. */
  290. io_write32(TCON_LCD0_lcd_ctl, 0
  291. | (0 << TCON_LCD0_lcd_ctl_lcd_en_SHIFT)
  292. | (0 << TCON_LCD0_lcd_ctl_lcd_if_SHIFT)
  293. | (22 << TCON_LCD0_lcd_ctl_lcd_start_dly_SHIFT)
  294. | 0b000 //0b111
  295. );
  296. dump_reg(TCON_LCD0_lcd_ctl);
  297. /*
  298. #define TCON_LCD0_lcd_hv_if (TCON_LCD0 + 0x58) // LCD HV Panel Interface Register ()
  299. #define TCON_LCD0_lcd_hv_if_OFFSET 0x58
  300. #define TCON_LCD0_lcd_hv_if_hv_mode (0xf << 28)
  301. #define TCON_LCD0_lcd_hv_if_hv_mode_SHIFT 28
  302. #define TCON_LCD0_lcd_hv_if_rgb888_odd_order (0x3 << 26)
  303. #define TCON_LCD0_lcd_hv_if_rgb888_odd_order_SHIFT 26
  304. #define TCON_LCD0_lcd_hv_if_rgb888_even_order (0x3 << 24)
  305. #define TCON_LCD0_lcd_hv_if_rgb888_even_order_SHIFT 24
  306. #define TCON_LCD0_lcd_hv_if_yuv_sm (0x3 << 22)
  307. #define TCON_LCD0_lcd_hv_if_yuv_sm_SHIFT 22
  308. #define TCON_LCD0_lcd_hv_if_yuv_eav_sav_f_line_dly (0x3 << 20)
  309. #define TCON_LCD0_lcd_hv_if_yuv_eav_sav_f_line_dly_SHIFT 20
  310. #define TCON_LCD0_lcd_hv_if_ccir_csc_dis (0x1 << 19)
  311. #define TCON_LCD0_lcd_hv_if_ccir_csc_dis_SHIFT 19
  312. lcd0.lcd_hv_if_reg.write(|w| unsafe { w.bits(
  313. // LCD_HV_IF_REG.HV_MODE=0 for 24bit/cycle parallel mode.
  314. 0 << 28
  315. )});
  316. */
  317. io_write32(TCON_LCD0_lcd_hv_if, 0 << TCON_LCD0_lcd_hv_if_hv_mode_SHIFT);
  318. dump_reg(TCON_LCD0_lcd_hv_if);
  319. /*
  320. #define TCON_LCD0_lcd_dclk (TCON_LCD0 + 0x44) // LCD Data Clock Register ()
  321. #define TCON_LCD0_lcd_dclk_OFFSET 0x44
  322. #define TCON_LCD0_lcd_dclk_lcd_dclk_en (0xf << 28)
  323. #define TCON_LCD0_lcd_dclk_lcd_dclk_en_SHIFT 28
  324. #define TCON_LCD0_lcd_dclk_lcd_dclk_div 0x7f
  325. #define TCON_LCD0_lcd_dclk_lcd_dclk_div_SHIFT 0
  326. lcd0.lcd_dclk_reg.write(|w| unsafe { w.bits(
  327. // LCD_DCLK_REG.LCD_DCLK_EN=0001 for dclk_en=1, others=0
  328. (0b0001 << 28)
  329. // Linux just sets bit 31, i.e. 0b1000, which is "reserved" in D1 docs.
  330. //(1 << 31)
  331. // LCD_DCLK_REG.LCD_DCLK_DIV=36 for /36 to obtain 9MHz DCLK from 324MHz.
  332. | (13 << 0) //324MHz/13 = ~25MHz
  333. )});
  334. */
  335. io_write32(TCON_LCD0_lcd_dclk, 0
  336. | (0b0001 << TCON_LCD0_lcd_dclk_lcd_dclk_en_SHIFT)
  337. | (13 << TCON_LCD0_lcd_dclk_lcd_dclk_div_SHIFT)
  338. );
  339. dump_reg(TCON_LCD0_lcd_dclk);
  340. /*
  341. #define TCON_LCD0_lcd_basic0 (TCON_LCD0 + 0x48) // LCD Basic Timing Register0 ()
  342. #define TCON_LCD0_lcd_basic0_OFFSET 0x48
  343. #define TCON_LCD0_lcd_basic0_width_x (0xfff << 16)
  344. #define TCON_LCD0_lcd_basic0_width_x_SHIFT 16
  345. #define TCON_LCD0_lcd_basic0_height_y 0xfff
  346. #define TCON_LCD0_lcd_basic0_height_y_SHIFT 0
  347. lcd0.lcd_basic0_reg.write(|w| unsafe { w.bits(
  348. // LCD_BASIC0_REG.WIDTH_X=479 for 480px wide panel
  349. ((640-1) << 16)
  350. // LCD_BASIC0_REG.HEIGHT_Y=271 for 272px tall panel
  351. | ((480-1) << 0)
  352. )});
  353. */
  354. io_write32(TCON_LCD0_lcd_basic0, 0
  355. | ((640-1) << TCON_LCD0_lcd_basic0_width_x_SHIFT)
  356. | ((480-1) << TCON_LCD0_lcd_basic0_height_y_SHIFT)
  357. );
  358. dump_reg(TCON_LCD0_lcd_basic0);
  359. /*
  360. #define TCON_LCD0_lcd_basic1 (TCON_LCD0 + 0x4c) // LCD Basic Timing Register1 ()
  361. #define TCON_LCD0_lcd_basic1_OFFSET 0x4c
  362. #define TCON_LCD0_lcd_basic1_ht (0x1fff << 16)
  363. #define TCON_LCD0_lcd_basic1_ht_SHIFT 16
  364. #define TCON_LCD0_lcd_basic1_hbp 0xfff
  365. #define TCON_LCD0_lcd_basic1_hbp_SHIFT 0
  366. lcd0.lcd_basic1_reg.write(|w| unsafe { w.bits(
  367. // LCD_BASIC1_REG.HT=530 for 531 horizontal clocks total
  368. ((800-1) << 16)
  369. // LCD_BASIC1_REG.HBP=42 for 43 Thbp (sync+bp)
  370. | ((96+48-1) << 0)
  371. )});
  372. */
  373. io_write32(TCON_LCD0_lcd_basic1, 0
  374. | ((800-1) << TCON_LCD0_lcd_basic1_ht_SHIFT)
  375. | ((96+48-1) << TCON_LCD0_lcd_basic1_hbp_SHIFT
  376. ));
  377. dump_reg(TCON_LCD0_lcd_basic1);
  378. /*
  379. #define TCON_LCD0_lcd_basic2 (TCON_LCD0 + 0x50) // LCD Basic Timing Register2 ()
  380. #define TCON_LCD0_lcd_basic2_OFFSET 0x50
  381. #define TCON_LCD0_lcd_basic2_vt (0x1fff << 16)
  382. #define TCON_LCD0_lcd_basic2_vt_SHIFT 16
  383. #define TCON_LCD0_lcd_basic2_vbp 0xfff
  384. #define TCON_LCD0_lcd_basic2_vbp_SHIFT 0
  385. lcd0.lcd_basic2_reg.write(|w| unsafe { w.bits(
  386. // LCD_BASIC2_REG.VT=584 for 292 vertical rows total
  387. ((525*2) << 16)
  388. // LCD_BASIC2_REG.VBP=11 for 12 Tvbp (sync+bp)
  389. | ((2+33-1) << 0)
  390. )});
  391. */
  392. io_write32(TCON_LCD0_lcd_basic2, 0
  393. | ((525*2) << TCON_LCD0_lcd_basic2_vt_SHIFT)
  394. | ((2+33-1) << TCON_LCD0_lcd_basic2_vbp_SHIFT)
  395. );
  396. dump_reg(TCON_LCD0_lcd_basic2);
  397. /*
  398. #define TCON_LCD0_lcd_basic3 (TCON_LCD0 + 0x54) // LCD Basic Timing Register3 ()
  399. #define TCON_LCD0_lcd_basic3_OFFSET 0x54
  400. #define TCON_LCD0_lcd_basic3_hspw (0x3ff << 16)
  401. #define TCON_LCD0_lcd_basic3_hspw_SHIFT 16
  402. #define TCON_LCD0_lcd_basic3_vspw 0x3ff
  403. #define TCON_LCD0_lcd_basic3_vspw_SHIFT 0
  404. lcd0.lcd_basic3_reg.write(|w| unsafe { w.bits(
  405. // LCD_BASIC3_REG.HSPW=3 for 4 DCLK wide HSYNC pulse
  406. (96 << 16)
  407. // LCD_BASIC3_REG.VSPW=3 for 4 row long VSYNC pulse
  408. | (2 << 0)
  409. )});
  410. */
  411. io_write32(TCON_LCD0_lcd_basic3, 0
  412. | (96 << TCON_LCD0_lcd_basic3_hspw_SHIFT)
  413. | (2 << TCON_LCD0_lcd_basic3_vspw_SHIFT)
  414. );
  415. dump_reg(TCON_LCD0_lcd_basic3);
  416. /*
  417. #define TCON_LCD0_lcd_io_tri (TCON_LCD0 + 0x8c) // LCD IO Control Register ()
  418. #define TCON_LCD0_lcd_io_tri_OFFSET 0x8c
  419. #define TCON_LCD0_lcd_io_tri_RESET 0x0FFFFFFF
  420. #define TCON_LCD0_lcd_io_tri_rgb_endian (0x1 << 28)
  421. #define TCON_LCD0_lcd_io_tri_rgb_endian_SHIFT 28
  422. #define TCON_LCD0_lcd_io_tri_io0_output_tri_en (0x1 << 24)
  423. #define TCON_LCD0_lcd_io_tri_io0_output_tri_en_SHIFT 24
  424. #define TCON_LCD0_lcd_io_tri_data_output_tri_en 0xffffff
  425. #define TCON_LCD0_lcd_io_tri_data_output_tri_en_SHIFT 0
  426. lcd0.lcd_io_tri_reg.write(|w| unsafe { w.bits(
  427. // Enable IO0-3, D2..7, D10..15, D18..23 inclusive.
  428. 0x0003_0303
  429. )});
  430. */
  431. io_write32(TCON_LCD0_lcd_io_tri, 0x00030303);
  432. dump_reg(TCON_LCD0_lcd_io_tri);
  433. /*
  434. #define TCON_LCD0_lcd_io_pol (TCON_LCD0 + 0x88) // LCD IO Polarity Register ()
  435. #define TCON_LCD0_lcd_io_pol_OFFSET 0x88
  436. #define TCON_LCD0_lcd_io_pol_io_output_sel (0x1 << 31)
  437. #define TCON_LCD0_lcd_io_pol_io_output_sel_SHIFT 31
  438. #define TCON_LCD0_lcd_io_pol_dclk_sel (0x7 << 28)
  439. #define TCON_LCD0_lcd_io_pol_dclk_sel_SHIFT 28
  440. #define TCON_LCD0_lcd_io_pol_io0_inv (0x1 << 24)
  441. #define TCON_LCD0_lcd_io_pol_io0_inv_SHIFT 24
  442. #define TCON_LCD0_lcd_io_pol_data_inv 0xffffff
  443. #define TCON_LCD0_lcd_io_pol_data_inv_SHIFT 0
  444. lcd0.lcd_io_pol_reg.write(|w| unsafe { w.bits(
  445. 0b0011 << 24 //DE, CLK, H, V polarity
  446. )});
  447. */
  448. io_write32(TCON_LCD0_lcd_io_pol, 0b0011 << TCON_LCD0_lcd_io_pol_io0_inv_SHIFT);
  449. dump_reg(TCON_LCD0_lcd_io_pol);
  450. /*
  451. // LCD_EN
  452. lcd0.lcd_ctl_reg.modify(|r, w| unsafe { w.bits(r.bits() | (1 << 31)) });
  453. */
  454. io_write32(TCON_LCD0_lcd_ctl, io_read32(TCON_LCD0_lcd_ctl) | TCON_LCD0_lcd_ctl_lcd_en);
  455. dump_reg(TCON_LCD0_lcd_ctl);
  456. /*
  457. unsafe { de::init(&FB.0) };
  458. */
  459. void init_de(void);
  460. init_de();
  461. }
  462. /*
  463. Working values for 640x480 (test grid):
  464. REGISTER at 0x2001040: 0xc0001a02
  465. REGISTER at 0x2001040: 0xe0001a02
  466. REGISTER at 0x2001040: 0xf0001a02
  467. REGISTER at 0x2001040: 0xf8001a02
  468. REGISTER at 0x2001b60: 0x81000000
  469. REGISTER at 0x2001b7c: 0x10001
  470. REGISTER at 0x2001600: 0x81000000
  471. REGISTER at 0x200160c: 0x10001
  472. REGISTER at 0x2000090: 0x22222222
  473. REGISTER at 0x2000094: 0x22222222
  474. REGISTER at 0x2000098: 0x1222222
  475. REGISTER at 0x20000a0: 0x400000
  476. REGISTER at 0x5461000: 0x80000000
  477. REGISTER at 0x5461040: 0x167
  478. REGISTER at 0x5461058: 0x0
  479. REGISTER at 0x5461044: 0x1000000d
  480. REGISTER at 0x5461048: 0x27f01df
  481. REGISTER at 0x546104c: 0x31f008f
  482. REGISTER at 0x5461050: 0x41a0022
  483. REGISTER at 0x5461054: 0x600002
  484. REGISTER at 0x546108c: 0x30303
  485. REGISTER at 0x5461088: 0x3
  486. REGISTER at 0x5461040: 0x80000167
  487. */
  488. #define DE_BASE 0x05000000
  489. #define DE_SCLK_GATE (DE_BASE + 0x000)
  490. #define DE_HCLK_GATE (DE_BASE + 0x004)
  491. #define DE_AHB_RESET (DE_BASE + 0x008)
  492. #define DE_SCLK_DIV (DE_BASE + 0x00C)
  493. #define DE_MIXER0 (DE_BASE + 0x00100000)
  494. #define DE_M0_GLB (DE_MIXER0 + 0x00000)
  495. #define DE_M0_BLD (DE_MIXER0 + 0x01000)
  496. #define DE_M0_OVL_V (DE_MIXER0 + 0x02000)
  497. #define DE_M0_OVL_UI1 (DE_MIXER0 + 0x03000)
  498. #define DE_M0_VIDEO_SCALAR (DE_MIXER0 + 0x20000)
  499. #define DE_M0_UI_SCALAR1 (DE_MIXER0 + 0x40000)
  500. #define DE_M0_POST_PROC1 (DE_MIXER0 + 0xA0000)
  501. #define DE_M0_POST_PROC2 (DE_MIXER0 + 0xB0000)
  502. #define DE_M0_DMA (DE_MIXER0 + 0xC0000)
  503. #define DE_M0_GLB_CTL (DE_M0_GLB + 0x000)
  504. #define DE_M0_GLB_STS (DE_M0_GLB + 0x004)
  505. #define DE_M0_GLB_DBUFFER (DE_M0_GLB + 0x008)
  506. #define DE_M0_GLB_SIZE (DE_M0_GLB + 0x00C)
  507. #define DE_M0_OVL_V_ATTCTL (DE_M0_OVL_V + 0x000)
  508. #define DE_M0_OVL_V_MBSIZE (DE_M0_OVL_V + 0x004)
  509. #define DE_M0_OVL_V_COOR (DE_M0_OVL_V + 0x008)
  510. #define DE_M0_OVL_V_PITCH0 (DE_M0_OVL_V + 0x00C)
  511. #define DE_M0_OVL_V_PITCH1 (DE_M0_OVL_V + 0x010)
  512. #define DE_M0_OVL_V_PITCH2 (DE_M0_OVL_V + 0x014)
  513. #define DE_M0_OVL_V_TOP_LADD0 (DE_M0_OVL_V + 0x018)
  514. #define DE_M0_OVL_V_TOP_LADD1 (DE_M0_OVL_V + 0x01C)
  515. #define DE_M0_OVL_V_TOP_LADD2 (DE_M0_OVL_V + 0x020)
  516. #define DE_M0_OVL_V_BOT_LADD0 (DE_M0_OVL_V + 0x024)
  517. #define DE_M0_OVL_V_BOT_LADD1 (DE_M0_OVL_V + 0x028)
  518. #define DE_M0_OVL_V_BOT_LADD2 (DE_M0_OVL_V + 0x02C)
  519. #define DE_M0_OVL_V_FILL_COLOR (DE_M0_OVL_V + 0x0C0)
  520. #define DE_M0_OVL_V_TOP_HADD0 (DE_M0_OVL_V + 0x0D0)
  521. #define DE_M0_OVL_V_TOP_HADD1 (DE_M0_OVL_V + 0x0D4)
  522. #define DE_M0_OVL_V_TOP_HADD2 (DE_M0_OVL_V + 0x0D8)
  523. #define DE_M0_OVL_V_BOT_HADD0 (DE_M0_OVL_V + 0x0DC)
  524. #define DE_M0_OVL_V_BOT_HADD1 (DE_M0_OVL_V + 0x0E0)
  525. #define DE_M0_OVL_V_BOT_HADD2 (DE_M0_OVL_V + 0x0E4)
  526. #define DE_M0_OVL_V_SIZE (DE_M0_OVL_V + 0x0E8)
  527. #define DE_M0_OVL_V_HDS_CTL0 (DE_M0_OVL_V + 0x0F0)
  528. #define DE_M0_OVL_V_HDS_CTL1 (DE_M0_OVL_V + 0x0F4)
  529. #define DE_M0_OVL_V_VDS_CTL0 (DE_M0_OVL_V + 0x0F8)
  530. #define DE_M0_OVL_V_VDS_CTL1 (DE_M0_OVL_V + 0x0FC)
  531. #define DE_M0_UI1_ATTCTL_L0 (DE_M0_OVL_UI1 + 0x000)
  532. #define DE_M0_UI1_MBSIZE_L0 (DE_M0_OVL_UI1 + 0x004)
  533. #define DE_M0_UI1_COOR_L0 (DE_M0_OVL_UI1 + 0x008)
  534. #define DE_M0_UI1_PITCH_L0 (DE_M0_OVL_UI1 + 0x00C)
  535. #define DE_M0_UI1_TOP_LADD_L0 (DE_M0_OVL_UI1 + 0x010)
  536. #define DE_M0_UI1_BOT_LADD_L0 (DE_M0_OVL_UI1 + 0x014)
  537. #define DE_M0_UI1_FILL_COLOR_L0 (DE_M0_OVL_UI1 + 0x018)
  538. #define DE_M0_UI1_TOP_HADD (DE_M0_OVL_UI1 + 0x080)
  539. #define DE_M0_UI1_BOT_HADD (DE_M0_OVL_UI1 + 0x084)
  540. #define DE_M0_UI1_SIZE (DE_M0_OVL_UI1 + 0x088)
  541. #define DE_M0_BLD_FILL_COLOR_CTL (DE_M0_BLD + 0x000)
  542. #define DE_M0_BLD_FILL_COLOR_P0 (DE_M0_BLD + 0x004 + 0 * 0x14)
  543. #define DE_M0_BLD_CH_ISIZE_P0 (DE_M0_BLD + 0x008 + 0 * 0x14)
  544. #define DE_M0_BLD_CH_OFFSET_P0 (DE_M0_BLD + 0x008 + 0 * 0x14)
  545. #define DE_M0_BLD_CH_RTCTL (DE_M0_BLD + 0x080)
  546. #define DE_M0_BLD_PREMUL_CTL (DE_M0_BLD + 0x084)
  547. #define DE_M0_BLD_BK_COLOR (DE_M0_BLD + 0x088)
  548. #define DE_M0_BLD_SIZE (DE_M0_BLD + 0x08C)
  549. #define DE_M0_BLD_CTL (DE_M0_BLD + 0x090)
  550. #define DE_M0_BLD_KEY_CTL (DE_M0_BLD + 0x0B0)
  551. #define DE_M0_BLD_KEY_CON (DE_M0_BLD + 0x0B4)
  552. #define DE_M0_BLD_KEY_MAX (DE_M0_BLD + 0x0C0)
  553. #define DE_M0_BLD_KEY_MIN (DE_M0_BLD + 0x0E0)
  554. #define DE_M0_BLD_OUT_COLOR (DE_M0_BLD + 0x0FC)
  555. #warning this should be parameters
  556. uintptr_t framebuffer_address;
  557. unsigned framebuffer_pitch;
  558. //see https://linux-sunxi.org/images/7/7b/Allwinner_DE2.0_Spec_V1.0.pdf section 5.10
  559. void init_de(void)
  560. {
  561. framebuffer_pitch = 640*sizeof(uint32_t);
  562. // Enable ROT_SCLK_GATE, RT_WB_SCLK_GATE, CORE1_SCLK_GATE, CORE0_SCLK_GATE
  563. // (at least, as they exist in the H8).
  564. // write_volatile(DE_SCLK_GATE as *mut u32, 0xF);
  565. io_write32(DE_SCLK_GATE, 0b1111);
  566. dump_reg(DE_SCLK_GATE);
  567. // Enable ROT_HCLK_GATE, RT_WB_HCLK_GATE, CORE1_HCLK_GATE, CORE_HCLK_GATE0
  568. // (at least, as they exist in the H8).
  569. // write_volatile(DE_HCLK_GATE as *mut u32, 0xF);
  570. io_write32(DE_HCLK_GATE, 0b1111);
  571. dump_reg(DE_HCLK_GATE);
  572. // Bring ROT, RT_WB, CORE1, CORE0 out of reset.
  573. // write_volatile(DE_AHB_RESET as *mut u32, 0xF);
  574. io_write32(DE_AHB_RESET, 0b1111);
  575. dump_reg(DE_AHB_RESET);
  576. // Hopefully default div is OK.
  577. /* write_volatile(DE_SCLK_DIV as *mut u32,
  578. (0 << 12) // ROT_SCLK_DIV
  579. | (0 << 8) // RT_WB_SCLK_DIV
  580. | (0 << 4) // CORE1_SCLK_DIV
  581. | (0 << 0) // CORE0_SCLK_DIV
  582. );*/
  583. io_write32(DE_SCLK_DIV, 0
  584. | (0 << 12) // ROT_SCLK_DIV
  585. | (0 << 8) // RT_WB_SCLK_DIV
  586. | (0 << 4) // CORE1_SCLK_DIV
  587. | (0 << 0) // CORE0_SCLK_DIV
  588. );
  589. dump_reg(DE_SCLK_DIV);
  590. // Hopefully DE2TCON_MUX either doesn't exist or default is fine.
  591. // Hopefully CMD_CTL either doesn't exist or default is fine.
  592. // Hopefully DI_CTL either doesn't exist or default is fine.
  593. // Enable RT
  594. // write_volatile(DE_M0_GLB_CTL as *mut u32, 1);
  595. io_write32(DE_M0_GLB_CTL, 1);
  596. dump_reg(DE_M0_GLB_CTL);
  597. // Set height=272 and width=480
  598. // write_volatile(DE_M0_GLB_SIZE as *mut u32, ((480-1) << 16) | ((640-1) << 0));
  599. io_write32(DE_M0_GLB_SIZE, ((480-1) << 16) | ((640-1) << 0));
  600. dump_reg(DE_M0_GLB_SIZE);
  601. // Set OVL_UI1_L0 to alpha=FF, top-addr-only, no-premult, BGR888, no fill, global alpha, enable
  602. // NB not sure why BGR is required, since data is in RGB...??
  603. // write_volatile(DE_M0_UI1_ATTCTL_L0 as *mut u32, (0xFF << 24) | (0 << 23) | (0 << 16) | (0x09 << 8) | (0 << 4) | (1 << 1) | (1 << 0));
  604. //See DE manual, Section 5.10.8
  605. //Note: the layer priority is layer3>layer2>layer1>layer0
  606. enum LAY_FBFMT
  607. {
  608. ARGB_8888 = 0,
  609. ABGR_8888,
  610. RGBA_8888,
  611. BGRA_8888,
  612. XRGB_8888,
  613. XBGR_8888,
  614. RGBX_8888,
  615. BGRX_8888,
  616. RGB_888,
  617. BGR_888,
  618. RGB_565,
  619. BGR_565,
  620. ARGB_4444,
  621. ABGR_4444,
  622. RGBA_4444,
  623. BGRA_4444,
  624. ARGB_1555,
  625. ABGR_1555,
  626. RGBA_5551,
  627. BGRA_5551
  628. };
  629. io_write32(DE_M0_UI1_ATTCTL_L0, 0
  630. | (0xFF << 24) //LAY_GBLALPHA
  631. | (0 << 23) //TOP_BOTTOM_ADDR_EN
  632. | (0 << 16) //LAY_PREMUL_CTL
  633. | (XBGR_8888 << 8) //LAY_FBFMT
  634. | (0 << 4) //LAY_FILLCOLOR_EN
  635. | (1 << 1) //LAY_ALPHA_MODE
  636. | (1 << 0) //LAY_EN
  637. );
  638. dump_reg(DE_M0_UI1_ATTCTL_L0);
  639. // Set OVL_UI1_L0 to height=272 width=480
  640. // write_volatile(DE_M0_UI1_MBSIZE_L0 as *mut u32, ((480-1) << 16) | ((640-1) << 0));
  641. io_write32(DE_M0_UI1_MBSIZE_L0, ((480-1) << 16) | ((640-1) << 0));
  642. dump_reg(DE_M0_UI1_MBSIZE_L0);
  643. // Set OVL_UI1_L0 coordinate to 0, 0
  644. // write_volatile(DE_M0_UI1_COOR_L0 as *mut u32, (0 << 16) | (0 << 0));
  645. io_write32(DE_M0_UI1_COOR_L0, (0 << 16) | (0 << 0));
  646. dump_reg(DE_M0_UI1_COOR_L0);
  647. // Set OVL_UI1_L0 pitch to 480*3 bytes/line.
  648. // write_volatile(DE_M0_UI1_PITCH_L0 as *mut u32, 640*3);
  649. io_write32(DE_M0_UI1_PITCH_L0, framebuffer_pitch);
  650. dump_reg(DE_M0_UI1_PITCH_L0);
  651. // Set memory start address
  652. // write_volatile(DE_M0_UI1_TOP_LADD_L0 as *mut u32, fb.as_ptr() as u32);
  653. // write_volatile(DE_M0_UI1_TOP_HADD as *mut u32, 0);
  654. io_write32(DE_M0_UI1_TOP_LADD_L0, framebuffer_address);
  655. dump_reg(DE_M0_UI1_TOP_LADD_L0);
  656. io_write32(DE_M0_UI1_TOP_HADD, 0);
  657. dump_reg(DE_M0_UI1_TOP_HADD);
  658. // Set overlay to 272x480
  659. // write_volatile(DE_M0_UI1_SIZE as *mut u32, ((480-1) << 16) | ((640-1) << 0));
  660. io_write32(DE_M0_UI1_SIZE, ((480-1) << 16) | ((640-1) << 0));
  661. dump_reg(DE_M0_UI1_SIZE);
  662. // Enable Pipe0, no fill
  663. // write_volatile(DE_M0_BLD_FILL_COLOR_CTL as *mut u32, 1<<8);
  664. io_write32(DE_M0_BLD_FILL_COLOR_CTL, 1<<8);
  665. dump_reg(DE_M0_BLD_FILL_COLOR_CTL);
  666. // Pipe0 Input size 272x480
  667. // write_volatile(DE_M0_BLD_CH_ISIZE_P0 as *mut u32, ((480-1)<<16) | ((640-1) << 0));
  668. io_write32(DE_M0_BLD_CH_ISIZE_P0, ((480-1)<<16) | ((640-1) << 0));
  669. dump_reg(DE_M0_BLD_CH_ISIZE_P0);
  670. // Pipe 0 offset apparently needs to be 271,479? Not sure why.
  671. // write_volatile(DE_M0_BLD_CH_OFFSET_P0 as *mut u32, ((480-1) << 16) | ((640-1) << 0));
  672. io_write32(DE_M0_BLD_CH_OFFSET_P0, ((480-1) << 16) | ((640-1) << 0));
  673. dump_reg(DE_M0_BLD_CH_OFFSET_P0);
  674. // Pipe 0 select from channel 1, pipe 1 from 0, pipe 2 from 2, pipe 3 from 3
  675. // write_volatile(DE_M0_BLD_CH_RTCTL as *mut u32, (3<<12) | (2<<8) | (0<<4) | (1<<0));
  676. io_write32(DE_M0_BLD_CH_RTCTL, (3<<12) | (2<<8) | (0<<4) | (1<<0));
  677. dump_reg(DE_M0_BLD_CH_RTCTL);
  678. // Output size 272x480
  679. // write_volatile(DE_M0_BLD_SIZE as *mut u32, ((480-1) << 16) | ((640-1) << 0));
  680. io_write32(DE_M0_BLD_SIZE, ((480-1) << 16) | ((640-1) << 0));
  681. dump_reg(DE_M0_BLD_SIZE);
  682. }
  683. /*
  684. DE values for 640x480, 32-bpp:
  685. EGISTER at 0x5000000: 0xf
  686. REGISTER at 0x5000004: 0xf
  687. REGISTER at 0x5000008: 0xf
  688. REGISTER at 0x500000c: 0x0
  689. REGISTER at 0x5100000: 0x1
  690. REGISTER at 0x510000c: 0x1df027f
  691. REGISTER at 0x5103000: 0xff000503
  692. REGISTER at 0x5103004: 0x1df027f
  693. REGISTER at 0x5103008: 0x0
  694. REGISTER at 0x510300c: 0xa00
  695. REGISTER at 0x5103010: 0x40000b50
  696. REGISTER at 0x5103080: 0x0
  697. REGISTER at 0x5103088: 0x1df027f
  698. REGISTER at 0x5101000: 0x100
  699. REGISTER at 0x5101008: 0x1df027f
  700. REGISTER at 0x5101008: 0x1df027f
  701. REGISTER at 0x5101080: 0x3201
  702. REGISTER at 0x510108c: 0x1df027f
  703. */