Пример #1
0
void
agtenattach(struct device *parent, struct device *self, void *args)
{
	struct agten_softc *sc = (struct agten_softc *)self;
	struct confargs *ca = args;
	struct wsemuldisplaydev_attach_args waa;
	int node, isconsole;
	char *nam;

	sc->sc_sunfb.sf_flags = self->dv_cfdata->cf_flags;

	node = ca->ca_ra.ra_node;
	nam = getpropstring(node, "model");
	printf(": model %s", nam);

	isconsole = node == fbnode;

	sc->sc_phys = ca->ca_ra.ra_reg[0];

	/*
	 * Map the various beasts of this card we are interested in.
	 */

	sc->sc_physoffset =
	    (off_t)getpropint(node, "i128_fb_physaddr", 0x8000000);
	sc->sc_i128_fb = mapiodev(ca->ca_ra.ra_reg, sc->sc_physoffset,
	    getpropint(node, "i128_fb_size", 0x400000));
	sc->sc_dac = mapiodev(ca->ca_ra.ra_reg,
	    getpropint(node, "p9100_reg_physaddr", 0x10a0000) + 0x200,
	    0x800 - 0x200);

	/*
	 * For some reason the agten does not use the canonical name for
	 * properties, but uses an ffb_ prefix; and the linebytes property is
	 * missing.
	 * The following is a specific version of
	 *   fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, BUS_SBUS);
	 * using the correct property names.
	 */
#ifdef notyet
	sc->sc_sunfb.sf_depth = 32;
#else
	sc->sc_sunfb.sf_depth = getpropint(node, "ffb_depth", 8);
#endif
	sc->sc_sunfb.sf_width = getpropint(node, "ffb_width", 1152);
	sc->sc_sunfb.sf_height = getpropint(node, "ffb_height", 900);
	sc->sc_sunfb.sf_linebytes =
	    roundup(sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_depth) *
	        sc->sc_sunfb.sf_depth / 8;
	sc->sc_sunfb.sf_fbsize =
	    sc->sc_sunfb.sf_height * sc->sc_sunfb.sf_linebytes;

	printf(", %dx%d, depth %d\n",
	    sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height,
	    sc->sc_sunfb.sf_depth);

	sc->sc_sunfb.sf_ro.ri_bits = (void *)sc->sc_i128_fb;
	
	sc->sc_sunfb.sf_ro.ri_hw = sc;
	fbwscons_init(&sc->sc_sunfb, isconsole);
	fbwscons_setcolormap(&sc->sc_sunfb, agten_setcolor);

	agten_stdscreen.capabilities = sc->sc_sunfb.sf_ro.ri_caps;
	agten_stdscreen.nrows = sc->sc_sunfb.sf_ro.ri_rows;
	agten_stdscreen.ncols = sc->sc_sunfb.sf_ro.ri_cols;
	agten_stdscreen.textops = &sc->sc_sunfb.sf_ro.ri_ops;

	if (isconsole) {
		fbwscons_console_init(&sc->sc_sunfb, &agten_stdscreen, -1,
		    NULL);
	}

	sbus_establish(&sc->sc_sd, &sc->sc_sunfb.sf_dev);

	waa.console = isconsole;
	waa.scrdata = &agten_screenlist;
	waa.accessops = &agten_accessops;
	waa.accesscookie = sc;
	config_found(self, &waa, wsemuldisplaydevprint);
}
Пример #2
0
/**
 * radeon_driver_load_kms - Main load function for KMS.
 *
 * @dev: drm dev pointer
 * @flags: device flags
 *
 * This is the main load function for KMS (all asics).
 * It calls radeon_device_init() to set up the non-display
 * parts of the chip (asic init, CP, writeback, etc.), and
 * radeon_modeset_init() to set up the display parts
 * (crtcs, encoders, hotplug detect, etc.).
 * Returns 0 on success, error on failure.
 */
void
radeondrm_attach_kms(struct device *parent, struct device *self, void *aux)
{
	struct radeon_device	*rdev = (struct radeon_device *)self;
	struct drm_device	*dev;
	struct pci_attach_args	*pa = aux;
	const struct drm_pcidev *id_entry;
	int			 is_agp;
	pcireg_t		 type;
	uint8_t			 iobar;
#if !defined(__sparc64__)
	pcireg_t		 addr, mask;
	int			 s;
#endif

#if defined(__sparc64__) || defined(__macppc__)
	extern int fbnode;
#endif

	id_entry = drm_find_description(PCI_VENDOR(pa->pa_id),
	    PCI_PRODUCT(pa->pa_id), radeondrm_pciidlist);
	rdev->flags = id_entry->driver_data;
	rdev->pc = pa->pa_pc;
	rdev->pa_tag = pa->pa_tag;
	rdev->iot = pa->pa_iot;
	rdev->memt = pa->pa_memt;
	rdev->dmat = pa->pa_dmat;

#if defined(__sparc64__) || defined(__macppc__)
	if (fbnode == PCITAG_NODE(rdev->pa_tag))
		rdev->console = 1;
#else
	if (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY &&
	    PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_DISPLAY_VGA &&
	    (pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG)
	    & (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE))
	    == (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE)) {
		rdev->console = 1;
#if NVGA > 0
		vga_console_attached = 1;
#endif
	}
#endif

