Exemple #1
0
void lcd_init_device(void)
{
    semaphore_init(&g_wait_sema, 1, 0);
    /* I'm not really sure this pin is related to power, it does not seem to do anything */
    imx233_pinctrl_acquire(1, 8, "lcd_power");
    imx233_pinctrl_acquire(1, 9, "lcd_spi_sdo");
    imx233_pinctrl_acquire(1, 10, "lcd_spi_scl");
    imx233_pinctrl_acquire(1, 11, "lcd_spi_cs");
    imx233_pinctrl_set_function(1, 9, PINCTRL_FUNCTION_GPIO);
    imx233_pinctrl_set_function(1, 10, PINCTRL_FUNCTION_GPIO);
    imx233_pinctrl_set_function(1, 11, PINCTRL_FUNCTION_GPIO);
    imx233_pinctrl_set_function(1, 8, PINCTRL_FUNCTION_GPIO);
    imx233_pinctrl_enable_gpio(1, 8, true);
    /** lcd is 320x240, data bus is 8-bit, depth is 24-bit so we need 3clk/pix
     * by running PIX clock at 24MHz we can sustain ~100 fps */
    imx233_clkctrl_enable(CLK_PIX, false);
    imx233_clkctrl_set_div(CLK_PIX, 2);
    imx233_clkctrl_set_bypass(CLK_PIX, true); /* use XTAL */
    imx233_clkctrl_enable(CLK_PIX, true);
    imx233_lcdif_init();
    imx233_lcdif_setup_dotclk_pins(8, false);
    imx233_lcdif_set_word_length(8);
    imx233_lcdif_set_underflow_cb(&lcd_underflow);
    imx233_lcdif_enable_underflow_irq(true);
    imx233_dma_clkgate_channel(APB_LCDIF, true);
    imx233_dma_reset_channel(APB_LCDIF);
    /** Datasheet states:
     * 257H >= VBP >= 3H, VBP > VLW, VFP >= 1H
     * 1533clk >= HBP >= 24clk, HBP > HLW, HFP >= 4clk
     * 
     * Take VLW=1H, VBP=3H, VFP=1H, HLW=8, HBP=24, HFP=4
     * Take 3clk/pix because we send 24-bit/pix with 8-bit data bus
     * Keep consistent with register setting in lcd_init_seq
     */
    imx233_lcdif_setup_dotclk_ex(/*v_pulse_width*/1, /*v_back_porch*/3,
        /*v_front_porch*/1, /*h_pulse_width*/8, /*h_back_porch*/24,
        /*h_front_porch*/4, LCD_WIDTH, LCD_HEIGHT, /*clk_per_pix*/3,
        /*enable_present*/false);
    imx233_lcdif_set_byte_packing_format(0xf);
    imx233_lcdif_enable_sync_signals(true); // we need frame signals during init
    // setup dma
    unsigned size = IMX233_FRAMEBUFFER_SIZE;
    uint8_t *frame_p = FRAME;
    for(int i = 0; i < NR_CMDS; i++)
    {
        unsigned xfer = MIN(IMX233_MAX_SINGLE_DMA_XFER_SIZE, size);
        lcdif_dma[i].dma.next = &lcdif_dma[(i + 1) % NR_CMDS].dma;
        lcdif_dma[i].dma.cmd = BF_OR3(APB_CHx_CMD, CHAIN(1),
            COMMAND(BV_APB_CHx_CMD_COMMAND__READ), XFER_COUNT(xfer));
        lcdif_dma[i].dma.buffer =  frame_p;
        size -= xfer;
        frame_p += xfer;
    }
    // first transfer: enable run, dotclk and so on
    lcdif_dma[0].dma.cmd |= BF_OR1(APB_CHx_CMD, CMDWORDS(1));
    lcdif_dma[0].ctrl = BF_OR4(LCDIF_CTRL, BYPASS_COUNT(1), DOTCLK_MODE(1),
        RUN(1), WORD_LENGTH(1));
    // enable
    lcd_enable(true);
}
Exemple #2
0
void imx233_digctl_set_arm_cache_timings(unsigned timings)
{
#if IMX233_SUBTARGET >= 3780
    HW_DIGCTL_ARMCACHE = BF_OR5(DIGCTL_ARMCACHE, ITAG_SS(timings),
        DTAG_SS(timings), CACHE_SS(timings), DRTY_SS(timings), VALID_SS(timings));
#else
    HW_DIGCTL_ARMCACHE = BF_OR3(DIGCTL_ARMCACHE, ITAG_SS(timings),
        DTAG_SS(timings), CACHE_SS(timings));
#endif
}
Exemple #3
0
/* volume in half dB
 * don't check input values */
