1// Copyright 2018 The Fuchsia Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "astro-clock.h" 6#include <ddk/debug.h> 7 8namespace astro_display { 9 10namespace { 11constexpr uint8_t kMaxPllLockAttempt = 3; 12constexpr uint8_t kStv2Sel = 5; 13constexpr uint8_t kStv1Sel = 4; 14constexpr uint32_t kKHZ = 1000; 15} // namespace 16 17#define READ32_HHI_REG(a) hhi_regs_->Read<uint32_t>(a) 18#define WRITE32_HHI_REG(a, v) hhi_regs_->Write<uint32_t>(a, v) 19 20#define READ32_VPU_REG(a) vpu_regs_->Read<uint32_t>(a) 21#define WRITE32_VPU_REG(a, v) vpu_regs_->Write<uint32_t>(a, v) 22 23void AstroDisplayClock::CalculateLcdTiming(const DisplaySetting& d) { 24 // Calculate and store DataEnable horizontal and vertical start/stop times 25 const uint32_t de_hstart = d.h_period - d.h_active - 1; 26 const uint32_t de_vstart = d.v_period - d.v_active; 27 lcd_timing_.vid_pixel_on = de_hstart; 28 lcd_timing_.vid_line_on = de_vstart; 29 lcd_timing_.de_hs_addr = de_hstart; 30 lcd_timing_.de_he_addr = de_hstart + d.h_active; 31 lcd_timing_.de_vs_addr = de_vstart; 32 lcd_timing_.de_ve_addr = de_vstart + d.v_active - 1; 33 34 // Calculate and Store HSync horizontal and vertical start/stop times 35 const uint32_t hstart = (de_hstart + d.h_period - d.hsync_bp - d.hsync_width) % d.h_period; 36 const uint32_t hend = (de_hstart + d.h_period - d.hsync_bp) % d.h_period; 37 lcd_timing_.hs_hs_addr = hstart; 38 lcd_timing_.hs_he_addr = hend; 39 lcd_timing_.hs_vs_addr = 0; 40 lcd_timing_.hs_ve_addr = d.v_period - 1; 41 42 // Calculate and Store VSync horizontal and vertical start/stop times 43 lcd_timing_.vs_hs_addr = (hstart + d.h_period) % d.h_period; 44 lcd_timing_.vs_he_addr = lcd_timing_.vs_hs_addr; 45 const uint32_t vstart = (de_vstart + d.v_period - d.vsync_bp - d.vsync_width) % d.v_period; 46 const uint32_t vend = (de_vstart + d.v_period - d.vsync_bp) % d.v_period; 47 lcd_timing_.vs_vs_addr = vstart; 48 lcd_timing_.vs_ve_addr = vend; 49} 50 51zx_status_t AstroDisplayClock::PllLockWait() { 52 uint32_t pll_lock; 53 54 for (int lock_attempts = 0; lock_attempts < kMaxPllLockAttempt; lock_attempts++) { 55 DISP_SPEW("Waiting for PLL Lock: (%d/3).\n", lock_attempts+1); 56 if (lock_attempts == 1) { 57 SET_BIT32(HHI, HHI_HDMI_PLL_CNTL3, 1, 31, 1); 58 } else if (lock_attempts == 2) { 59 WRITE32_REG(HHI, HHI_HDMI_PLL_CNTL6, 0x55540000); // more magic 60 } 61 int retries = 1000; 62 while ((pll_lock = GET_BIT32(HHI, HHI_HDMI_PLL_CNTL0, LCD_PLL_LOCK_HPLL_G12A, 1)) != 1 && 63 retries--) { 64 zx_nanosleep(zx_deadline_after(ZX_USEC(50))); 65 } 66 if (pll_lock) { 67 return ZX_OK; 68 } 69 } 70 71 // We got here, which means we never locked! 72 DISP_ERROR("PLL not locked! exiting\n"); 73 return ZX_ERR_UNAVAILABLE; 74} 75 76zx_status_t AstroDisplayClock::GenerateHPLL(const DisplaySetting& d) { 77 uint32_t pll_fout; 78 // Requested Pixel clock 79 pll_cfg_.fout = d.lcd_clock / kKHZ; // KHz 80 // Desired PLL Frequency based on pixel clock needed 81 pll_fout = pll_cfg_.fout * d.clock_factor; 82 83 // Make sure all clocks are within range 84 // If these values are not within range, we will not have a valid display 85 if((pll_cfg_.fout > MAX_PIXEL_CLK_KHZ) || 86 (pll_fout < MIN_PLL_FREQ_KHZ) || (pll_fout > MAX_PLL_FREQ_KHZ)) { 87 DISP_ERROR("Calculated clocks out of range!\n"); 88 return ZX_ERR_OUT_OF_RANGE; 89 } 90 91 // Now that we have valid frequency ranges, let's calculated all the PLL-related 92 // multipliers/dividers 93 // [fin] * [m/n] = [pll_vco] 94 // [pll_vco] / [od1] / [od2] / [od3] = pll_fout 95 // [fvco] --->[OD1] --->[OD2] ---> [OD3] --> pll_fout 96 uint32_t od3, od2, od1; 97 od3 = (1 << (MAX_OD_SEL - 1)); 98 while (od3) { 99 uint32_t fod3 = pll_fout * od3; 100 od2 = od3; 101 while (od2) { 102 uint32_t fod2 = fod3 * od2; 103 od1 = od2; 104 while (od1) { 105 uint32_t fod1 = fod2 * od1; 106 if ((fod1 >= MIN_PLL_VCO_KHZ) && 107 (fod1 <= MAX_PLL_VCO_KHZ)) { 108 // within range! 109 pll_cfg_.pll_od1_sel = od1 >> 1; 110 pll_cfg_.pll_od2_sel = od2 >> 1; 111 pll_cfg_.pll_od3_sel = od3 >> 1; 112 pll_cfg_.pll_fout = pll_fout; 113 DISP_SPEW("od1=%d, od2=%d, od3=%d\n", 114 (od1 >> 1), (od2 >> 1), 115 (od3 >> 1)); 116 DISP_SPEW("pll_fvco=%d\n", fod1); 117 pll_cfg_.pll_fvco = fod1; 118 // for simplicity, assume n = 1 119 // calculate m such that fin x m = fod1 120 uint32_t m; 121 uint32_t pll_frac; 122 fod1 = fod1 / 1; 123 m = fod1 / FIN_FREQ_KHZ; 124 pll_frac = (fod1 % FIN_FREQ_KHZ) * PLL_FRAC_RANGE / FIN_FREQ_KHZ; 125 pll_cfg_.pll_m = m; 126 pll_cfg_.pll_n = 1; 127 pll_cfg_.pll_frac = pll_frac; 128 DISP_SPEW("m=%d, n=%d, frac=0x%x\n", 129 m, 1, pll_frac); 130 pll_cfg_.bitrate = pll_fout * kKHZ; // Hz 131 return ZX_OK; 132 } 133 od1 >>= 1; 134 } 135 od2 >>= 1; 136 } 137 od3 >>= 1; 138 } 139 140 DISP_ERROR("Could not generate correct PLL values!\n"); 141 return ZX_ERR_INTERNAL; 142} 143 144void AstroDisplayClock::Disable() { 145 ZX_DEBUG_ASSERT(initialized_); 146 if (!clock_enabled_) { 147 return; 148 } 149 WRITE32_REG(VPU, ENCL_VIDEO_EN, 0); 150 151 SET_BIT32(HHI, HHI_VID_CLK_CNTL2, 0, ENCL_GATE_VCLK, 1); 152 SET_BIT32(HHI, HHI_VIID_CLK_CNTL, 0, 0, 5); 153 SET_BIT32(HHI, HHI_VIID_CLK_CNTL, 0, VCLK2_EN, 1); 154 155 // disable pll 156 SET_BIT32(HHI, HHI_HDMI_PLL_CNTL0, 0, LCD_PLL_EN_HPLL_G12A, 1); 157 clock_enabled_ = false; 158} 159 160zx_status_t AstroDisplayClock::Enable(const DisplaySetting& d) { 161 ZX_DEBUG_ASSERT(initialized_); 162 163 if (clock_enabled_) { 164 return ZX_OK; 165 } 166 167 // Populate internal LCD timing structure based on predefined tables 168 CalculateLcdTiming(d); 169 GenerateHPLL(d); 170 171 uint32_t regVal; 172 PllConfig* pll_cfg = &pll_cfg_; 173 bool useFrac = !!pll_cfg->pll_frac; 174 175 regVal = ((1 << LCD_PLL_EN_HPLL_G12A) | 176 (1 << LCD_PLL_OUT_GATE_CTRL_G12A) | // clk out gate 177 (pll_cfg->pll_n << LCD_PLL_N_HPLL_G12A) | 178 (pll_cfg->pll_m << LCD_PLL_M_HPLL_G12A) | 179 (pll_cfg->pll_od1_sel << LCD_PLL_OD1_HPLL_G12A) | 180 (pll_cfg->pll_od2_sel << LCD_PLL_OD2_HPLL_G12A) | 181 (pll_cfg->pll_od3_sel << LCD_PLL_OD3_HPLL_G12A) | 182 (useFrac? (1 << 27) : (0 << 27))); 183 WRITE32_REG(HHI, HHI_HDMI_PLL_CNTL0, regVal); 184 185 WRITE32_REG(HHI, HHI_HDMI_PLL_CNTL1, pll_cfg->pll_frac); 186 WRITE32_REG(HHI, HHI_HDMI_PLL_CNTL2, 0x00); 187 // Magic numbers from U-Boot. 188 WRITE32_REG(HHI, HHI_HDMI_PLL_CNTL3, useFrac? 0x6a285c00 : 0x48681c00); 189 WRITE32_REG(HHI, HHI_HDMI_PLL_CNTL4, useFrac? 0x65771290 : 0x33771290); 190 WRITE32_REG(HHI, HHI_HDMI_PLL_CNTL5, 0x39272000); 191 WRITE32_REG(HHI, HHI_HDMI_PLL_CNTL6, useFrac? 0x56540000 : 0x56540000); 192 193 // reset dpll 194 SET_BIT32(HHI, HHI_HDMI_PLL_CNTL0, 1, LCD_PLL_RST_HPLL_G12A, 1); 195 zx_nanosleep(zx_deadline_after(ZX_USEC(100))); 196 // release from reset 197 SET_BIT32(HHI, HHI_HDMI_PLL_CNTL0, 0, LCD_PLL_RST_HPLL_G12A, 1); 198 199 zx_nanosleep(zx_deadline_after(ZX_USEC(50))); 200 zx_status_t status = PllLockWait(); 201 if (status != ZX_OK) { 202 DISP_ERROR("hpll lock failed\n"); 203 io_buffer_release(&mmio_vpu_); 204 io_buffer_release(&mmio_hhi_); 205 return status; 206 } 207 208 // Enable VIID Clock (whatever that is) 209 SET_BIT32(HHI, HHI_VIID_CLK_CNTL, 0, VCLK2_EN, 1); 210 zx_nanosleep(zx_deadline_after(ZX_USEC(5))); 211 212 // Disable the div output clock 213 SET_BIT32(HHI, HHI_VID_PLL_CLK_DIV, 0, 19, 1); 214 SET_BIT32(HHI, HHI_VID_PLL_CLK_DIV, 0, 15, 1); 215 216 SET_BIT32(HHI, HHI_VID_PLL_CLK_DIV, 1, 18, 1); // Undocumented register bit 217 218 // Enable the final output clock 219 SET_BIT32(HHI, HHI_VID_PLL_CLK_DIV, 1, 19, 1); // Undocumented register bit 220 221 // Undocumented register bits 222 SET_BIT32(HHI, HHI_VDIN_MEAS_CLK_CNTL, 0, 21, 3); 223 SET_BIT32(HHI, HHI_VDIN_MEAS_CLK_CNTL, 0, 12, 7); 224 SET_BIT32(HHI, HHI_VDIN_MEAS_CLK_CNTL, 1, 20, 1); 225 226 // USE VID_PLL 227 SET_BIT32(HHI, HHI_MIPIDSI_PHY_CLK_CNTL, 0, 12, 3); 228 // enable dsi_phy_clk 229 SET_BIT32(HHI, HHI_MIPIDSI_PHY_CLK_CNTL, 1, 8, 1); 230 // set divider to 0 -- undocumented 231 SET_BIT32(HHI, HHI_MIPIDSI_PHY_CLK_CNTL, 0, 0, 7); 232 233 // setup the XD divider value 234 SET_BIT32(HHI, HHI_VIID_CLK_DIV, (d.clock_factor-1), VCLK2_XD, 8); 235 zx_nanosleep(zx_deadline_after(ZX_USEC(5))); 236 237 // select vid_pll_clk 238 SET_BIT32(HHI, HHI_VIID_CLK_CNTL, 0, VCLK2_CLK_IN_SEL, 3); 239 SET_BIT32(HHI, HHI_VIID_CLK_CNTL, 1, VCLK2_EN, 1); 240 zx_nanosleep(zx_deadline_after(ZX_USEC(2))); 241 242 // [15:12] encl_clk_sel, select vclk2_div1 243 SET_BIT32(HHI, HHI_VIID_CLK_DIV, 8, ENCL_CLK_SEL, 4); 244 // release vclk2_div_reset and enable vclk2_div 245 SET_BIT32(HHI, HHI_VIID_CLK_DIV, 1, VCLK2_XD_EN, 2); 246 zx_nanosleep(zx_deadline_after(ZX_USEC(5))); 247 248 SET_BIT32(HHI, HHI_VIID_CLK_CNTL, 1, VCLK2_DIV1_EN, 1); 249 SET_BIT32(HHI, HHI_VIID_CLK_CNTL, 1, VCLK2_SOFT_RST, 1); 250 zx_nanosleep(zx_deadline_after(ZX_USEC(10))); 251 SET_BIT32(HHI, HHI_VIID_CLK_CNTL, 0, VCLK2_SOFT_RST, 1); 252 zx_nanosleep(zx_deadline_after(ZX_USEC(5))); 253 254 // enable CTS_ENCL clk gate 255 SET_BIT32(HHI, HHI_VID_CLK_CNTL2, 1, ENCL_GATE_VCLK, 1); 256 257 zx_nanosleep(zx_deadline_after(ZX_MSEC(10))); 258 259 WRITE32_REG(VPU, ENCL_VIDEO_EN, 0); 260 261 // connect both VIUs (Video Input Units) to LCD LVDS Encoders 262 WRITE32_REG(VPU, VPU_VIU_VENC_MUX_CTRL, (0 << 0) | (0 << 2)); //TODO(payamm): macros 263 264 // Undocumented registers below 265 WRITE32_REG(VPU, ENCL_VIDEO_MODE, 0x8000); // bit[15] shadown en 266 WRITE32_REG(VPU, ENCL_VIDEO_MODE_ADV, 0x0418); // Sampling rate: 1 267 268 // bypass filter -- Undocumented registers 269 WRITE32_REG(VPU, ENCL_VIDEO_FILT_CTRL, 0x1000); 270 WRITE32_REG(VPU, ENCL_VIDEO_MAX_PXCNT, d.h_period - 1); 271 WRITE32_REG(VPU, ENCL_VIDEO_MAX_LNCNT, d.v_period - 1); 272 WRITE32_REG(VPU, ENCL_VIDEO_HAVON_BEGIN, lcd_timing_.vid_pixel_on); 273 WRITE32_REG(VPU, ENCL_VIDEO_HAVON_END, d.h_active - 1 + lcd_timing_.vid_pixel_on); 274 WRITE32_REG(VPU, ENCL_VIDEO_VAVON_BLINE, lcd_timing_.vid_line_on); 275 WRITE32_REG(VPU, ENCL_VIDEO_VAVON_ELINE, d.v_active - 1 + lcd_timing_.vid_line_on); 276 WRITE32_REG(VPU, ENCL_VIDEO_HSO_BEGIN, lcd_timing_.hs_hs_addr); 277 WRITE32_REG(VPU, ENCL_VIDEO_HSO_END, lcd_timing_.hs_he_addr); 278 WRITE32_REG(VPU, ENCL_VIDEO_VSO_BEGIN, lcd_timing_.vs_hs_addr); 279 WRITE32_REG(VPU, ENCL_VIDEO_VSO_END, lcd_timing_.vs_he_addr); 280 WRITE32_REG(VPU, ENCL_VIDEO_VSO_BLINE, lcd_timing_.vs_vs_addr); 281 WRITE32_REG(VPU, ENCL_VIDEO_VSO_ELINE, lcd_timing_.vs_ve_addr); 282 WRITE32_REG(VPU, ENCL_VIDEO_RGBIN_CTRL, 3); 283 WRITE32_REG(VPU, ENCL_VIDEO_EN, 1); 284 285 WRITE32_REG(VPU, L_RGB_BASE_ADDR, 0); 286 WRITE32_REG(VPU, L_RGB_COEFF_ADDR, 0x400); 287 WRITE32_REG(VPU, L_DITH_CNTL_ADDR, 0x400); 288 289 // DE signal for TTL m8,m8m2 290 WRITE32_REG(VPU, L_OEH_HS_ADDR, lcd_timing_.de_hs_addr); 291 WRITE32_REG(VPU, L_OEH_HE_ADDR, lcd_timing_.de_he_addr); 292 WRITE32_REG(VPU, L_OEH_VS_ADDR, lcd_timing_.de_vs_addr); 293 WRITE32_REG(VPU, L_OEH_VE_ADDR, lcd_timing_.de_ve_addr); 294 // DE signal for TTL m8b 295 WRITE32_REG(VPU, L_OEV1_HS_ADDR, lcd_timing_.de_hs_addr); 296 WRITE32_REG(VPU, L_OEV1_HE_ADDR, lcd_timing_.de_he_addr); 297 WRITE32_REG(VPU, L_OEV1_VS_ADDR, lcd_timing_.de_vs_addr); 298 WRITE32_REG(VPU, L_OEV1_VE_ADDR, lcd_timing_.de_ve_addr); 299 300 // Hsync signal for TTL m8,m8m2 301 if (d.hsync_pol == 0) { 302 WRITE32_REG(VPU, L_STH1_HS_ADDR, lcd_timing_.hs_he_addr); 303 WRITE32_REG(VPU, L_STH1_HE_ADDR, lcd_timing_.hs_hs_addr); 304 } else { 305 WRITE32_REG(VPU, L_STH1_HS_ADDR, lcd_timing_.hs_hs_addr); 306 WRITE32_REG(VPU, L_STH1_HE_ADDR, lcd_timing_.hs_he_addr); 307 } 308 WRITE32_REG(VPU, L_STH1_VS_ADDR, lcd_timing_.hs_vs_addr); 309 WRITE32_REG(VPU, L_STH1_VE_ADDR, lcd_timing_.hs_ve_addr); 310 311 // Vsync signal for TTL m8,m8m2 312 WRITE32_REG(VPU, L_STV1_HS_ADDR, lcd_timing_.vs_hs_addr); 313 WRITE32_REG(VPU, L_STV1_HE_ADDR, lcd_timing_.vs_he_addr); 314 if (d.vsync_pol == 0) { 315 WRITE32_REG(VPU, L_STV1_VS_ADDR, lcd_timing_.vs_ve_addr); 316 WRITE32_REG(VPU, L_STV1_VE_ADDR, lcd_timing_.vs_vs_addr); 317 } else { 318 WRITE32_REG(VPU, L_STV1_VS_ADDR, lcd_timing_.vs_vs_addr); 319 WRITE32_REG(VPU, L_STV1_VE_ADDR, lcd_timing_.vs_ve_addr); 320 } 321 322 // DE signal 323 WRITE32_REG(VPU, L_DE_HS_ADDR, lcd_timing_.de_hs_addr); 324 WRITE32_REG(VPU, L_DE_HE_ADDR, lcd_timing_.de_he_addr); 325 WRITE32_REG(VPU, L_DE_VS_ADDR, lcd_timing_.de_vs_addr); 326 WRITE32_REG(VPU, L_DE_VE_ADDR, lcd_timing_.de_ve_addr); 327 328 // Hsync signal 329 WRITE32_REG(VPU, L_HSYNC_HS_ADDR, lcd_timing_.hs_hs_addr); 330 WRITE32_REG(VPU, L_HSYNC_HE_ADDR, lcd_timing_.hs_he_addr); 331 WRITE32_REG(VPU, L_HSYNC_VS_ADDR, lcd_timing_.hs_vs_addr); 332 WRITE32_REG(VPU, L_HSYNC_VE_ADDR, lcd_timing_.hs_ve_addr); 333 334 // Vsync signal 335 WRITE32_REG(VPU, L_VSYNC_HS_ADDR, lcd_timing_.vs_hs_addr); 336 WRITE32_REG(VPU, L_VSYNC_HE_ADDR, lcd_timing_.vs_he_addr); 337 WRITE32_REG(VPU, L_VSYNC_VS_ADDR, lcd_timing_.vs_vs_addr); 338 WRITE32_REG(VPU, L_VSYNC_VE_ADDR, lcd_timing_.vs_ve_addr); 339 340 WRITE32_REG(VPU, L_INV_CNT_ADDR, 0); 341 WRITE32_REG(VPU, L_TCON_MISC_SEL_ADDR, ((1 << kStv1Sel) | (1 << kStv2Sel))); 342 343 WRITE32_REG(VPU, VPP_MISC, READ32_REG(VPU, VPP_MISC) & ~(VPP_OUT_SATURATE)); 344 345 // Ready to be used 346 clock_enabled_ = true; 347 return ZX_OK; 348} 349 350zx_status_t AstroDisplayClock::Init(zx_device_t* parent) { 351 if (initialized_) { 352 return ZX_OK; 353 } 354 355 zx_status_t status = device_get_protocol(parent, ZX_PROTOCOL_PLATFORM_DEV, &pdev_); 356 if (status != ZX_OK) { 357 DISP_ERROR("AstroDisplayClock: Could not get ZX_PROTOCOL_PLATFORM_DEV protocol\n"); 358 return status; 359 } 360 361 // Map VPU and HHI registers 362 status = pdev_map_mmio_buffer(&pdev_, MMIO_VPU, ZX_CACHE_POLICY_UNCACHED_DEVICE, 363 &mmio_vpu_); 364 if (status != ZX_OK) { 365 DISP_ERROR("AstroDisplayClock: Could not map VPU mmio\n"); 366 return status; 367 } 368 status = pdev_map_mmio_buffer(&pdev_, MMIO_HHI, ZX_CACHE_POLICY_UNCACHED_DEVICE, 369 &mmio_hhi_); 370 if (status != ZX_OK) { 371 DISP_ERROR("AstroDisplayClock: Could not map HHI mmio\n"); 372 io_buffer_release(&mmio_vpu_); 373 return status; 374 } 375 376 // Create register io 377 vpu_regs_ = fbl::make_unique<hwreg::RegisterIo>(io_buffer_virt(&mmio_vpu_)); 378 hhi_regs_ = fbl::make_unique<hwreg::RegisterIo>(io_buffer_virt(&mmio_hhi_)); 379 380 initialized_ = true; 381 return ZX_OK; 382} 383 384void AstroDisplayClock::Dump() { 385 ZX_DEBUG_ASSERT(initialized_); 386 DISP_INFO("#############################\n"); 387 DISP_INFO("Dumping pll_cfg structure:\n"); 388 DISP_INFO("#############################\n"); 389 DISP_INFO("fin = 0x%x (%u)\n", pll_cfg_.fin,pll_cfg_.fin); 390 DISP_INFO("fout = 0x%x (%u)\n", pll_cfg_.fout,pll_cfg_.fout); 391 DISP_INFO("pll_m = 0x%x (%u)\n", pll_cfg_.pll_m,pll_cfg_.pll_m); 392 DISP_INFO("pll_n = 0x%x (%u)\n", pll_cfg_.pll_n,pll_cfg_.pll_n); 393 DISP_INFO("pll_fvco = 0x%x (%u)\n", pll_cfg_.pll_fvco,pll_cfg_.pll_fvco); 394 DISP_INFO("pll_od1_sel = 0x%x (%u)\n", pll_cfg_.pll_od1_sel, 395 pll_cfg_.pll_od1_sel); 396 DISP_INFO("pll_od2_sel = 0x%x (%u)\n", pll_cfg_.pll_od2_sel, 397 pll_cfg_.pll_od2_sel); 398 DISP_INFO("pll_od3_sel = 0x%x (%u)\n", pll_cfg_.pll_od3_sel, 399 pll_cfg_.pll_od3_sel); 400 DISP_INFO("pll_frac = 0x%x (%u)\n", pll_cfg_.pll_frac,pll_cfg_.pll_frac); 401 DISP_INFO("pll_fout = 0x%x (%u)\n", pll_cfg_.pll_fout,pll_cfg_.pll_fout); 402 403 DISP_INFO("#############################\n"); 404 DISP_INFO("Dumping lcd_timing structure:\n"); 405 DISP_INFO("#############################\n"); 406 DISP_INFO("vid_pixel_on = 0x%x (%u)\n", lcd_timing_.vid_pixel_on, 407 lcd_timing_.vid_pixel_on); 408 DISP_INFO("vid_line_on = 0x%x (%u)\n", lcd_timing_.vid_line_on, 409 lcd_timing_.vid_line_on); 410 DISP_INFO("de_hs_addr = 0x%x (%u)\n", lcd_timing_.de_hs_addr, 411 lcd_timing_.de_hs_addr); 412 DISP_INFO("de_he_addr = 0x%x (%u)\n", lcd_timing_.de_he_addr, 413 lcd_timing_.de_he_addr); 414 DISP_INFO("de_vs_addr = 0x%x (%u)\n", lcd_timing_.de_vs_addr, 415 lcd_timing_.de_vs_addr); 416 DISP_INFO("de_ve_addr = 0x%x (%u)\n", lcd_timing_.de_ve_addr, 417 lcd_timing_.de_ve_addr); 418 DISP_INFO("hs_hs_addr = 0x%x (%u)\n", lcd_timing_.hs_hs_addr, 419 lcd_timing_.hs_hs_addr); 420 DISP_INFO("hs_he_addr = 0x%x (%u)\n", lcd_timing_.hs_he_addr, 421 lcd_timing_.hs_he_addr); 422 DISP_INFO("hs_vs_addr = 0x%x (%u)\n", lcd_timing_.hs_vs_addr, 423 lcd_timing_.hs_vs_addr); 424 DISP_INFO("hs_ve_addr = 0x%x (%u)\n", lcd_timing_.hs_ve_addr, 425 lcd_timing_.hs_ve_addr); 426 DISP_INFO("vs_hs_addr = 0x%x (%u)\n", lcd_timing_.vs_hs_addr, 427 lcd_timing_.vs_hs_addr); 428 DISP_INFO("vs_he_addr = 0x%x (%u)\n", lcd_timing_.vs_he_addr, 429 lcd_timing_.vs_he_addr); 430 DISP_INFO("vs_vs_addr = 0x%x (%u)\n", lcd_timing_.vs_vs_addr, 431 lcd_timing_.vs_vs_addr); 432 DISP_INFO("vs_ve_addr = 0x%x (%u)\n", lcd_timing_.vs_ve_addr, 433 lcd_timing_.vs_ve_addr); 434} 435 436} // namespace astro_display 437