#define RADEON_PCI_MEM		0x10
#define RADEON_PCI_IO		0x14
#define RADEON_PCI_MMIO		0x18
#define RADEON_PCI_IO2		0x20

	type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, RADEON_PCI_MEM);
	if (PCI_MAPREG_TYPE(type) != PCI_MAPREG_TYPE_MEM ||
	    pci_mapreg_info(pa->pa_pc, pa->pa_tag, RADEON_PCI_MEM,
	    type, &rdev->fb_aper_offset, &rdev->fb_aper_size, NULL)) {
		printf(": can't get frambuffer info\n");
		return;
	}

	if (PCI_MAPREG_MEM_TYPE(type) != PCI_MAPREG_MEM_TYPE_64BIT)
		iobar = RADEON_PCI_IO;
	else
		iobar = RADEON_PCI_IO2;
	
	if (pci_mapreg_map(pa, iobar, PCI_MAPREG_TYPE_IO, 0,
	    NULL, &rdev->rio_mem, NULL, &rdev->rio_mem_size, 0)) {
		printf(": can't map IO space\n");
		return;
	}

	type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, RADEON_PCI_MMIO);
	if (PCI_MAPREG_TYPE(type) != PCI_MAPREG_TYPE_MEM ||
	    pci_mapreg_map(pa, RADEON_PCI_MMIO, type, 0, NULL,
	    &rdev->rmmio, &rdev->rmmio_base, &rdev->rmmio_size, 0)) {
		printf(": can't map mmio space\n");
		return;
	}

#if !defined(__sparc64__)
	/*
	 * Make sure we have a base address for the ROM such that we
	 * can map it later.
	 */
	s = splhigh();
	addr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG);
	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, ~PCI_ROM_ENABLE);
	mask = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG);
	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, addr);
	splx(s);

	if (addr == 0 && PCI_ROM_SIZE(mask) != 0 && pa->pa_memex) {
		bus_size_t size, start, end;
		bus_addr_t base;

		size = PCI_ROM_SIZE(mask);
		start = max(PCI_MEM_START, pa->pa_memex->ex_start);
		end = min(PCI_MEM_END, pa->pa_memex->ex_end);
		if (extent_alloc_subregion(pa->pa_memex, start, end, size,
		    size, 0, 0, 0, &base) == 0)
			pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, base);
	}
#endif

#ifdef notyet
	mtx_init(&rdev->swi_lock, IPL_TTY);
