void init_structures(memory_c *main_memory) // please modify init_structures function argument  /** NEW-LAB2 */ 
{
  init_op_pool(); 
  init_op_latency();
  init_latches();
  init_registers(); // initializing processor registers to TRUE since no data dependency when processor is powered on
  main_memory->init_mem(); // initializing DRAM and MSHR
  cache_init(data_cache, KNOB(KNOB_DCACHE_SIZE)->getValue(), KNOB(KNOB_BLOCK_SIZE)->getValue(), KNOB(KNOB_DCACHE_WAY)->getValue(), "L1 Cache"); // initializing cache
}
Example #2
0
void
initialize_low (void)
{
  using_threads = 0;
  set_target_ops (&fbsd_target_ops);
  set_breakpoint_data (the_low_target.breakpoint,
		       the_low_target.breakpoint_len);
  init_registers ();
  fbsd_init_signals ();
}
/* Step 3: Work forwards once again.  Perform register allocations,
 * taking into account instructions like TEX which require contiguous
 * result registers.  Where necessary spill registers to scratch space
 * and reload later.
 */
void brw_wm_pass2( struct brw_wm_compile *c )
{
   GLuint insn;
   GLuint i;

   init_registers(c);

   for (insn = 0; insn < c->nr_insns; insn++) {
      struct brw_wm_instruction *inst = &c->instruction[insn];

      /* Update registers' nextuse values:
       */
      update_register_usage(c, insn);

      /* May need to unspill some args.
       */
      load_args(c, inst);

      /* Allocate registers to hold results:
       */
      switch (inst->opcode) {
      case TGSI_OPCODE_TEX:
      case TGSI_OPCODE_TXB:
      case TGSI_OPCODE_TXP:
	 alloc_contiguous_dest(c, inst->dst, 4, insn);
	 break;

      default:
	 for (i = 0; i < 4; i++) {
	    if (inst->writemask & (1<<i)) {
	       assert(inst->dst[i]);
	       alloc_contiguous_dest(c, &inst->dst[i], 1, insn);
	    }
	 }
	 break;
      }

      if (TEST_DST_SPILLS && inst->opcode != WM_PIXELXY) {
	 for (i = 0; i < 4; i++)	
	    if (inst->dst[i])
	       spill_value(c, inst->dst[i]);
      }
   }

   if (BRW_DEBUG & DEBUG_WM) {
      brw_wm_print_program(c, "pass2");
   }

   c->state = PASS2_DONE;

   if (BRW_DEBUG & DEBUG_WM) {
       brw_wm_print_program(c, "pass2/done");
   }
}
Example #4
0
static void tx_timeout(struct net_device *dev)
{
	struct netdev_private *np = (struct netdev_private *)dev->priv;
	long ioaddr = dev->base_addr;

	printk(KERN_WARNING "%s: Transmit timed out, status %8.8x,"
		   " resetting...\n", dev->name, (int)readl(ioaddr + IntrStatus));

#ifndef __alpha__
	{
		int i;
		printk(KERN_DEBUG "  Rx ring %8.8x: ", (int)np->rx_ring);
		for (i = 0; i < RX_RING_SIZE; i++)
			printk(" %8.8x", (unsigned int)np->rx_ring[i].status);
		printk("\n"KERN_DEBUG"  Tx ring %8.8x: ", (int)np->tx_ring);
		for (i = 0; i < TX_RING_SIZE; i++)
			printk(" %8.8x", np->tx_ring[i].status);
		printk("\n");
	}
	printk(KERN_DEBUG "Tx cur %d Tx dirty %d Tx Full %d, q bytes %d.\n",
				np->cur_tx, np->dirty_tx, np->tx_full,np->tx_q_bytes);
	printk(KERN_DEBUG "Tx Descriptor addr %xh.\n",readl(ioaddr+0x4C));

#endif
	spin_lock_irq(&np->lock);
	/*
	 * Under high load dirty_tx and the internal tx descriptor pointer
	 * come out of sync, thus perform a software reset and reinitialize
	 * everything.
	 */

	writel(1, dev->base_addr+PCIBusCfg);
	udelay(1);

	free_rxtx_rings(np);
	init_rxtx_rings(dev);
	init_registers(dev);
	set_rx_mode(dev);

	spin_unlock_irq(&np->lock);

	netif_wake_queue(dev);
	dev->trans_start = jiffies;
	np->stats.tx_errors++;
	return;
}
Example #5
0
/* Initializes data structures and registers for the controller,
 * and brings the interface up.	 Returns the link status, meaning
 * that it returns success if the link is up, failure otherwise.
 * This allows u-boot to find the first active controller.
 */
