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); }
static void do_reload(void) { int e = 0; drivers_unload_all(); /* Close all drivers */ config_clear(); clear_settings(); /* Reread command line*/ CHAIN(e, process_command_line(stored_argc, stored_argv)); /* Reread config file */ if (strcmp(configfile, UNSET_STR)==0) strncpy(configfile, DEFAULT_CONFIGFILE, sizeof(configfile)); CHAIN(e, process_configfile(configfile)); /* Set default values */ CHAIN(e, (set_default_settings(), 0)); /* Set reporting values */ CHAIN(e, set_reporting("LCDd", report_level, report_dest)); CHAIN(e, (report(RPT_INFO, "Set report level to %d, output to %s", report_level, ((report_dest == RPT_DEST_SYSLOG) ? "syslog" : "stderr")), 0)); /* And restart the drivers */ CHAIN(e, init_drivers()); CHAIN_END(e, "Critical error while reloading, abort."); }
int main(int argc, char **argv) { int e = 0; pid_t parent_pid = 0; stored_argc = argc; stored_argv = argv; /* * Settings in order of preference: * * 1: Settings specified in command line options... * 2: Settings specified in configuration file... * 3: Default settings * * Because of this, and because one option (-c) specifies where * the configuration file is, things are done in this order: * * 1. Read and set options. * 2. Read configuration file; if option is read in configuration * file and not already set, then set it. * 3. Having read configuration file, if parameter is not set, * set it to the default value. * * It is for this reason that the default values are **NOT** set * in the variable declaration... */ /* Report that server is starting (report will be delayed) */ report(RPT_NOTICE, "LCDd version %s starting", version); report(RPT_INFO, "Built on %s, protocol version %s, API version %s", build_date, protocol_version, api_version); clear_settings(); /* Read command line*/ CHAIN(e, process_command_line(argc, argv)); /* Read config file * If config file was not given on command line use default */ if (strcmp(configfile, UNSET_STR) == 0) strncpy(configfile, DEFAULT_CONFIGFILE, sizeof(configfile)); CHAIN(e, process_configfile(configfile)); /* Set default values*/ set_default_settings(); /* Set reporting settings (will also flush delayed reports) */ set_reporting("LCDd", report_level, report_dest); report(RPT_INFO, "Set report level to %d, output to %s", report_level, ((report_dest == RPT_DEST_SYSLOG) ? "syslog" : "stderr")); CHAIN_END(e, "Critical error while processing settings, abort."); /* Now, go into daemon mode (if we should)... * We wait for the child to report it is running OK. This mechanism * is used because forking after starting the drivers causes the * child to loose the (LPT) port access. */ if (!foreground_mode) { report(RPT_INFO, "Server forking to background"); CHAIN(e, parent_pid = daemonize()); } else { output_GPL_notice(); report(RPT_INFO, "Server running in foreground"); } install_signal_handlers(!foreground_mode); /* Only catch SIGHUP if not in foreground mode */ /* Startup the subparts of the server */ CHAIN(e, sock_init(bind_addr, bind_port)); CHAIN(e, screenlist_init()); CHAIN(e, init_drivers()); CHAIN(e, clients_init()); CHAIN(e, input_init()); CHAIN(e, menuscreens_init()); CHAIN(e, server_screen_init()); CHAIN_END(e, "Critical error while initializing, abort."); if (!foreground_mode) { /* Tell to parent that startup went OK. */ wave_to_parent(parent_pid); } drop_privs(user); /* This can't be done before, because sending a signal to a process of a different user will fail */ do_mainloop(); /* This loop never stops; we'll get out only with a signal...*/ return 0; }