#endif

	/* update BUS flag */
	if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, NULL, NULL)) {
		rdev->flags |= RADEON_IS_AGP;
	} else if (pci_get_capability(pa->pa_pc, pa->pa_tag,
	    PCI_CAP_PCIEXPRESS, NULL, NULL)) {
		rdev->flags |= RADEON_IS_PCIE;
	} else {
		rdev->flags |= RADEON_IS_PCI;
	}

	DRM_DEBUG("%s card detected\n",
		 ((rdev->flags & RADEON_IS_AGP) ? "AGP" :
		 (((rdev->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI"))));

	is_agp = pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP,
	    NULL, NULL);

	printf("\n");

	kms_driver.num_ioctls = radeon_max_kms_ioctl;

	dev = (struct drm_device *)drm_attach_pci(&kms_driver, pa, is_agp,
	    rdev->console, self);
	rdev->ddev = dev;
	rdev->pdev = dev->pdev;

	rdev->family = rdev->flags & RADEON_FAMILY_MASK;
	if (!radeon_msi_ok(rdev))
		pa->pa_flags &= ~PCI_FLAGS_MSI_ENABLED;

	rdev->msi_enabled = 0;
	if (pci_intr_map_msi(pa, &rdev->intrh) == 0)
		rdev->msi_enabled = 1;
	else if (pci_intr_map(pa, &rdev->intrh) != 0) {
		printf(": couldn't map interrupt\n");
		return;
	}
	printf("%s: %s\n", rdev->dev.dv_xname,
	    pci_intr_string(pa->pa_pc, rdev->intrh));

	rdev->irqh = pci_intr_establish(pa->pa_pc, rdev->intrh, IPL_TTY,
	    radeon_driver_irq_handler_kms, rdev->ddev, rdev->dev.dv_xname);
	if (rdev->irqh == NULL) {
		printf("%s: couldn't establish interrupt\n",
		    rdev->dev.dv_xname);
		return;
	}

#ifdef __sparc64__
{
	struct rasops_info *ri;
	int node, console;

	node = PCITAG_NODE(pa->pa_tag);
	console = (fbnode == node);

	fb_setsize(&rdev->sf, 8, 1152, 900, node, 0);

	/*
	 * The firmware sets up the framebuffer such that at starts at
	 * an offset from the start of video memory.
	 */
	rdev->fb_offset =
	    bus_space_read_4(rdev->memt, rdev->rmmio, RADEON_CRTC_OFFSET);
	if (bus_space_map(rdev->memt, rdev->fb_aper_offset + rdev->fb_offset,
	    rdev->sf.sf_fbsize, BUS_SPACE_MAP_LINEAR, &rdev->memh)) {
		printf("%s: can't map video memory\n", rdev->dev.dv_xname);
		return;
	}

	ri = &rdev->sf.sf_ro;
	ri->ri_bits = bus_space_vaddr(rdev->memt, rdev->memh);
	ri->ri_hw = rdev;
	ri->ri_updatecursor = NULL;

	fbwscons_init(&rdev->sf, RI_VCONS | RI_WRONLY | RI_BSWAP, console);
	if (console)
		fbwscons_console_init(&rdev->sf, -1);
}
#endif

	rdev->shutdown = true;
	if (rootvp == NULL)
		mountroothook_establish(radeondrm_attachhook, rdev);
	else
		radeondrm_attachhook(rdev);
}
Пример #3
0
void
bwtwoattach(struct device *parent, struct device *self, void *args)
{
	struct bwtwo_softc *sc = (struct bwtwo_softc *)self;
	struct confargs *ca = args;
	int node = ca->ca_ra.ra_node;
	int isconsole = 0;
	int sbus = 1;
	char *nam;

	printf(": ");

	/*
	 * Map the control register.
	 */
#if defined(SUN4)
	if (CPU_ISSUN4 && ca->ca_bustype == BUS_OBIO &&
	    fb_pfour_id(ca->ca_ra.ra_vaddr) != PFOUR_NOTPFOUR) {
		SET(sc->sc_sunfb.sf_flags, FB_PFOUR);
		sc->sc_sunfb.sf_pfour = (volatile u_int32_t *)
		    mapiodev(ca->ca_ra.ra_reg, 0, sizeof(u_int32_t));
	} else
#endif
	{
		sc->sc_reg = (volatile struct fbcontrol *)
		    mapiodev(ca->ca_ra.ra_reg, BWREG_REG,
			     sizeof(struct fbcontrol));
	}

	/* Set up default pixel offset.  May be changed below. */
	sc->sc_pixeloffset = BWREG_MEM;

	switch (ca->ca_bustype) {
	case BUS_OBIO:
		if (CPU_ISSUN4M)	/* 4m has framebuffer on obio */
			goto obp_name;

		sbus = node = 0;
#if defined(SUN4)
		if (ISSET(sc->sc_sunfb.sf_flags, FB_PFOUR)) {
			nam = "p4";
			sc->sc_pixeloffset = PFOUR_BW_OFF;
		} else
#endif
			nam = NULL;
		break;

	case BUS_VME32:
	case BUS_VME16:
		sbus = node = 0;
		nam = NULL;
		break;

	case BUS_SBUS:
obp_name:
#if defined(SUN4C) || defined(SUN4M)
		nam = getpropstring(node, "model");
#endif
		break;
	}

	if (nam != NULL && *nam != '\0')
		printf("%s, ", nam);

#if defined(SUN4)
	if (CPU_ISSUN4) {
		struct eeprom *eep = (struct eeprom *)eeprom_va;
		int constype = ISSET(sc->sc_sunfb.sf_flags, FB_PFOUR) ?
		    EE_CONS_P4OPT : EE_CONS_BW;
		/*
		 * Assume this is the console if there's no eeprom info
		 * to be found.
		 */
		if (eep == NULL || eep->eeConsole == constype)
			isconsole = 1;
		else
		/*
		 * On sun4 systems without on-board framebuffers (such as
		 * the 4/3xx models), the PROM will accept the EE_CONS_BW
		 * setting although the framebuffer is a P4.
		 * Accept this setting as well.
		 */
		if (eep->eeConsole == EE_CONS_BW)
			isconsole = 1;
	}
#endif

	if (CPU_ISSUN4COR4M)
		isconsole = node == fbnode;

	sc->sc_phys = ca->ca_ra.ra_reg[0];
	sc->sc_bustype = ca->ca_bustype;

	/* enable video */
	bwtwo_burner(sc, 1, 0);

	fb_setsize(&sc->sc_sunfb, 1, 1152, 900, node, ca->ca_bustype);
	printf("%dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);

	sc->sc_sunfb.sf_ro.ri_bits = mapiodev(ca->ca_ra.ra_reg,
	    sc->sc_pixeloffset, round_page(sc->sc_sunfb.sf_fbsize));
	sc->sc_sunfb.sf_ro.ri_hw = sc;
	fbwscons_init(&sc->sc_sunfb, isconsole ? 0 : RI_CLEAR);

	if (isconsole) {
		fbwscons_console_init(&sc->sc_sunfb, -1);
	}

	fbwscons_attach(&sc->sc_sunfb, &bwtwo_accessops, isconsole);
}
Пример #4
0
void    
cgsixattach(struct device *parent, struct device *self, void *aux)
{
	struct cgsix_softc *sc = (struct cgsix_softc *)self;
	struct sbus_attach_args *sa = aux;
	int node, console;
	u_int32_t fhc, rev;
	const char *nam;

	node = sa->sa_node;
	sc->sc_bustag = sa->sa_bustag;
	sc->sc_paddr = sbus_bus_addr(sa->sa_bustag, sa->sa_slot, sa->sa_offset);

	if (sa->sa_nreg != 1) {
		printf(": expected %d registers, got %d\n", 1, sa->sa_nreg);
		goto fail;
	}

	fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, 0);

	/*
	 * Map just BT, FHC, FBC, THC, and video RAM.
	 */
	if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
	    sa->sa_reg[0].sbr_offset + CGSIX_BT_OFFSET,
	    CGSIX_BT_SIZE, 0, 0, &sc->sc_bt_regs) != 0) {
		printf(": cannot map bt registers\n");
		goto fail_bt;
	}

	if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
	    sa->sa_reg[0].sbr_offset + CGSIX_FHC_OFFSET,
	    CGSIX_FHC_SIZE, 0, 0, &sc->sc_fhc_regs) != 0) {
		printf(": cannot map fhc registers\n");
		goto fail_fhc;
	}

	if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
	    sa->sa_reg[0].sbr_offset + CGSIX_THC_OFFSET,
	    CGSIX_THC_SIZE, 0, 0, &sc->sc_thc_regs) != 0) {
		printf(": cannot map thc registers\n");
		goto fail_thc;
	}

	if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
	    sa->sa_reg[0].sbr_offset + CGSIX_VID_OFFSET,
	    sc->sc_sunfb.sf_fbsize, BUS_SPACE_MAP_LINEAR,
	    0, &sc->sc_vid_regs) != 0) {
		printf(": cannot map vid registers\n");
		goto fail_vid;
	}

	if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
	    sa->sa_reg[0].sbr_offset + CGSIX_TEC_OFFSET,
	    CGSIX_TEC_SIZE, 0, 0, &sc->sc_tec_regs) != 0) {
		printf(": cannot map tec registers\n");
		goto fail_tec;
	}

	if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
	    sa->sa_reg[0].sbr_offset + CGSIX_FBC_OFFSET,
	    CGSIX_FBC_SIZE, 0, 0, &sc->sc_fbc_regs) != 0) {
		printf(": cannot map fbc registers\n");
		goto fail_fbc;
	}

	if ((sc->sc_ih = bus_intr_establish(sa->sa_bustag, sa->sa_pri,
	    IPL_TTY, 0, cgsix_intr, sc, self->dv_xname)) == NULL) {
		printf(": couldn't establish interrupt, pri %d\n%s",
		    INTLEV(sa->sa_pri), self->dv_xname);
	}

	/* if prom didn't initialize us, do it the hard way */
	if (OF_getproplen(node, "width") != sizeof(u_int32_t))
		cgsix_hardreset(sc);

	nam = getpropstring(node, "model");
	if (*nam == '\0')
		nam = sa->sa_name;
	printf(": %s", nam);

	console = cgsix_is_console(node);

	fhc = FHC_READ(sc);
	rev = (fhc & FHC_REV_MASK) >> FHC_REV_SHIFT;
	cgsix_reset(sc, rev);

	cgsix_burner(sc, 1, 0);

	sc->sc_sunfb.sf_ro.ri_bits = (void *)bus_space_vaddr(sc->sc_bustag,
	    sc->sc_vid_regs);
	sc->sc_sunfb.sf_ro.ri_hw = sc;

	printf(", %dx%d, rev %d\n", sc->sc_sunfb.sf_width,
	    sc->sc_sunfb.sf_height, rev);

	fbwscons_init(&sc->sc_sunfb, 0, console);
	fbwscons_setcolormap(&sc->sc_sunfb, cgsix_setcolor);

	/*
	 * Old rev. cg6 cards do not like the current acceleration code.
	 *
	 * Some hints from Sun point out at timing and cache problems, which
	 * will be investigated later.
	 */
	if (rev < 5)
		sc->sc_sunfb.sf_dev.dv_cfdata->cf_flags |= CG6_CFFLAG_NOACCEL;

	if ((sc->sc_sunfb.sf_dev.dv_cfdata->cf_flags & CG6_CFFLAG_NOACCEL)
	    == 0) {
		sc->sc_sunfb.sf_ro.ri_ops.copyrows = cgsix_ras_copyrows;
		sc->sc_sunfb.sf_ro.ri_ops.copycols = cgsix_ras_copycols;
		sc->sc_sunfb.sf_ro.ri_ops.eraserows = cgsix_ras_eraserows;
		sc->sc_sunfb.sf_ro.ri_ops.erasecols = cgsix_ras_erasecols;
		sc->sc_sunfb.sf_ro.ri_do_cursor = cgsix_ras_do_cursor;
		cgsix_ras_init(sc);
	}

	if (console)
		fbwscons_console_init(&sc->sc_sunfb, -1);

	fbwscons_attach(&sc->sc_sunfb, &cgsix_accessops, console);

	return;

