Ejemplo n.º 1
0
/*
 * Attach all the sub-devices we can find
 */
void
obio_attach(struct device *parent, struct device *self, void *aux)
{
	struct obio_softc *sc = (struct obio_softc *)self;
	struct pci_attach_args *pa = aux;
	struct confargs ca;
	bus_space_handle_t bsh;
	int node, child, namelen, error;
	u_int reg[20];
	int intr[6], parent_intr = 0, parent_nintr = 0;
	char name[32];
	char compat[32];

#ifdef OBIO_SPEED_CONTROL
	sc->sc_voltage = -1;
	sc->sc_busspeed = -1;
#endif

	switch (PCI_PRODUCT(pa->pa_id)) {

	case PCI_PRODUCT_APPLE_GC:
	case PCI_PRODUCT_APPLE_OHARE:
	case PCI_PRODUCT_APPLE_HEATHROW:
	case PCI_PRODUCT_APPLE_PADDINGTON:
	case PCI_PRODUCT_APPLE_KEYLARGO:
	case PCI_PRODUCT_APPLE_PANGEA_MACIO:
	case PCI_PRODUCT_APPLE_INTREPID:
		node = pcidev_to_ofdev(pa->pa_pc, pa->pa_tag);
		if (node == -1)
			node = OF_finddevice("mac-io");
			if (node == -1)
				node = OF_finddevice("/pci/mac-io");
		break;
	case PCI_PRODUCT_APPLE_K2:
		node = OF_finddevice("mac-io");
		break;

	default:
		node = -1;
		break;
	}
	if (node == -1)
		panic("macio not found or unknown");

	sc->sc_node = node;

#if defined (PMAC_G5)
	if (OF_getprop(node, "assigned-addresses", reg, sizeof(reg)) < 20)
	{
		return;
	}
#else
	if (OF_getprop(node, "assigned-addresses", reg, sizeof(reg)) < 12)
		return;
#endif /* PMAC_G5 */

	/*
	 * XXX
	 * This relies on the primary obio always attaching first which is
	 * true on the PowerBook 3400c and similar machines but may or may
	 * not work on others. We can't rely on the node name since Apple
	 * didn't follow anything remotely resembling a consistent naming
	 * scheme.
	 */
	if (obio0 == NULL)
		obio0 = sc;

	ca.ca_baseaddr = reg[2];
	ca.ca_tag = pa->pa_memt;
	sc->sc_tag = pa->pa_memt;
	error = bus_space_map (pa->pa_memt, ca.ca_baseaddr, 0x80, 0, &bsh);
	if (error)
		panic(": failed to map mac-io %#x", ca.ca_baseaddr);
	sc->sc_bh = bsh;

	printf(": addr 0x%x\n", ca.ca_baseaddr);

	/* Enable internal modem (KeyLargo) */
	if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_APPLE_KEYLARGO) {
		aprint_normal("%s: enabling KeyLargo internal modem\n",
		    self->dv_xname);
		bus_space_write_4(ca.ca_tag, bsh, 0x40, 
		    bus_space_read_4(ca.ca_tag, bsh, 0x40) & ~(1<<25));
	}

	/* Enable internal modem (Pangea) */
	if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_APPLE_PANGEA_MACIO) {
		/* set reset */
		bus_space_write_1(ca.ca_tag, bsh, 0x006a + 0x03, 0x04);
		/* power modem on */
		bus_space_write_1(ca.ca_tag, bsh, 0x006a + 0x02, 0x04);
		/* unset reset */
		bus_space_write_1(ca.ca_tag, bsh, 0x006a + 0x03, 0x05);
	}

	/* Gatwick and Paddington use same product ID */
	namelen = OF_getprop(node, "compatible", compat, sizeof(compat));

	if (strcmp(compat, "gatwick") == 0) {
		parent_nintr = OF_getprop(node, "AAPL,interrupts", intr,
					sizeof(intr));
		parent_intr = intr[0];
	} else {
  		/* Enable CD and microphone sound input. */
		if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_APPLE_PADDINGTON)
			bus_space_write_1(ca.ca_tag, bsh, 0x37, 0x03);
	}

	for (child = OF_child(node); child; child = OF_peer(child)) {
		namelen = OF_getprop(child, "name", name, sizeof(name));
		if (namelen < 0)
			continue;
		if (namelen >= sizeof(name))
			continue;

#ifdef OBIO_SPEED_CONTROL
		if (strcmp(name, "gpio") == 0) {

			obio_setup_gpios(sc, child);
			continue;
		}
#endif

		name[namelen] = 0;
		ca.ca_name = name;
		ca.ca_node = child;
		ca.ca_tag = pa->pa_memt;

		ca.ca_nreg = OF_getprop(child, "reg", reg, sizeof(reg));

		if (strcmp(compat, "gatwick") != 0) {
			ca.ca_nintr = OF_getprop(child, "AAPL,interrupts", intr,
					sizeof(intr));
			if (ca.ca_nintr == -1)
				ca.ca_nintr = OF_getprop(child, "interrupts", intr,
						sizeof(intr));
		} else {
			intr[0] = parent_intr;
			ca.ca_nintr = parent_nintr;
		}
		ca.ca_reg = reg;
		ca.ca_intr = intr;

		config_found(self, &ca, obio_print);
	}
}
Ejemplo n.º 2
0
static void
ofbattach(device_t parent, device_t self, void *aux)
{
	struct ofb_softc *sc = device_private(self);
	struct pci_attach_args *pa = aux;
	struct wsemuldisplaydev_attach_args a;
	struct rasops_info *ri = &rascons_console_screen.scr_ri;
	long defattr;
	int console, node, sub;
	char devinfo[256];

	sc->sc_dev = self;

	pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
	printf(": %s\n", devinfo);

	if (console_node == 0)
		return;

	node = pcidev_to_ofdev(pa->pa_pc, pa->pa_tag);
	console = (node == console_node);
	if (!console) {
		/* check if any of the childs matches */
		sub = OF_child(node);
		while ((sub != 0) && (sub != console_node)) {
			sub = OF_peer(sub);
		}
		if (sub == console_node) {
			console = true;
		}
	}
	
	sc->sc_memt = pa->pa_memt;
	sc->sc_iot = pa->pa_iot;	
	sc->sc_pc = pa->pa_pc;
	sc->sc_pcitag = pa->pa_tag;
	sc->sc_mode = WSDISPLAYIO_MODE_EMUL;

	if (!console)
		return;
	
	vcons_init(&sc->vd, sc, &rascons_stdscreen, &ofb_accessops);
	sc->vd.init_screen = ofb_init_screen;

	sc->sc_node = console_node;

	sc->sc_ih = console_instance;
	vcons_init_screen(&sc->vd, &rascons_console_screen, 1, &defattr);
	rascons_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
	
	printf("%s: %d x %d, %dbpp\n", device_xname(self),
	       ri->ri_width, ri->ri_height, ri->ri_depth);
	
	sc->sc_fbaddr = 0;
	if (OF_getprop(sc->sc_node, "address", &sc->sc_fbaddr, 4) != 4)
		OF_interpret("frame-buffer-adr", 0, 1, &sc->sc_fbaddr);
	if (sc->sc_fbaddr == 0) {
		printf("%s: Unable to find the framebuffer address.\n",
		    device_xname(sc->sc_dev));
		return;
	}
	sc->sc_fbsize = round_page(ri->ri_stride * ri->ri_height);

	/* XXX */
	if (OF_getprop(sc->sc_node, "assigned-addresses", sc->sc_addrs,
	    sizeof(sc->sc_addrs)) == -1) {
		sc->sc_node = OF_parent(sc->sc_node);
		OF_getprop(sc->sc_node, "assigned-addresses", sc->sc_addrs,
		    sizeof(sc->sc_addrs));
	}

	ofb_init_cmap(sc);

	a.console = console;
	a.scrdata = &ofb_screenlist;
	a.accessops = &ofb_accessops;
	a.accesscookie = &sc->vd;

	config_found(self, &a, wsemuldisplaydevprint);

	config_found_ia(self, "drm", aux, ofb_drm_print);
}