| 340 | } |
| 341 | |
| 342 | static int |
| 343 | a10fb_setup_tcon(struct a10fb_softc *sc, const struct videomode *mode) |
| 344 | { |
| 345 | u_int interlace, hspw, hbp, vspw, vbp, vbl, width, height, start_delay; |
| 346 | u_int vtotal, framerate, clk; |
| 347 | clk_t clk_ahb; |
| 348 | hwreset_t rst; |
| 349 | uint32_t val; |
| 350 | int error; |
| 351 | |
| 352 | interlace = !!(mode->flags & VID_INTERLACE); |
| 353 | width = mode->hdisplay; |
| 354 | height = mode->vdisplay; |
| 355 | hspw = mode->hsync_end - mode->hsync_start; |
| 356 | hbp = mode->htotal - mode->hsync_start; |
| 357 | vspw = mode->vsync_end - mode->vsync_start; |
| 358 | vbp = mode->vtotal - mode->vsync_start; |
| 359 | vbl = VBLANK_LEN(mode->vtotal, mode->vdisplay, interlace); |
| 360 | start_delay = START_DELAY(vbl); |
| 361 | |
| 362 | /* Leave reset */ |
| 363 | error = hwreset_get_by_ofw_name(sc->dev, 0, "lcd", &rst); |
| 364 | if (error != 0) { |
| 365 | device_printf(sc->dev, "cannot find reset 'lcd'\n"); |
| 366 | return (error); |
| 367 | } |
| 368 | error = hwreset_deassert(rst); |
| 369 | if (error != 0) { |
| 370 | device_printf(sc->dev, "couldn't de-assert reset 'lcd'\n"); |
| 371 | return (error); |
| 372 | } |
| 373 | /* Gating AHB clock for LCD */ |
| 374 | error = clk_get_by_ofw_name(sc->dev, 0, "ahb_lcd", &clk_ahb); |
| 375 | if (error != 0) { |
| 376 | device_printf(sc->dev, "cannot find clk 'ahb_lcd'\n"); |
| 377 | return (error); |
| 378 | } |
| 379 | error = clk_enable(clk_ahb); |
| 380 | if (error != 0) { |
| 381 | device_printf(sc->dev, "cannot enable clk 'ahb_lcd'\n"); |
| 382 | return (error); |
| 383 | } |
| 384 | |
| 385 | /* Disable TCON and TCON1 */ |
| 386 | TCON_WRITE(sc, TCON_GCTL, 0); |
| 387 | TCON_WRITE(sc, TCON1_CTL, 0); |
| 388 | |
| 389 | /* Enable clocks */ |
| 390 | TCON_WRITE(sc, TCON0_DCLK, DCLK_EN); |
| 391 | |
| 392 | /* Disable IO and data output ports */ |
| 393 | TCON_WRITE(sc, TCON1_IO_TRI, IO_TRI_MASK); |
| 394 | |
| 395 | /* Disable TCON and select TCON1 */ |
| 396 | TCON_WRITE(sc, TCON_GCTL, GCTL_IO_MAP_SEL_TCON1); |
| 397 | |
| 398 | /* Source width and height */ |
| 399 | TCON_WRITE(sc, TCON1_BASIC0, BASIC_X(width) | BASIC_Y(height)); |
no test coverage detected