fail_fbc:
	bus_space_unmap(sa->sa_bustag, sc->sc_tec_regs, CGSIX_TEC_SIZE);
fail_tec:
	bus_space_unmap(sa->sa_bustag, sc->sc_vid_regs, sc->sc_sunfb.sf_fbsize);
fail_vid:
	bus_space_unmap(sa->sa_bustag, sc->sc_thc_regs, CGSIX_THC_SIZE);
fail_thc:
	bus_space_unmap(sa->sa_bustag, sc->sc_fhc_regs, CGSIX_FHC_SIZE);
fail_fhc:
	bus_space_unmap(sa->sa_bustag, sc->sc_bt_regs, CGSIX_BT_SIZE);
fail_bt:
fail:
	return;
}
Пример #5
0
/*
 * Attach and initialize a cgtwelve.
 */
void
cgtwelveattach(struct device *parent, struct device *self, void *args)
{
    struct cgtwelve_softc *sc = (struct cgtwelve_softc *)self;
    struct sbus_attach_args *sa = args;
    bus_space_tag_t bt;
    bus_space_handle_t bh;
    int node, isconsole = 0;
    char *ps;

    bt = sa->sa_bustag;
    node = sa->sa_node;

    printf(": %s", getpropstring(node, "model"));
    ps = getpropstring(node, "dev_id");
    if (*ps != '\0')
        printf(" (%s)", ps);
    printf("\n");

    isconsole = node == fbnode;

    if (sa->sa_nreg == 0) {
        printf("%s: no SBus registers!\n", self->dv_xname);
        return;
    }

    sc->sc_bustag = bt;

    /*
     * Map registers
     */
    if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset +
                     CG12_OFF_DPU, sizeof(struct cgtwelve_dpu),
                     BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
        printf("%s: can't map DPU registers\n", self->dv_xname);
        return;
    }
    sc->sc_dpu = bus_space_vaddr(bt, bh);
    if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset +
                     CG12_OFF_APU, sizeof(struct cgtwelve_apu),
                     BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
        printf("%s: can't map APU registers\n", self->dv_xname);
        return;
    }
    sc->sc_apu = bus_space_vaddr(bt, bh);
    if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset +
                     CG12_OFF_DAC, sizeof(struct cgtwelve_dac),
                     BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
        printf("%s: can't map RAMDAC registers\n", self->dv_xname);
        return;
    }
    sc->sc_ramdac = bus_space_vaddr(bt, bh);

    /*
     * The console is using the 1-bit overlay plane, while the prom
     * will correctly report 32 bit depth.
     */
    fb_setsize(&sc->sc_sunfb, 1, CG12_WIDTH, CG12_HEIGHT,
               node, 0);
    sc->sc_sunfb.sf_depth = 1;
    sc->sc_sunfb.sf_linebytes = sc->sc_sunfb.sf_width / 8;
    sc->sc_sunfb.sf_fbsize = sc->sc_sunfb.sf_height *
                             sc->sc_sunfb.sf_linebytes;

    sc->sc_highres = sc->sc_sunfb.sf_width == CG12_WIDTH_HR;

    /*
     * Map planes
     */
    if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset +
                     (sc->sc_highres ? CG12_OFF_OVERLAY0_HR : CG12_OFF_OVERLAY0),
                     round_page(sc->sc_highres ? CG12_SIZE_OVERLAY_HR :
                                CG12_SIZE_OVERLAY), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
        printf("%s: can't map overlay plane\n", self->dv_xname);
        return;
    }
    sc->sc_overlay = bus_space_vaddr(bt, bh);
    if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset +
                     (sc->sc_highres ? CG12_OFF_INTEN_HR : CG12_OFF_INTEN),
                     round_page(sc->sc_highres ? CG12_SIZE_COLOR24_HR :
                                CG12_SIZE_COLOR24), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
        printf("%s: can't map color plane\n", self->dv_xname);
        return;
    }
    sc->sc_inten = bus_space_vaddr(bt, bh);
    sc->sc_paddr = sbus_bus_addr(bt, sa->sa_slot, sa->sa_offset +
                                 (sc->sc_highres ? CG12_OFF_INTEN_HR : CG12_OFF_INTEN));

    /* reset cursor & frame buffer controls */
    sc->sc_sunfb.sf_depth = 0;	/* force action */
    cgtwelve_reset(sc, 1);

    sc->sc_sunfb.sf_ro.ri_bits = (void *)sc->sc_overlay;
    sc->sc_sunfb.sf_ro.ri_hw = sc;
    fbwscons_init(&sc->sc_sunfb, isconsole ? 0 : RI_CLEAR);

    if (isconsole) {
        fbwscons_console_init(&sc->sc_sunfb, -1);
        shutdownhook_establish(cgtwelve_prom, sc);
    }

    printf("%s: %dx%d", self->dv_xname,
           sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);
    ps = getpropstring(node, "ucoderev");
    if (*ps != '\0')
        printf(", microcode rev. %s", ps);
    printf("\n");

    fbwscons_attach(&sc->sc_sunfb, &cgtwelve_accessops, isconsole);
}
Пример #6
0
/*
 * Attach a display.
 */