static int tsec_init(struct eth_device *dev, bd_t * bd)
{
	uint tempval;
	char tmpbuf[MAC_ADDR_LEN];
	int i;
	struct tsec_private *priv = (struct tsec_private *)dev->priv;
	tsec_t *regs = priv->regs;

	/* Make sure the controller is stopped */
	tsec_halt(dev);

	/* Init MACCFG2.  Defaults to GMII */
	out_be32(&regs->maccfg2, MACCFG2_INIT_SETTINGS);

	/* Init ECNTRL */
	out_be32(&regs->ecntrl, ECNTRL_INIT_SETTINGS);

	/* Copy the station address into the address registers.
	 * Backwards, because little endian MACS are dumb */
	for (i = 0; i < MAC_ADDR_LEN; i++)
		tmpbuf[MAC_ADDR_LEN - 1 - i] = dev->enetaddr[i];

	tempval = (tmpbuf[0] << 24) | (tmpbuf[1] << 16) | (tmpbuf[2] << 8) |
		  tmpbuf[3];

	out_be32(&regs->macstnaddr1, tempval);

	tempval = *((uint *) (tmpbuf + 4));

	out_be32(&regs->macstnaddr2, tempval);

	/* Clear out (for the most part) the other registers */
	init_registers(regs);

	/* Ready the device for tx/rx */
	startup_tsec(dev);

	/* Start up the PHY */
	phy_startup(priv->phydev);

	adjust_link(priv, priv->phydev);

	/* If there's no link, fail */
	return priv->phydev->link ? 0 : -1;
}
Example #6
0
void __init os_early_checks(void)
{
	int pid;

	/* Print out the core dump limits early */
	check_coredump_limit();

	check_ptrace();

	/* Need to check this early because mmapping happens before the
	 * kernel is running.
	 */
	check_tmpexec();

	pid = start_ptraced_child();
	if (init_registers(pid))
		fatal("Failed to initialize default registers");
	stop_ptraced_child(pid, 1, 1);
}
Example #7
0
int main(int argc, char *argv[]) {
    init_registers();
    init_memory();

    printf(">> Begin 6502 emulation\n");
    printf("SP: 0x%X\n", get_full_SP());
    printf("Execute instruction DEX\n");
    instr_dex();
    printf("X: %d\n", reg_X.data);
    printf("A: %d\n", reg_A.data);
    printf("Execute instruction TXA\n");
    instr_txa();
    printf("X: %d\n", reg_X.data);
    printf("A: %d\n", reg_A.data);
    printf("Execute instruction LDA #$42\n");
    instr_lda(42, IMMEDIATE);
    printf("X: %d\n", reg_X.data);
    printf("A: %d\n", reg_A.data);
    return 0;
}
Example #8
0
void init_debugger()
{
	debugger_mode = 1;
	run = 0;

//]=-=-=[ Initialisation des Couleurs ]=-=-=[
	color_modif.red = 0x0000;
	color_modif.green = 0xA000;
	color_modif.blue = 0xFFFF;

	color_ident.red = 0xFFFF;
	color_ident.green = 0xFFFF;
	color_ident.blue = 0xFFFF;

	init_registers();
	init_desasm();
	init_breakpoints();
	//init_TLBwindow();

	pthread_mutex_init( &mutex, NULL);
	pthread_cond_init( &debugger_done_cond, NULL);
}
Example #9
0
static int nic_open(struct net_device *dev)
{
	struct nic_private *np = netdev_priv(dev);
	int rc;
	printk("In Open...");

	/* register isr */
	rc=request_irq(np->irq,nic_interrupt,IRQF_SHARED,dev->name,(void*)dev);
	if (rc)
		return rc;	

	/*allocate ring buffer for received packets*/
        np->rxbuf = pci_alloc_consistent(np->pdev,RX_BUF_LEN,&np->rxring_dma);
	if (!np->rxbuf) {
		printk(KERN_ERR "Could not allocate DMA memory.\n");
		return -ENOMEM;
	}

	/*allocate memory for trasmission packets*/
	np->txbuf = pci_alloc_consistent(np->pdev,TX_BUF_LEN,&np->txbuf_dma);
	if(!np->txbuf){
		printk(KERN_ERR "Could not allocate DMA memory.\n");
		return -ENOMEM;
	}

	np->txcount=0;
	np->rxcount=0;
	np->rxdroped=0;
	np->txdroped=0;

	nic_reset_chip(dev);
	init_registers(dev);


	netif_start_queue(dev);
	return 0;

}
Example #10
0
status_t
detect_displays()
{
    // reset known displays
    for (uint32 id = 0; id < MAX_DISPLAY; id++) {
        gDisplay[id]->attached = false;
        gDisplay[id]->powered = false;
        gDisplay[id]->foundRanges = false;
    }

    uint32 displayIndex = 0;
    for (uint32 id = 0; id < ATOM_MAX_SUPPORTED_DEVICE; id++) {
        if (gConnector[id]->valid == false)
            continue;
        if (displayIndex >= MAX_DISPLAY)
            continue;

        if (gConnector[id]->type == VIDEO_CONNECTOR_9DIN) {
            TRACE("%s: connector(%" B_PRIu32 "): Skipping 9DIN connector "
                  "(not yet supported)\n", __func__, id);
            continue;
        }

        if (gConnector[id]->type == VIDEO_CONNECTOR_DP) {
            TRACE("%s: connector(%" B_PRIu32 "): Checking DP.\n", __func__, id);

            edid1_info* edid = &gDisplay[displayIndex]->edidData;
            gDisplay[displayIndex]->attached
                = ddc2_dp_read_edid1(id, edid);

            if (gDisplay[displayIndex]->attached) {
                TRACE("%s: connector(%" B_PRIu32 "): Found DisplayPort EDID!\n",
                      __func__);
            }
        }

        // TODO: Handle external DP brides - ??
#if 0
        if (gConnector[id]->encoderExternal.isDPBridge == true) {
            // If this is a DisplayPort Bridge, setup ddc on bus
            // TRAVIS (LVDS) or NUTMEG (VGA)
            TRACE("%s: is bridge, performing bridge DDC setup\n", __func__);
            encoder_external_setup(id, 23860,
                                   EXTERNAL_ENCODER_ACTION_V3_DDC_SETUP);
            gDisplay[displayIndex]->attached = true;

            // TODO: DDC Router switching for DisplayPort (and others?)
        }
#endif

        if (gConnector[id]->type == VIDEO_CONNECTOR_LVDS) {
            display_mode preferredMode;
            bool lvdsInfoFound = connector_read_mode_lvds(id,
                                 &preferredMode);
            TRACE("%s: connector(%" B_PRIu32 "): bit-banging LVDS for EDID.\n",
                  __func__, id);

            gDisplay[displayIndex]->attached = connector_read_edid(id,
                                               &gDisplay[displayIndex]->edidData);

            if (!gDisplay[displayIndex]->attached && lvdsInfoFound) {
                // If we didn't find ddc edid data, fallback to lvdsInfo
                // We have to call connector_read_mode_lvds first to
                // collect SS data for the lvds connector
                TRACE("%s: connector(%" B_PRIu32 "): using AtomBIOS LVDS_Info "
                      "preferred mode\n", __func__, id);
                gDisplay[displayIndex]->attached = true;
                memcpy(&gDisplay[displayIndex]->preferredMode,
                       &preferredMode, sizeof(display_mode));
            }
        }

        // If no display found yet, try more standard detection methods
        if (gDisplay[displayIndex]->attached == false) {
            TRACE("%s: connector(%" B_PRIu32 "): bit-banging ddc for EDID.\n",
                  __func__, id);

            // Bit-bang edid from connector
            gDisplay[displayIndex]->attached = connector_read_edid(id,
                                               &gDisplay[displayIndex]->edidData);

            // Found EDID data?
            if (gDisplay[displayIndex]->attached) {
                TRACE("%s: connector(%" B_PRIu32 "): found EDID data.\n",
                      __func__, id);

                if (gConnector[id]->type == VIDEO_CONNECTOR_DVII
                        || gConnector[id]->type == VIDEO_CONNECTOR_HDMIB) {
                    // These connectors can share gpio pins for data
                    // communication between digital and analog encoders
                    // (DVI-I is most common)
                    edid1_info* edid = &gDisplay[displayIndex]->edidData;

                    bool analogEncoder
                        = gConnector[id]->encoder.type == VIDEO_ENCODER_TVDAC
                          || gConnector[id]->encoder.type == VIDEO_ENCODER_DAC;
                    bool digitalEncoder
                        = gConnector[id]->encoder.type == VIDEO_ENCODER_TMDS;

                    bool digitalEdid = edid->display.input_type ? true : false;

                    if (digitalEdid && analogEncoder) {
                        // Digital EDID + analog encoder? Lets try a load test
                        gDisplay[displayIndex]->attached
                            = encoder_analog_load_detect(id);
                    } else if (!digitalEdid && digitalEncoder) {
                        // non-digital EDID + digital encoder? Nope.
                        gDisplay[displayIndex]->attached = false;
                    }

                    // Else... everything aligns as it should and attached = 1
                }
            }
        }

        if (gDisplay[displayIndex]->attached != true) {
            // Nothing interesting here, move along
            continue;
        }

        // We found a valid / attached display

        gDisplay[displayIndex]->connectorIndex = id;
        // Populate physical connector index from gConnector

        init_registers(gDisplay[displayIndex]->regs, displayIndex);

        if (gDisplay[displayIndex]->preferredMode.virtual_width > 0) {
            // Found a single preferred mode
            gDisplay[displayIndex]->foundRanges = false;
        } else {
            // Use edid data and pull ranges
            if (detect_crt_ranges(displayIndex) == B_OK)
                gDisplay[displayIndex]->foundRanges = true;
        }

        displayIndex++;
    }

    // fallback if no attached monitors were found
    if (displayIndex == 0) {
        // This is a hack, however as we don't support HPD just yet,
        // it tries to prevent a "no displays" situation.
        ERROR("%s: ERROR: 0 attached monitors were found on display connectors."
              " Injecting first connector as a last resort.\n", __func__);
        for (uint32 id = 0; id < ATOM_MAX_SUPPORTED_DEVICE; id++) {
            // skip TV DAC connectors as likely fallback isn't for TV
            if (gConnector[id]->encoder.type == VIDEO_ENCODER_TVDAC)
                continue;
            gDisplay[0]->attached = true;
            gDisplay[0]->connectorIndex = id;
            init_registers(gDisplay[0]->regs, 0);
            if (detect_crt_ranges(0) == B_OK)
                gDisplay[0]->foundRanges = true;
            break;
        }
    }

    // Initial boot state is the first two crtc's powered
    if (gDisplay[0]->attached == true)
        gDisplay[0]->powered = true;
    if (gDisplay[1]->attached == true)
        gDisplay[1]->powered = true;

    return B_OK;
}
Example #11
0
int
main(int argc, char *argv[])
{
	/* TODO: refactor main() function */

	char dir[PATH_MAX];
	char lwin_path[PATH_MAX] = "";
	char rwin_path[PATH_MAX] = "";
	int lwin_handle = 0, rwin_handle = 0;
	int old_config;
	int no_configs;

	init_config();

	if(is_in_string_array(argv + 1, argc - 1, "--logging"))
	{
		init_logger(1);
	}

	(void)setlocale(LC_ALL, "");
	if(getcwd(dir, sizeof(dir)) == NULL)
	{
		perror("getcwd");
		return -1;
	}
#ifdef _WIN32
	to_forward_slash(dir);
#endif

	init_filelists();
	init_registers();
	set_config_paths();
	reinit_logger();

	init_commands();
	init_builtin_functions();
	update_path_env(1);

	if(init_status() != 0)
	{
		puts("Error during session status initialization.");
		return -1;
	}

	no_configs = is_in_string_array(argv + 1, argc - 1, "--no-configs");

	/* Tell file type module what function to use to check availability of
	 * external programs. */
	config_filetypes(&external_command_exists);
	/* This should be called before loading any configuration file. */
	reset_all_file_associations(curr_stats.env_type == ENVTYPE_EMULATOR_WITH_X);

	init_option_handlers();

	old_config = is_old_config();
	if(!old_config && !no_configs)
		read_info_file(0);

	ipc_pre_init();

	parse_args(argc, argv, dir, lwin_path, rwin_path, &lwin_handle, &rwin_handle);

	ipc_init(&parse_recieved_arguments);

	init_background();

	set_view_path(&lwin, lwin_path);
	set_view_path(&rwin, rwin_path);

	/* Force view switch when path is specified for invisible pane. */
	if(lwin_path[0] != '\0' && rwin_path[0] == '\0' && curr_view != &lwin)
	{
		change_window();
	}

	load_initial_directory(&lwin, dir);
	load_initial_directory(&rwin, dir);

	/* Force split view when two paths are specified on command-line. */
	if(lwin_path[0] != '\0' && rwin_path[0] != '\0')
	{
		curr_stats.number_of_windows = 2;
	}

	/* Setup the ncurses interface. */
	if(!setup_ncurses_interface())
		return -1;

	colmgr_init(COLOR_PAIRS);
	init_modes();
	init_undo_list(&perform_operation, NULL, &cfg.undo_levels);
	load_local_options(curr_view);

	curr_stats.load_stage = 1;

	if(!old_config && !no_configs)
	{
		load_scheme();
		source_config();
	}

	write_color_scheme_file();
	setup_signals();

	if(old_config && !no_configs)
	{
		convert_configs();

		curr_stats.load_stage = 0;
		read_info_file(0);
		curr_stats.load_stage = 1;

		set_view_path(&lwin, lwin_path);
		set_view_path(&rwin, rwin_path);

		load_initial_directory(&lwin, dir);
		load_initial_directory(&rwin, dir);

		source_config();
	}

	(void)create_trash_dir(cfg.trash_dir);

	check_path_for_file(&lwin, lwin_path, lwin_handle);
	check_path_for_file(&rwin, rwin_path, rwin_handle);

	curr_stats.load_stage = 2;

	exec_startup_commands(argc, argv);
	update_screen(UT_FULL);
	modes_update();

	/* Update histories of the views to ensure that their current directories,
	 * which might have been set using command-line parameters, are stored in the
	 * history.  This is not done automatically as history manipulation should be
	 * postponed until views are fully loaded, otherwise there is no correct
	 * information about current file and relative cursor position. */
	save_view_history(&lwin, NULL, NULL, -1);
	save_view_history(&rwin, NULL, NULL, -1);

	curr_stats.load_stage = 3;

	main_loop();

	return 0;
}
Example #12
0
void cNRF24L01::init(HAL *_hal, dir_t dir, uint8_t addr, uint8_t channel, hal_spi_c *_SPI)
{
    hal = _hal;
	address_width_t addr_width = RF24_ADDR_5_BYTES;
	
    this->channel = channel;
	this->addr_size = addr_width + 2;
	this->addr = BASE_ADDR + addr;
	this->payload_size = 10;
	this->dynamic_payload = 1;
	this->dir = dir;

	/*PWR_.init(&hw_conf.pwr);
	IRQ.init(&hw_conf.irq);
	CE.init(&hw_conf.ce);*/
    hal->gpio->init(SPI1_PINS_RCC, SPI1_PINS_PORT, SPI1_PWR, GPIO_Mode_OUT);
    hal->gpio->init(SPI1_CE_PIN_RCC, SPI1_CE_PIN_PORT, SPI1_CE, GPIO_Mode_OUT);        
    hal->gpio->init(SPI1_PINS_RCC, SPI1_PINS_PORT, SPI1_IRQ, GPIO_Mode_IN);
	init_registers(_SPI);

	// Turn on RF24 - defaults, standby-I mode
    hal->gpio->set(SPI1_PINS_PORT, SPI1_PWR, PIN_HIGH);
    hal->gpio->set(SPI1_CE_PIN_PORT, SPI1_CE, PIN_LOW);
	//PWR_.set(PIN_HIGH);
	//CE.set(PIN_LOW);
	// XXX fixme delay(5, msec_1);
	power_mode_set(RF24_PWR_DOWN, RF24_DIR_TX);

//#define RF_DEBUG_INIT
#ifdef RF_DEBUG_INIT
    volatile uint64_t tmp = 0;
#endif
    // Enable CRC
	CRC_len_set(RF24_CRC_16);
#ifdef RF_DEBUG_INIT
	tmp = config.read();// CONFIG = 0x0C
#endif
	// Answer if msg recieved on P0 addr
    auto_ack_enable(RF24_AUTO_ACK_P0);
#ifdef RF_DEBUG_INIT
    tmp = en_aa.read(); // EN_AA = 0x01
#endif
    // Enable P0 addr for RX
    enable_rx_address(RF24_AUTO_ACK_P0);
#ifdef RF_DEBUG_INIT
    tmp = en_rxaddr.read(); //RX_ADDR = 0x01
#endif
    // Addressing width 4 bytes
    address_width_set(addr_width);
#ifdef RF_DEBUG_INIT
    tmp = setup_aw.read(); //SETUP_AW = 0x02 - 4 bytes
#endif
    // Set retries
    retry_mode_set(RF24_RETR_COUNT_5, RF24_RETR_DELAY_500);
#ifdef RF_DEBUG_INIT
    tmp = setup_retr.read(); //SETUP_RETR = 0x2A
#endif
    // Default channel #2, set 1 !!!
    channel_set((rf_channel_t)this->channel);
#ifdef RF_DEBUG_INIT
    tmp = rf_ch.read(); // 0x02
#endif
    rf_setup_set(RF24_1MBPS, RF24_PA_MAX);
#ifdef RF_DEBUG_INIT
    tmp = rf_setup.read(); // RF_SETUP = 0x07
#endif
    tx_addr_set(addr);
#ifdef RF_DEBUG_INIT
    tx_addr.read((uint8_t*)(&tmp), this->addr_size);
#endif
    rx_addr_set(addr, RF24_AUTO_ACK_P0);
#ifdef RF_DEBUG_INIT
    rx_addr_p0.read((uint8_t*)(&tmp), this->addr_size);
#endif
			payload_size_set(this->payload_size);
#ifdef RF_DEBUG_INIT
    tmp = rx_pw_p0.read();
#endif
    if (!this->dynamic_payload)
    {
    	dyn_pd.write(0);
    	feature.write(0);
    }
		else
    {
        feature_setup();
		}
    // Reset current IRQ status
    irq_status_reset();

    // Flush buffers
    config.flush(RX_BUFF);
    config.flush(TX_BUFF);
}
Example #13
0
status_t
detect_displays()
{
	// reset known displays
	for (uint32 id = 0; id < MAX_DISPLAY; id++) {
		gDisplay[id]->attached = false;
		gDisplay[id]->powered = false;
		gDisplay[id]->foundRanges = false;
	}

	uint32 displayIndex = 0;
	for (uint32 id = 0; id < ATOM_MAX_SUPPORTED_DEVICE; id++) {
		if (gConnector[id]->valid == false)
			continue;
		if (displayIndex >= MAX_DISPLAY)
			continue;

		if (gConnector[id]->type == VIDEO_CONNECTOR_9DIN) {
			TRACE("%s: Skipping 9DIN connector (not yet supported)\n",
				__func__);
			continue;
		}

		// TODO: As DP aux transactions don't work yet, just use LVDS as a hack
		#if 0
		if (gConnector[id]->encoderExternal.isDPBridge == true) {
			// If this is a DisplayPort Bridge, setup ddc on bus
			// TRAVIS (LVDS) or NUTMEG (VGA)
			TRACE("%s: is bridge, performing bridge DDC setup\n", __func__);
			encoder_external_setup(id, 23860,
				EXTERNAL_ENCODER_ACTION_V3_DDC_SETUP);
			gDisplay[displayIndex]->attached = true;
		} else if (gConnector[id]->type == VIDEO_CONNECTOR_LVDS) {
		#endif
		if (gConnector[id]->type == VIDEO_CONNECTOR_LVDS) {
			// If plain (non-DP) laptop LVDS, read mode info from AtomBIOS
			//TRACE("%s: non-DP laptop LVDS detected\n", __func__);
			gDisplay[displayIndex]->attached
				= connector_read_mode_lvds(id,
					&gDisplay[displayIndex]->preferredMode);
		}

		// If no display found yet, try more standard detection methods
		if (gDisplay[displayIndex]->attached == false) {
			TRACE("%s: bit-banging ddc for EDID on connector %" B_PRIu32 "\n",
				__func__, id);

			// Lets try bit-banging edid from connector
			gDisplay[displayIndex]->attached
				= connector_read_edid(id, &gDisplay[displayIndex]->edidData);

			// Since DVI-I shows up as two connectors, and there is only one
			// edid channel, we have to make *sure* the edid data received is
			// valid for te connector.

			// Found EDID data?
			if (gDisplay[displayIndex]->attached) {
				TRACE("%s: found EDID data on connector %" B_PRIu32 "\n",
					__func__, id);

				bool analogEncoder
					= gConnector[id]->encoder.type == VIDEO_ENCODER_TVDAC
					|| gConnector[id]->encoder.type == VIDEO_ENCODER_DAC;

				edid1_info* edid = &gDisplay[displayIndex]->edidData;
				if (!edid->display.input_type && analogEncoder) {
					// If non-digital EDID + the encoder is analog...
					TRACE("%s: connector %" B_PRIu32 " has non-digital EDID "
						"and a analog encoder.\n", __func__, id);
					gDisplay[displayIndex]->attached
						= encoder_analog_load_detect(id);
				} else if (edid->display.input_type && !analogEncoder) {
					// If EDID is digital, we make an assumption here.
					TRACE("%s: connector %" B_PRIu32 " has digital EDID "
						"and is not a analog encoder.\n", __func__, id);
				} else {
					// This generally means the monitor is of poor design
					// Since we *know* there is no load on the analog encoder
					// we assume that it is a digital display.
					TRACE("%s: Warning: monitor on connector %" B_PRIu32 " has "
						"false digital EDID flag and unloaded analog encoder!\n",
						__func__, id);
				}
			}
		}

		if (gDisplay[displayIndex]->attached != true) {
			// Nothing interesting here, move along
			continue;
		}

		// We found a valid / attached display

		gDisplay[displayIndex]->connectorIndex = id;
			// Populate physical connector index from gConnector

		init_registers(gDisplay[displayIndex]->regs, displayIndex);

		if (gDisplay[displayIndex]->preferredMode.virtual_width > 0) {
			// Found a single preferred mode
			gDisplay[displayIndex]->foundRanges = false;
		} else {
			// Use edid data and pull ranges
			if (detect_crt_ranges(displayIndex) == B_OK)
				gDisplay[displayIndex]->foundRanges = true;
		}

		displayIndex++;
	}

	// fallback if no attached monitors were found
	if (displayIndex == 0) {
		// This is a hack, however as we don't support HPD just yet,
		// it tries to prevent a "no displays" situation.
		ERROR("%s: ERROR: 0 attached monitors were found on display connectors."
			" Injecting first connector as a last resort.\n", __func__);
		for (uint32 id = 0; id < ATOM_MAX_SUPPORTED_DEVICE; id++) {
			// skip TV DAC connectors as likely fallback isn't for TV
			if (gConnector[id]->encoder.type == VIDEO_ENCODER_TVDAC)
				continue;
			gDisplay[0]->attached = true;
			gDisplay[0]->connectorIndex = id;
			init_registers(gDisplay[0]->regs, 0);
			if (detect_crt_ranges(0) == B_OK)
				gDisplay[0]->foundRanges = true;
			break;
		}
	}

	// Initial boot state is the first two crtc's powered
	if (gDisplay[0]->attached == true)
		gDisplay[0]->powered = true;
	if (gDisplay[1]->attached == true)
		gDisplay[1]->powered = true;

	return B_OK;
}


void
debug_displays()
{
	TRACE("Currently detected monitors===============\n");
	for (uint32 id = 0; id < MAX_DISPLAY; id++) {
		ERROR("Display #%" B_PRIu32 " attached = %s\n",
			id, gDisplay[id]->attached ? "true" : "false");

		uint32 connectorIndex = gDisplay[id]->connectorIndex;

		if (gDisplay[id]->attached) {
			uint32 connectorType = gConnector[connectorIndex]->type;
			uint32 encoderType = gConnector[connectorIndex]->encoder.type;
			ERROR(" + connector ID:   %" B_PRIu32 "\n", connectorIndex);
			ERROR(" + connector type: %s\n", get_connector_name(connectorType));
			ERROR(" + encoder type:   %s\n", get_encoder_name(encoderType));
			ERROR(" + limits: Vert Min/Max: %" B_PRIu32 "/%" B_PRIu32"\n",
				gDisplay[id]->vfreqMin, gDisplay[id]->vfreqMax);
			ERROR(" + limits: Horz Min/Max: %" B_PRIu32 "/%" B_PRIu32"\n",
				gDisplay[id]->hfreqMin, gDisplay[id]->hfreqMax);
		}
	}
	TRACE("==========================================\n");
}
status_t
detect_displays()
{
    // reset known displays
    for (uint32 id = 0; id < MAX_DISPLAY; id++) {
        gDisplay[id]->attached = false;
        gDisplay[id]->powered = false;
        gDisplay[id]->foundRanges = false;
    }

    uint32 displayIndex = 0;
    for (uint32 id = 0; id < ATOM_MAX_SUPPORTED_DEVICE; id++) {
        if (gConnector[id]->valid == false)
            continue;
        if (displayIndex >= MAX_DISPLAY)
            continue;

        if (gConnector[id]->type == VIDEO_CONNECTOR_9DIN) {
            TRACE("%s: connector(%" B_PRIu32 "): Skipping 9DIN connector "
                  "(not yet supported)\n", __func__, id);
            continue;
        }

        if (gConnector[id]->type == VIDEO_CONNECTOR_DP) {
            TRACE("%s: connector(%" B_PRIu32 "): Checking DP.\n", __func__, id);

            edid1_info* edid = &gDisplay[displayIndex]->edidData;
            gDisplay[displayIndex]->attached
                = ddc2_dp_read_edid1(id, edid);

            if (gDisplay[displayIndex]->attached) {
                TRACE("%s: connector(%" B_PRIu32 "): Found DisplayPort EDID!\n",
                      __func__);
            }
        }
        // TODO: Handle external DP brides - ??
#if 0
        if (gConnector[id]->encoderExternal.isDPBridge == true) {
            // If this is a DisplayPort Bridge, setup ddc on bus
            // TRAVIS (LVDS) or NUTMEG (VGA)
            TRACE("%s: is bridge, performing bridge DDC setup\n", __func__);
            encoder_external_setup(id, 23860,
                                   EXTERNAL_ENCODER_ACTION_V3_DDC_SETUP);
            gDisplay[displayIndex]->attached = true;

            // TODO: DDC Router switching for DisplayPort (and others?)
        }
#endif
        if (gConnector[id]->type == VIDEO_CONNECTOR_LVDS) {
            // If plain (non-DP) laptop LVDS, read mode info from AtomBIOS
            //TRACE("%s: non-DP laptop LVDS detected\n", __func__);
            gDisplay[displayIndex]->attached = connector_read_mode_lvds(id,
                                               &gDisplay[displayIndex]->preferredMode);
            if (gDisplay[displayIndex]->attached) {
                TRACE("%s: connector(%" B_PRIu32 "): found LVDS preferred "
                      "mode\n", __func__, id);
            }
        }

        // If no display found yet, try more standard detection methods
        if (gDisplay[displayIndex]->attached == false) {
            TRACE("%s: connector(%" B_PRIu32 "): bit-banging ddc for EDID.\n",
                  __func__, id);

            // Lets try bit-banging edid from connector
            gDisplay[displayIndex]->attached
                = connector_read_edid(id, &gDisplay[displayIndex]->edidData);

            // Since DVI-I shows up as two connectors, and there is only one
            // edid channel, we have to make *sure* the edid data received is
            // valid for the connector.

            // Found EDID data?
            if (gDisplay[displayIndex]->attached) {
                TRACE("%s: connector(%" B_PRIu32 "): found EDID data.\n",
                      __func__, id);

                bool analogEncoder
                    = gConnector[id]->encoder.type == VIDEO_ENCODER_TVDAC
                      || gConnector[id]->encoder.type == VIDEO_ENCODER_DAC;

                edid1_info* edid = &gDisplay[displayIndex]->edidData;
                if (!edid->display.input_type && analogEncoder) {
                    // If non-digital EDID + the encoder is analog...
                    TRACE("%s: connector(%" B_PRIu32 "): has non-digital EDID "
                          "and a analog encoder.\n", __func__, id);
                    gDisplay[displayIndex]->attached
                        = encoder_analog_load_detect(id);
                    remove_dup_displays(displayIndex, id);
                } else if (edid->display.input_type && !analogEncoder) {
                    // If EDID is digital, we make an assumption here.
                    TRACE("%s: connector(%" B_PRIu32 "): has digital EDID "
                          "and is not a analog encoder.\n", __func__, id);
                } else {
                    // This generally means the monitor is of poor design
                    // Since we *know* there is no load on the analog encoder
                    // we assume that it is a digital display.
                    // This can also occur when a display has both DVI and VGA
                    // inputs and the graphics board has a DVI-I connector
                    // (reported as both digital and analog connectors) and the
                    // analog connection is the one in use. In that case, we
                    // get here when checking the digital connector and want
                    // to disable that display in favor of the analog one.
                    TRACE("%s: connector(%" B_PRIu32 "): Warning: monitor has "
                          "false digital EDID flag + unloaded analog encoder!\n",
                          __func__, id);
                    gDisplay[displayIndex]->attached = false;
                }
            }
        }

        if (gDisplay[displayIndex]->attached != true) {
            // Nothing interesting here, move along
            continue;
        }

        // We found a valid / attached display

        gDisplay[displayIndex]->connectorIndex = id;
        // Populate physical connector index from gConnector

        init_registers(gDisplay[displayIndex]->regs, displayIndex);

        if (gDisplay[displayIndex]->preferredMode.virtual_width > 0) {
            // Found a single preferred mode
            gDisplay[displayIndex]->foundRanges = false;
        } else {
            // Use edid data and pull ranges
            if (detect_crt_ranges(displayIndex) == B_OK)
                gDisplay[displayIndex]->foundRanges = true;
        }

        displayIndex++;
    }

    // fallback if no attached monitors were found
    if (displayIndex == 0) {
        // This is a hack, however as we don't support HPD just yet,
        // it tries to prevent a "no displays" situation.
        ERROR("%s: ERROR: 0 attached monitors were found on display connectors."
              " Injecting first connector as a last resort.\n", __func__);
        for (uint32 id = 0; id < ATOM_MAX_SUPPORTED_DEVICE; id++) {
            // skip TV DAC connectors as likely fallback isn't for TV
            if (gConnector[id]->encoder.type == VIDEO_ENCODER_TVDAC)
                continue;
            gDisplay[0]->attached = true;
            gDisplay[0]->connectorIndex = id;
            init_registers(gDisplay[0]->regs, 0);
            if (detect_crt_ranges(0) == B_OK)
                gDisplay[0]->foundRanges = true;
            break;
        }
    }

    // Initial boot state is the first two crtc's powered
    if (gDisplay[0]->attached == true)
        gDisplay[0]->powered = true;
    if (gDisplay[1]->attached == true)
        gDisplay[1]->powered = true;

    return B_OK;
}