X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=board%2Fbf527-ezkit%2Fvideo.c;h=ca5e9b0454586e090a0e3b7341afc968e7ef1b7c;hb=579129398605fbde65b1612ad01d81874ac411ae;hp=57652be293eb5e907ca9d60eb9e4cb9ffe8dc4ee;hpb=87d93a1ba2ae23550e1370adb7a3b00af0831165;p=u-boot diff --git a/board/bf527-ezkit/video.c b/board/bf527-ezkit/video.c index 57652be293..ca5e9b0454 100644 --- a/board/bf527-ezkit/video.c +++ b/board/bf527-ezkit/video.c @@ -11,41 +11,113 @@ #include #include #include +#include #include -#include +#include #include #include -#define DMA_SIZE16 2 - #include #include -#include - #define LCD_X_RES 320 /* Horizontal Resolution */ #define LCD_Y_RES 240 /* Vertical Resolution */ -#define LCD_BPP 24 /* Bit Per Pixel */ -#define LCD_PIXEL_SIZE (LCD_BPP / 8) +#define DMA_BUS_SIZE 16 + +#ifdef CONFIG_BF527_EZKIT_REV_2_1 /* lq035q1 */ + +#if !defined(CONFIG_LQ035Q1_USE_RGB888_8_BIT_PPI) && \ + !defined(CONFIG_LQ035Q1_USE_RGB565_8_BIT_PPI) +# define CONFIG_LQ035Q1_USE_RGB565_8_BIT_PPI +#endif + +/* Interface 16/18-bit TFT over an 8-bit wide PPI using a + * small Programmable Logic Device (CPLD) + * http://blackfin.uclinux.org/gf/project/stamp/frs/?action=FrsReleaseBrowse&frs_package_id=165 + */ + +#ifdef CONFIG_LQ035Q1_USE_RGB565_8_BIT_PPI +#include +#define LCD_BPP 16 /* Bit Per Pixel */ +#define CLOCKS_PPIX 2 /* Clocks per pixel */ +#define CPLD_DELAY 3 /* RGB565 pipeline delay */ +#endif + +#ifdef CONFIG_LQ035Q1_USE_RGB888_8_BIT_PPI +#include +#define LCD_BPP 24 /* Bit Per Pixel */ +#define CLOCKS_PPIX 3 /* Clocks per pixel */ +#define CPLD_DELAY 5 /* RGB888 pipeline delay */ +#endif + +/* + * HS and VS timing parameters (all in number of PPI clk ticks) + */ + +#define H_ACTPIX (LCD_X_RES * CLOCKS_PPIX) /* active horizontal pixel */ +#define H_PERIOD (336 * CLOCKS_PPIX) /* HS period */ +#define H_PULSE (2 * CLOCKS_PPIX) /* HS pulse width */ +#define H_START (7 * CLOCKS_PPIX + CPLD_DELAY) /* first valid pixel */ + +#define U_LINE 4 /* Blanking Lines */ -#define DMA_BUS_SIZE 16 -#define LCD_CLK (12*1000*1000) /* 12MHz */ +#define V_LINES (LCD_Y_RES + U_LINE) /* total vertical lines */ +#define V_PULSE (2 * CLOCKS_PPIX) /* VS pulse width (1-5 H_PERIODs) */ +#define V_PERIOD (H_PERIOD * V_LINES) /* VS period */ + +#define ACTIVE_VIDEO_MEM_OFFSET ((U_LINE / 2) * LCD_X_RES * (LCD_BPP / 8)) -#define CLOCKS_PER_PIX 3 +/* + * LCD Modes + */ +#define LQ035_RL (0 << 8) /* Right -> Left Scan */ +#define LQ035_LR (1 << 8) /* Left -> Right Scan */ +#define LQ035_TB (1 << 9) /* Top -> Botton Scan */ +#define LQ035_BT (0 << 9) /* Botton -> Top Scan */ +#define LQ035_BGR (1 << 11) /* Use BGR format */ +#define LQ035_RGB (0 << 11) /* Use RGB format */ +#define LQ035_NORM (1 << 13) /* Reversal */ +#define LQ035_REV (0 << 13) /* Reversal */ + +#define LQ035_INDEX 0x74 +#define LQ035_DATA 0x76 + +#define LQ035_DRIVER_OUTPUT_CTL 0x1 +#define LQ035_SHUT_CTL 0x11 + +#define LQ035_DRIVER_OUTPUT_MASK (LQ035_LR | LQ035_TB | LQ035_BGR | LQ035_REV) +#define LQ035_DRIVER_OUTPUT_DEFAULT (0x2AEF & ~LQ035_DRIVER_OUTPUT_MASK) + +#define LQ035_SHUT (1 << 0) /* Shutdown */ +#define LQ035_ON (0 << 0) /* Shutdown */ + +#ifndef CONFIG_LQ035Q1_LCD_MODE +#define CONFIG_LQ035Q1_LCD_MODE (LQ035_NORM | LQ035_RL | LQ035_TB | LQ035_BGR) +#endif + +#else /* t350mcqb */ +#include + +#define LCD_BPP 24 /* Bit Per Pixel */ +#define CLOCKS_PPIX 3 /* Clocks per pixel */ /* HS and VS timing parameters (all in number of PPI clk ticks) */ -#define H_ACTPIX (LCD_X_RES * CLOCKS_PER_PIX) /* active horizontal pixel */ -#define H_PERIOD (408 * CLOCKS_PER_PIX) /* HS period */ +#define H_ACTPIX (LCD_X_RES * CLOCKS_PPIX) /* active horizontal pixel */ +#define H_PERIOD (408 * CLOCKS_PPIX) /* HS period */ #define H_PULSE 90 /* HS pulse width */ #define H_START 204 /* first valid pixel */ #define U_LINE 1 /* Blanking Lines */ -#define V_LINES (LCD_Y_RES + U_LINE) /* total vertical lines */ +#define V_LINES (LCD_Y_RES + U_LINE) /* total vertical lines */ #define V_PULSE (3 * H_PERIOD) /* VS pulse width (1-5 H_PERIODs) */ #define V_PERIOD (H_PERIOD * V_LINES) /* VS period */ #define ACTIVE_VIDEO_MEM_OFFSET (U_LINE * H_ACTPIX) +#endif + +#define LCD_PIXEL_SIZE (LCD_BPP / 8) +#define DMA_SIZE16 2 #define PPI_TX_MODE 0x2 #define PPI_XFER_TYPE_11 0xC @@ -53,144 +125,191 @@ #define PPI_PACK_EN 0x80 #define PPI_POLS_1 0x8000 +#ifdef CONFIG_BF527_EZKIT_REV_2_1 +static struct spi_slave *slave; +static int lq035q1_control(unsigned char reg, unsigned short value) +{ + int ret; + u8 regs[3] = {LQ035_INDEX, 0, 0}; + u8 data[3] = {LQ035_DATA, 0, 0}; + u8 dummy[3]; + + regs[2] = reg; + data[1] = value >> 8; + data[2] = value & 0xFF; + + if (!slave) { + /* FIXME: Verify the max SCK rate */ + slave = spi_setup_slave(CONFIG_LQ035Q1_SPI_BUS, + CONFIG_LQ035Q1_SPI_CS, 20000000, + SPI_MODE_3); + if (!slave) + return -1; + } + + if (spi_claim_bus(slave)) + return -1; + + ret = spi_xfer(slave, 24, regs, dummy, SPI_XFER_BEGIN | SPI_XFER_END); + ret |= spi_xfer(slave, 24, data, dummy, SPI_XFER_BEGIN | SPI_XFER_END); + + spi_release_bus(slave); + + return ret; +} +#endif + /* enable and disable PPI functions */ void EnablePPI(void) { - *pPPI_CONTROL |= PORT_EN; + bfin_write_PPI_CONTROL(bfin_read_PPI_CONTROL() | PORT_EN); } void DisablePPI(void) { - *pPPI_CONTROL &= ~PORT_EN; + bfin_write_PPI_CONTROL(bfin_read_PPI_CONTROL() & ~PORT_EN); } void Init_Ports(void) { - *pPORTF_MUX &= ~PORT_x_MUX_0_MASK; - *pPORTF_MUX |= PORT_x_MUX_0_FUNC_1; - *pPORTF_FER |= PF0 | PF1 | PF2 | PF3 | PF4 | PF5 | PF6 | PF7; - - *pPORTG_MUX &= ~PORT_x_MUX_1_MASK; - *pPORTG_MUX |= PORT_x_MUX_1_FUNC_1; - *pPORTG_FER |= PG5; + const unsigned short pins[] = { + P_PPI0_D0, P_PPI0_D1, P_PPI0_D2, P_PPI0_D3, P_PPI0_D4, + P_PPI0_D5, P_PPI0_D6, P_PPI0_D7, P_PPI0_FS2, 0, + }; + peripheral_request_list(pins, "lcd"); } void Init_PPI(void) { - *pPPI_DELAY = H_START; - *pPPI_COUNT = (H_ACTPIX-1); - *pPPI_FRAME = 0; + bfin_write_PPI_DELAY(H_START); + bfin_write_PPI_COUNT(H_ACTPIX - 1); + bfin_write_PPI_FRAME(V_LINES); /* PPI control, to be replaced with definitions */ - *pPPI_CONTROL = PPI_TX_MODE | /* output mode , PORT_DIR */ + bfin_write_PPI_CONTROL( + PPI_TX_MODE | /* output mode , PORT_DIR */ PPI_XFER_TYPE_11 | /* sync mode XFR_TYPE */ PPI_PORT_CFG_01 | /* two frame sync PORT_CFG */ PPI_PACK_EN | /* packing enabled PACK_EN */ - PPI_POLS_1; /* faling edge syncs POLS */ + PPI_POLS_1 /* faling edge syncs POLS */ + ); } void Init_DMA(void *dst) { - *pDMA0_START_ADDR = dst; + bfin_write_DMA0_START_ADDR(dst); /* X count */ - *pDMA0_X_COUNT = H_ACTPIX / 2; - *pDMA0_X_MODIFY = DMA_BUS_SIZE / 8; + bfin_write_DMA0_X_COUNT(H_ACTPIX / 2); + bfin_write_DMA0_X_MODIFY(DMA_BUS_SIZE / 8); /* Y count */ - *pDMA0_Y_COUNT = V_LINES; - *pDMA0_Y_MODIFY = DMA_BUS_SIZE / 8; + bfin_write_DMA0_Y_COUNT(V_LINES); + bfin_write_DMA0_Y_MODIFY(DMA_BUS_SIZE / 8); /* DMA Config */ - *pDMA0_CONFIG = + bfin_write_DMA0_CONFIG( WDSIZE_16 | /* 16 bit DMA */ DMA2D | /* 2D DMA */ - FLOW_AUTO; /* autobuffer mode */ + FLOW_AUTO /* autobuffer mode */ + ); } - void EnableDMA(void) { - *pDMA0_CONFIG |= DMAEN; + bfin_write_DMA0_CONFIG(bfin_read_DMA0_CONFIG() | DMAEN); } void DisableDMA(void) { - *pDMA0_CONFIG &= ~DMAEN; + bfin_write_DMA0_CONFIG(bfin_read_DMA0_CONFIG() & ~DMAEN); } - /* Init TIMER0 as Frame Sync 1 generator */ void InitTIMER0(void) { - *pTIMER_DISABLE |= TIMDIS0; /* disable Timer */ + bfin_write_TIMER_DISABLE(TIMDIS0); /* disable Timer */ SSYNC(); - *pTIMER_STATUS |= TIMIL0 | TOVF_ERR0 | TRUN0; /* clear status */ + bfin_write_TIMER_STATUS(TIMIL0 | TOVF_ERR0 | TRUN0); /* clear status */ SSYNC(); - *pTIMER0_PERIOD = H_PERIOD; + bfin_write_TIMER0_PERIOD(H_PERIOD); SSYNC(); - *pTIMER0_WIDTH = H_PULSE; + bfin_write_TIMER0_WIDTH(H_PULSE); SSYNC(); - *pTIMER0_CONFIG = PWM_OUT | + bfin_write_TIMER0_CONFIG( + PWM_OUT | PERIOD_CNT | TIN_SEL | CLK_SEL | - EMU_RUN; + EMU_RUN + ); SSYNC(); } void EnableTIMER0(void) { - *pTIMER_ENABLE |= TIMEN0; + bfin_write_TIMER_ENABLE(TIMEN0); SSYNC(); } void DisableTIMER0(void) { - *pTIMER_DISABLE |= TIMDIS0; + bfin_write_TIMER_DISABLE(TIMDIS0); SSYNC(); } void InitTIMER1(void) { - *pTIMER_DISABLE |= TIMDIS1; /* disable Timer */ + bfin_write_TIMER_DISABLE(TIMDIS1); /* disable Timer */ SSYNC(); - *pTIMER_STATUS |= TIMIL1 | TOVF_ERR1 | TRUN1; /* clear status */ + bfin_write_TIMER_STATUS(TIMIL1 | TOVF_ERR1 | TRUN1); /* clear status */ SSYNC(); - - *pTIMER1_PERIOD = V_PERIOD; + bfin_write_TIMER1_PERIOD(V_PERIOD); SSYNC(); - *pTIMER1_WIDTH = V_PULSE; + bfin_write_TIMER1_WIDTH(V_PULSE); SSYNC(); - *pTIMER1_CONFIG = PWM_OUT | + bfin_write_TIMER1_CONFIG( + PWM_OUT | PERIOD_CNT | TIN_SEL | CLK_SEL | - EMU_RUN; + EMU_RUN + ); SSYNC(); } void EnableTIMER1(void) { - *pTIMER_ENABLE |= TIMEN1; + bfin_write_TIMER_ENABLE(TIMEN1); SSYNC(); } void DisableTIMER1(void) { - *pTIMER_DISABLE |= TIMDIS1; + bfin_write_TIMER_DISABLE(TIMDIS1); + SSYNC(); +} + +void EnableTIMER12(void) +{ + bfin_write_TIMER_ENABLE(TIMEN1 | TIMEN0); SSYNC(); } int video_init(void *dst) { +#ifdef CONFIG_BF527_EZKIT_REV_2_1 + lq035q1_control(LQ035_SHUT_CTL, LQ035_ON); + lq035q1_control(LQ035_DRIVER_OUTPUT_CTL, (CONFIG_LQ035Q1_LCD_MODE & + LQ035_DRIVER_OUTPUT_MASK) | LQ035_DRIVER_OUTPUT_DEFAULT); +#endif Init_Ports(); Init_DMA(dst); EnableDMA(); @@ -199,6 +318,9 @@ int video_init(void *dst) Init_PPI(); EnablePPI(); +#ifdef CONFIG_BF527_EZKIT_REV_2_1 + EnableTIMER12(); +#else /* Frame sync 2 (VS) needs to start at least one PPI clk earlier */ EnableTIMER1(); /* Add Some Delay ... */ @@ -209,6 +331,7 @@ int video_init(void *dst) /* now start frame sync 1 */ EnableTIMER0(); +#endif return 0; } @@ -259,6 +382,17 @@ static void dma_bitblit(void *dst, fastimage_t *logo, int x, int y) } +void video_stop(void) +{ + DisablePPI(); + DisableDMA(); + DisableTIMER0(); + DisableTIMER1(); +#ifdef CONFIG_BF527_EZKIT_REV_2_1 + lq035q1_control(LQ035_SHUT_CTL, LQ035_SHUT); +#endif +} + void video_putc(const char c) { }