void
p9100attach(struct device *parent, struct device *self, void *args)
{
	struct p9100_softc *sc = (struct p9100_softc *)self;
	struct rasops_info *ri = &sc->sc_sunfb.sf_ro;
	struct confargs *ca = args;
	struct romaux *ra = &ca->ca_ra;
	int node, pri, scr, force_reset;
	int isconsole, fontswitch, clear = 0;

	pri = ca->ca_ra.ra_intr[0].int_pri;
	printf(" pri %d", pri);

#ifdef DIAGNOSTIC
	if (ra->ra_nreg < P9100_NREG) {
		printf(": expected %d registers, got only %d\n",
		    P9100_NREG, ra->ra_nreg);
		return;
	}
#endif

	sc->sc_flags = SCF_INTERNAL;
	sc->sc_mapmode = WSDISPLAYIO_MODE_EMUL;

	bcopy(ra->ra_reg, sc->sc_phys, sizeof(sc->sc_phys));

	sc->sc_ctl = mapiodev(&ra->ra_reg[P9100_REG_CTL], 0,
	    ra->ra_reg[P9100_REG_CTL].rr_len);
	sc->sc_cmd = mapiodev(&ra->ra_reg[P9100_REG_CMD], 0,
	    ra->ra_reg[P9100_REG_CMD].rr_len);
#ifdef	FIDDLE_WITH_PCI_REGISTERS
	sc->sc_pci = (struct p9100_pci *)
	    mapiodev(&ra->ra_reg[P9100_REG_CONFIG], 0,
	      ra->ra_reg[P9100_REG_CONFIG].rr_len);
#endif

	node = ra->ra_node;
	isconsole = node == fbnode;

	P9100_SELECT_SCR(sc);
	scr = P9100_READ_CTL(sc, P9000_SYSTEM_CONFIG);
	switch (scr & SCR_PIXEL_MASK) {
	default:
#ifdef DIAGNOSTIC
		printf(": unknown color depth code 0x%x",
		    scr & SCR_PIXEL_MASK);
#endif
		/* FALLTHROUGH */
	case SCR_PIXEL_32BPP:
	case SCR_PIXEL_24BPP:
	case SCR_PIXEL_16BPP:
		force_reset = 1;
		break;
	case SCR_PIXEL_8BPP:
		force_reset = 0;
		break;
	}

	fb_setsize(&sc->sc_sunfb, 8, LCD_WIDTH, LCD_HEIGHT, node,
	    ca->ca_bustype);

#if 0
	/*
	 * The PROM will initialize us in 800x600x8 mode anyway. If it
	 * does not, we'll force this mode right now.
	 */
	if (sc->sc_sunfb.sf_width != LCD_WIDTH || sc->sc_sunfb.sf_depth != 8 ||
	    sc->sc_sunfb.sf_height != LCD_HEIGHT || force_reset != 0) {
		sc->sc_sunfb.sf_width = LCD_WIDTH;
		sc->sc_sunfb.sf_height = LCD_HEIGHT;
		sc->sc_sunfb.sf_depth = 8;
		sc->sc_sunfb.sf_linebytes = LCD_WIDTH;

		printf("\n");
		p9100_initialize_ramdac(sc, LCD_WIDTH, 8);
		printf("%s", self->dv_xname);
		clear = 1;
	}
#endif

#if NTCTRL > 0
	/*
	 * We want to run the frame buffer in 8bpp mode for the emulation mode,
	 * and use a potentially better mode for the mapped (X11) mode.
	 * Eventually this will become runtime user-selectable.
	 */

	sc->sc_mapwidth = LCD_WIDTH;
	sc->sc_mapheight = LCD_HEIGHT;
	sc->sc_mapdepth = 8;

	if (sc->sc_mapwidth != sc->sc_sunfb.sf_width ||
	    sc->sc_mapdepth != sc->sc_sunfb.sf_depth)
		SET(sc->sc_flags, SCF_MAPPEDSWITCH);
#endif

	ri->ri_bits = mapiodev(&ra->ra_reg[P9100_REG_VRAM], 0,
	    sc->sc_vramsize = round_page(ra->ra_reg[P9100_REG_VRAM].rr_len));
	ri->ri_hw = sc;

	printf(": rev %x, %dx%d\n", scr & SCR_ID_MASK, LCD_WIDTH, LCD_HEIGHT);

	/* Disable frame buffer interrupts */
	P9100_SELECT_SCR(sc);
	P9100_WRITE_CTL(sc, P9000_INTERRUPT_ENABLE, IER_MASTER_ENABLE | 0);

	sc->sc_ih.ih_fun = p9100_intr;
	sc->sc_ih.ih_arg = sc;
	intr_establish(pri, &sc->sc_ih, IPL_FB, self->dv_xname);

	/*
	 * Try to get a copy of the PROM font.
	 *
	 * If we can, we still need to adjust the visible portion of the
	 * display, as the PROM output is offset two chars to the left.
	 *
	 * If we can't, we'll switch to the 8x16 font, and we'll need to adjust
	 * two things:
	 * - the display row should be overrided from the current PROM metrics,
	 *   to prevent us from overwriting the last few lines of text.
	 * - if the 80x34 screen would make a large margin appear around it,
	 *   choose to clear the screen rather than keeping old prom output in
	 *   the margins.
	 * XXX there should be a rasops "clear margins" feature
	 */
	fontswitch = p9100_pick_romfont(sc);

	/*
	 * Register the external video control callback with tctrl; tctrl
	 * will invoke it immediately to set the appropriate behaviour.
	 * If tctrl is not configured, simply enable external video.
	 */
#if NTCTRL > 0
	tadpole_register_extvideo(p9100_external_video, sc);
#else
	p9100_external_video(sc, 1);
#endif

	if (isconsole == 0 || fontswitch)
		clear = 1;
	fbwscons_init(&sc->sc_sunfb, clear ? RI_CLEAR : 0);
	if (clear == 0) {
		ri->ri_bits -= 2 * ri->ri_xscale;
		ri->ri_xorigin -= 2 * ri->ri_xscale;
	}
	fbwscons_setcolormap(&sc->sc_sunfb, p9100_setcolor);

	/*
	 * Plug-in accelerated console operations.
	 */
	if (sc->sc_sunfb.sf_dev.dv_cfdata->cf_flags != 0)
		p9100_ras_init(sc);

	/* enable video */
	p9100_burner(sc, 1, 0);

	if (isconsole) {
		fbwscons_console_init(&sc->sc_sunfb, clear ? 0 : -1);
#if NTCTRL > 0
		shutdownhook_establish(p9100_prom, sc);
#endif
	}

	fbwscons_attach(&sc->sc_sunfb, &p9100_accessops, isconsole);
}
Пример #7
0
void
cgtwoattach(struct device *parent, struct device *self, void *args)
{
	struct cgtwo_softc *sc = (struct cgtwo_softc *)self;
	struct confargs *ca = args;
	int node = 0;
	int isconsole = 0;

	if (CPU_ISSUN4) {
		struct eeprom *eep = (struct eeprom *)eeprom_va;
		/*
		 * Assume this is the console if there's no eeprom info
		 * to be found.
		 */
		if (eep == NULL || eep->eeConsole == EE_CONS_COLOR)
			isconsole = 1;
	}

	/*
	 * When the ROM has mapped in a cgtwo display, the address
	 * maps only the video RAM, so in any case we have to map the
	 * registers ourselves.
	 */
	sc->sc_phys = ca->ca_ra.ra_reg[0];
	/* Apparently, the pixels are 32-bit data space */
	sc->sc_phys.rr_iospace = PMAP_VME32;

	sc->sc_reg = (volatile struct cg2statusreg *)
	    mapiodev(ca->ca_ra.ra_reg,
		CG2_ROPMEM_OFF + offsetof(struct cg2fb, status.reg),
		sizeof(struct cg2statusreg));

	sc->sc_ppmask = (volatile u_short *)
	    mapiodev(ca->ca_ra.ra_reg,
		CG2_ROPMEM_OFF + offsetof(struct cg2fb, ppmask.reg),
		sizeof(u_short));

	sc->sc_cmap = (volatile u_short *)
	    mapiodev(ca->ca_ra.ra_reg,
		     CG2_ROPMEM_OFF + offsetof(struct cg2fb, redmap),
		     3 * CG2_CMSIZE * sizeof(u_short));

	/* enable video */
	*sc->sc_ppmask = 0xffff;	/* enable all color planes... */
	cgtwo_burner(sc, 1, 0);		/* ... and video signals */

	fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, ca->ca_bustype);
	sc->sc_sunfb.sf_ro.ri_bits = mapiodev(&sc->sc_phys, CG2_PIXMAP_OFF,
	    round_page(sc->sc_sunfb.sf_fbsize));
	sc->sc_sunfb.sf_ro.ri_hw = sc;
	fbwscons_init(&sc->sc_sunfb, isconsole ? 0 : RI_CLEAR);
	fbwscons_setcolormap(&sc->sc_sunfb, cgtwo_setcolor);

	printf(": %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);

	if (isconsole) {
		fbwscons_console_init(&sc->sc_sunfb, -1);
	}

	fbwscons_attach(&sc->sc_sunfb, &cgtwo_accessops, isconsole);
}
Пример #8
0
void    
cgthreeattach(struct device *parent, struct device *self, void *aux)
{
	struct cgthree_softc *sc = (struct cgthree_softc *)self;
	struct sbus_attach_args *sa = aux;
	int node, console;
	const char *nam;

	node = sa->sa_node;
	sc->sc_bustag = sa->sa_bustag;
	sc->sc_paddr = sbus_bus_addr(sa->sa_bustag, sa->sa_slot, sa->sa_offset);

	fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, 0);

	if (sa->sa_nreg != 1) {
		printf(": expected %d registers, got %d\n", 1, sa->sa_nreg);
		goto fail;
	}

	/*
	 * Map just CTRL and video RAM.
	 */
	if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
	    sa->sa_reg[0].sbr_offset + CGTHREE_CTRL_OFFSET,
	    CGTHREE_CTRL_SIZE, 0, 0, &sc->sc_ctrl_regs) != 0) {
		printf(": cannot map ctrl registers\n");
		goto fail_ctrl;
	}

	if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
	    sa->sa_reg[0].sbr_offset + CGTHREE_VID_OFFSET,
	    sc->sc_sunfb.sf_fbsize, BUS_SPACE_MAP_LINEAR,
	    0, &sc->sc_vid_regs) != 0) {
		printf(": cannot map vid registers\n");
		goto fail_vid;
	}

	nam = getpropstring(node, "model");
	if (*nam == '\0')
		nam = sa->sa_name;
	printf(": %s", nam);

	console = cgthree_is_console(node);

	cgthree_reset(sc);
	cgthree_burner(sc, 1, 0);

	sc->sc_sunfb.sf_ro.ri_bits = (void *)bus_space_vaddr(sc->sc_bustag,
	    sc->sc_vid_regs);
	sc->sc_sunfb.sf_ro.ri_hw = sc;

	printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);

	/*
	 * If the framebuffer width is under 1024x768, which is the case for
	 * some clones on laptops, as well as with the VS10-EK, switch from
	 * the PROM font to the more adequate 8x16 font here.
	 * However, we need to adjust two things in this case:
	 * - the display row should be overrided from the current PROM metrics,
	 *   to prevent us from overwriting the last few lines of text.
	 * - if the 80x34 screen would make a large margin appear around it,
	 *   choose to clear the screen rather than keeping old prom output in
	 *   the margins.
	 * XXX there should be a rasops "clear margins" feature
	 */
	fbwscons_init(&sc->sc_sunfb, console &&
	    (sc->sc_sunfb.sf_width >= 1024) ? 0 : RI_CLEAR);

	fbwscons_setcolormap(&sc->sc_sunfb, cgthree_setcolor);

	if (console) {
		fbwscons_console_init(&sc->sc_sunfb,
		    sc->sc_sunfb.sf_width >= 1024 ? -1 : 0);
	}

	fbwscons_attach(&sc->sc_sunfb, &cgthree_accessops, console);

	return;