static void set_dac_vol(int vol_l, int vol_r)
{
    /* minimum is -100dB and max is 0dB */
    vol_l = MAX(-200, MIN(vol_l, 0));
    vol_r = MAX(-200, MIN(vol_r, 0));
    /* unmute, enable zero cross and set volume.
     * 0xff is 0dB */
    HW_AUDIOOUT_DACVOLUME = BF_OR3(AUDIOOUT_DACVOLUME,
        VOLUME_LEFT(0xff + vol_l), VOLUME_RIGHT(0xff + vol_r), EN_ZCD(1));
}
Exemple #4
0
void imx233_lcdif_setup_dotclk(unsigned v_pulse_width, unsigned v_period,
    unsigned v_wait_cnt, unsigned v_active, unsigned h_pulse_width,
    unsigned h_period, unsigned h_wait_cnt, unsigned h_active, bool enable_present)
{
    HW_LCDIF_VDCTRL0 = BF_OR4(LCDIF_VDCTRL0, ENABLE_PRESENT(enable_present),
        VSYNC_PERIOD_UNIT(1), VSYNC_PULSE_WIDTH_UNIT(1),
         DOTCLK_V_VALID_DATA_CNT(v_active));
    HW_LCDIF_VDCTRL1 = BF_OR2(LCDIF_VDCTRL1, VSYNC_PERIOD(v_period),
        VSYNC_PULSE_WIDTH(v_pulse_width));
    HW_LCDIF_VDCTRL2 = BF_OR3(LCDIF_VDCTRL2, HSYNC_PULSE_WIDTH(h_pulse_width),
        HSYNC_PERIOD(h_period), DOTCLK_H_VALID_DATA_CNT(h_active));
    HW_LCDIF_VDCTRL3 = BF_OR2(LCDIF_VDCTRL3, VERTICAL_WAIT_CNT(v_wait_cnt),
        HORIZONTAL_WAIT_CNT(h_wait_cnt));
    // setup dotclk mode, always bypass count, apparently data select is needed
    HW_LCDIF_CTRL_SET = BM_OR3(LCDIF_CTRL, DOTCLK_MODE, BYPASS_COUNT, DATA_SELECT);
}
Exemple #5
0
/* volume in half dB
 * don't check input values */
static void set_hp_vol(int vol_l, int vol_r)
{
    /* minimum is -57.5dB and max is 6dB in DAC mode
     * and -51.5dB / 12dB in Line1 mode */
    int min = input_line1 ? -103 : -115;
    int max = input_line1 ? 24 : 12;

    vol_l = MAX(min, MIN(vol_l, max));
    vol_r = MAX(min, MIN(vol_r, max));
    /* unmute, enable zero cross and set volume.*/
#if IMX233_SUBTARGET >= 3700
    unsigned mstr_zcd = BM_AUDIOOUT_HPVOL_EN_MSTR_ZCD;
#else
    unsigned mstr_zcd = 0;
#endif
    HW_AUDIOOUT_HPVOL = mstr_zcd | BF_OR3(AUDIOOUT_HPVOL, SELECT(input_line1),
        VOL_LEFT(max - vol_l), VOL_RIGHT(max - vol_r));
}