fail_vid:
	bus_space_unmap(sa->sa_bustag, sc->sc_ctrl_regs, CGTHREE_CTRL_SIZE);
fail_ctrl:
fail:
;
}
Пример #9
0
/*
 * Attach and initialize a rfx display, as well as a child wsdisplay.
 */
void
rfxattach(struct device *parent, struct device *self, void *args)
{
	struct rfx_softc *sc = (struct rfx_softc *)self;
	struct sbus_attach_args *sa = args;
	const char *device = sa->sa_name;
	struct rfx_config cf;
	bus_space_tag_t bt;
	bus_space_handle_t bh;
	int node, cflen, isconsole = 0;

	/* skip vendor name (could be CWARE, VITec, ...) */
	while (*device != ',' && *device != '\0')
		device++;
	if (*device == '\0')
		device = sa->sa_name;
	else
		device++;

	printf(": %s", device);

	if (sa->sa_nreg == 0) {
		printf("\n%s: no SBus registers!\n", self->dv_xname);
		return;
	}

	bt = sa->sa_bustag;
	node = sa->sa_node;
	isconsole = node == fbnode;

	/*
	 * Parse configuration structure
	 */
	cflen = getproplen(node, "configuration");
	if (cflen != sizeof cf) {
		printf(", unknown %d bytes conf. structure", cflen);
		/* fill in default values */
		cf.version = 0;
		cf.scanline = 2048;
		cf.width = 1152;
		cf.height = 900;
	} else {
		OF_getprop(node, "configuration", &cf, cflen);
		printf(", revision %d", cf.version);
	}

	/*
	 * Map registers
	 */

	sc->sc_bustag = bt;
	sc->sc_paddr = sbus_bus_addr(bt, sa->sa_slot, sa->sa_offset);

	if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + RFX_RAMDAC_ADDR,
	    RFX_RAMDAC_SIZE, BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
		printf("\n%s: couldn't map ramdac registers\n", self->dv_xname);
		return;
	}
	sc->sc_ramdac = (u_int8_t *)bus_space_vaddr(bt, bh);

	if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + RFX_CONTROL_ADDR,
	    RFX_CONTROL_SIZE, BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
		printf("\n%s: couldn't map control registers\n", self->dv_xname);
		return;
	}
	sc->sc_ctrl = (u_int32_t *)bus_space_vaddr(bt, bh);

#if 0	/* not yet */
	sc->sc_ih.ih_fun = rfx_intr;
	sc->sc_ih.ih_arg = sc;
	intr_establish(ca->ca_ra.ra_intr[0].int_pri, &sc->sc_ih, IPL_FB);
#endif

	/*
	 * The following is an equivalent for
	 *   fb_setsize(&sc->sc_sunfb, 8, cf.width, cf.height,
	 *     node, ca->ca_bustype);
	 * forcing the correct scan line value. Since the usual frame buffer
	 * properties are missing on this card, no need to go through
	 * fb_setsize()...
	 */
	sc->sc_sunfb.sf_depth = 8;
	sc->sc_sunfb.sf_width = cf.width;
	sc->sc_sunfb.sf_height = cf.height;
	sc->sc_sunfb.sf_linebytes = cf.scanline;
	sc->sc_sunfb.sf_fbsize = cf.height * cf.scanline;

	printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);

	if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + RFX_VRAM_ADDR,
	    round_page(sc->sc_sunfb.sf_fbsize), BUS_SPACE_MAP_LINEAR,
	    0, &bh) != 0) {
		printf("\n%s: couldn't map video memory\n", self->dv_xname);
		return;
	}
	sc->sc_sunfb.sf_ro.ri_bits = bus_space_vaddr(bt, bh);
	sc->sc_sunfb.sf_ro.ri_hw = sc;

	/*
	 * If we are not the console, the frame buffer has not been
	 * initalized by the PROM - do this ourselves.
	 */
	if (!isconsole) {
		if (rfx_initialize(sc, sa, &cf) != 0)
			return;
	}

	fbwscons_init(&sc->sc_sunfb, isconsole ? 0 : RI_CLEAR);

	bzero(&sc->sc_cmap, sizeof(sc->sc_cmap));
	fbwscons_setcolormap(&sc->sc_sunfb, rfx_setcolor);

	if (isconsole) {
		fbwscons_console_init(&sc->sc_sunfb, -1);
	}

	/* enable video */
	rfx_burner(sc, 1, 0);

	fbwscons_attach(&sc->sc_sunfb, &rfx_accessops, isconsole);
}
Пример #10
0
/*
 * Attach and initialize a vigra display, as well as a child wsdisplay.
 */
void
vigraattach(struct device *parent, struct device *self, void *args)
{
	struct vigra_softc *sc = (struct vigra_softc *)self;
	struct sbus_attach_args *sa = args;
	bus_space_tag_t bt;
	bus_space_handle_t bh;
	int node, row, isconsole = 0;
	char *nam;

	bt = sa->sa_bustag;
	node = sa->sa_node;
	nam = getpropstring(node, "model");
	if (*nam == '\0')
		nam = (char *)sa->sa_name;
	printf(": %s", nam);

	isconsole = node == fbnode;

	if (sa->sa_nreg < VIGRA_NREG) {
		printf("\n%s: expected %d registers, got %d",
		    self->dv_xname, VIGRA_NREG, sa->sa_nreg);
		return;
	}

	/*
	 * Check whether we are using an G300 or an G335 chip.
	 * The VS10 and VS12 use the G300, while the VS11 uses a G335.
	 */
	sc->sc_g300 = strncmp(nam, "VIGRA,vs11", strlen("VIGRA,vs11"));

	sc->sc_bustag = bt;
	if (sbus_bus_map(bt, sa->sa_reg[VIGRA_REG_CSR].sbr_slot,
	    sa->sa_reg[VIGRA_REG_CSR].sbr_offset,
	    sa->sa_reg[VIGRA_REG_CSR].sbr_size, BUS_SPACE_MAP_LINEAR, 0,
	    &bh) != 0) {
		printf("\n%s: can't map control registers\n", self->dv_xname);
		return;
	}
	sc->sc_regs = bus_space_vaddr(bt, bh);
	if (sbus_bus_map(bt, sa->sa_reg[VIGRA_REG_RAMDAC].sbr_slot,
	    sa->sa_reg[VIGRA_REG_RAMDAC].sbr_offset,
	    sa->sa_reg[VIGRA_REG_RAMDAC].sbr_size, BUS_SPACE_MAP_LINEAR, 0,
	    &bh) != 0) {
		printf("\n%s: can't map ramdac registers\n", self->dv_xname);
		return;
	}
	sc->sc_ramdac = bus_space_vaddr(bt, bh);

	/* enable video */
	vigra_burner(sc, 1, 0);

	fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, 0);
	if (sbus_bus_map(bt, sa->sa_reg[VIGRA_REG_VRAM].sbr_slot,
	    sa->sa_reg[VIGRA_REG_VRAM].sbr_offset,
	    round_page(sc->sc_sunfb.sf_fbsize), BUS_SPACE_MAP_LINEAR, 0,
	    &bh) != 0) {
		printf("\n%s: can't map video memory\n", self->dv_xname);
		return;
	}
	sc->sc_sunfb.sf_ro.ri_bits = bus_space_vaddr(bt, bh);
	sc->sc_sunfb.sf_ro.ri_hw = sc;
	sc->sc_paddr = sbus_bus_addr(bt, sa->sa_reg[VIGRA_REG_VRAM].sbr_slot,
	    sa->sa_reg[VIGRA_REG_VRAM].sbr_offset);

	printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);

	if ((sc->sc_ih = bus_intr_establish(sa->sa_bustag, sa->sa_pri,
	    IPL_TTY, 0, vigra_intr, sc, self->dv_xname)) == NULL) {
		printf("%s: couldn't establish interrupt, pri %d\n",
		    self->dv_xname, INTLEV(sa->sa_pri));
	}

	/*
	 * If the framebuffer width is under 1024x768, we will switch from the
	 * PROM font to the more adequate 8x16 font here.
	 * However, we need to adjust two things in this case:
	 * - the display row should be overrided from the current PROM metrics,
	 *   to prevent us from overwriting the last few lines of text.
	 * - if the 80x34 screen would make a large margin appear around it,
	 *   choose to clear the screen rather than keeping old prom output in
	 *   the margins.
	 * XXX there should be a rasops "clear margins" feature
	 *
	 * Also, in 1280x1024 resolution, the PROM display is not centered
	 * vertically (why? no other frame buffer does this in such a mode!),
	 * so be lazy and clear the screen here too anyways...
	 */
	fbwscons_init(&sc->sc_sunfb, isconsole && (sc->sc_sunfb.sf_width != 800
	    && sc->sc_sunfb.sf_width != 1280) ? 0 : RI_CLEAR);
	fbwscons_setcolormap(&sc->sc_sunfb, vigra_setcolor);

	if (isconsole) {
		switch (sc->sc_sunfb.sf_width) {
		case 640:
			row = sc->sc_sunfb.sf_ro.ri_rows - 1;
			break;
		case 800:
		case 1280:
			row = 0;	/* screen has been cleared above */
			break;
		default:
			row = -1;
			break;
		}

		fbwscons_console_init(&sc->sc_sunfb, row);
	}

	fbwscons_attach(&sc->sc_sunfb, &vigra_accessops, isconsole);
}