Esempio n. 1
0
void
bcm_mbox_write(int channel, uint32_t data)
{
	device_t mbox;

        mbox = devclass_get_device(devclass_find("mbox"), 0);

        if (mbox)
                MBOX_WRITE(mbox, channel, data);
}
Esempio n. 2
0
static void
bcm_fb_init(void *arg)
{
	volatile struct bcm_fb_config *fb_config;
	struct bcmsc_softc *sc;
	struct fb_info *info;
	phandle_t node;
	pcell_t cell;
	device_t mbox;
	device_t fbd;
	int err = 0;

	sc = arg;
	fb_config = sc->fb_config;
	node = ofw_bus_get_node(sc->dev);

	fb_config->xres = 0;
	fb_config->yres = 0;
	fb_config->bpp = 0;
	fb_config->vxres = 0;
	fb_config->vyres = 0;
	fb_config->xoffset = 0;
	fb_config->yoffset = 0;
	fb_config->base = 0;
	fb_config->pitch = 0;
	fb_config->screen_size = 0;

	if ((OF_getprop(node, "broadcom,width", &cell, sizeof(cell))) > 0)
		fb_config->xres = (int)fdt32_to_cpu(cell);
	if (fb_config->xres == 0)
		fb_config->xres = FB_WIDTH;

	if ((OF_getprop(node, "broadcom,height", &cell, sizeof(cell))) > 0)
		fb_config->yres = (uint32_t)fdt32_to_cpu(cell);
	if (fb_config->yres == 0)
		fb_config->yres = FB_HEIGHT;

	if ((OF_getprop(node, "broadcom,depth", &cell, sizeof(cell))) > 0)
		fb_config->bpp = (uint32_t)fdt32_to_cpu(cell);
	if (fb_config->bpp == 0)
		fb_config->bpp = FB_DEPTH;

	bus_dmamap_sync(sc->dma_tag, sc->dma_map,
		BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);

	mbox = devclass_get_device(devclass_find("mbox"), 0);
	if (mbox) {
		MBOX_WRITE(mbox, BCM2835_MBOX_CHAN_FB, sc->fb_config_phys);
		MBOX_READ(mbox, BCM2835_MBOX_CHAN_FB, &err);
	}
	bus_dmamap_sync(sc->dma_tag, sc->dma_map,
		BUS_DMASYNC_POSTREAD);

	if (fb_config->base != 0) {
		device_printf(sc->dev, "%dx%d(%dx%d@%d,%d) %dbpp\n",
			fb_config->xres, fb_config->yres,
			fb_config->vxres, fb_config->vyres,
			fb_config->xoffset, fb_config->yoffset,
			fb_config->bpp);

		device_printf(sc->dev, "pitch %d, base 0x%08x, screen_size %d\n",
			fb_config->pitch, fb_config->base,
			fb_config->screen_size);

		info = malloc(sizeof(struct fb_info), M_DEVBUF,
		    M_WAITOK | M_ZERO);
		info->fb_name = device_get_nameunit(sc->dev);
		info->fb_vbase = (intptr_t)pmap_mapdev(fb_config->base,
		    fb_config->screen_size);
		info->fb_pbase = fb_config->base;
		info->fb_size = fb_config->screen_size;
		info->fb_bpp = info->fb_depth = fb_config->bpp;
		info->fb_stride = fb_config->pitch;
		info->fb_width = fb_config->xres;
		info->fb_height = fb_config->yres;

		sc->info = info;

		fbd = device_add_child(sc->dev, "fbd",
		    device_get_unit(sc->dev));
		if (fbd == NULL) {
			device_printf(sc->dev, "Failed to add fbd child\n");
			return;
		}
		if (device_probe_and_attach(fbd) != 0) {
			device_printf(sc->dev, "Failed to attach fbd device\n");
			return;
		}
	} else {
		device_printf(sc->dev, "Failed to set framebuffer info\n");
		return;
	}

	config_intrhook_disestablish(&sc->init_hook);
}
Esempio n. 3
0
static int
bcm2835_mbox_call_prop(struct bcm2835_cpufreq_softc *sc)
{
	struct bcm2835_mbox_hdr *msg = (struct bcm2835_mbox_hdr *)sc->dma_buf;
	struct bcm2835_mbox_tag_hdr *tag, *last;
	uint8_t *up;
	device_t mbox;
	size_t hdr_size;
	int idx;
	int err;

	/*
	 * For multiple calls, locking is not here. The caller must have
	 * VC semaphore.
	 */

	/* get mbox device */
	mbox = devclass_get_device(devclass_find("mbox"), 0);
	if (mbox == NULL) {
		device_printf(sc->dev, "can't find mbox\n");
		return (-1);
	}

	/* go mailbox property */
#ifdef PROP_DEBUG
	bcm2835_dump(msg, 64);
#endif
	bus_dmamap_sync(sc->dma_tag, sc->dma_map,
	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
	MBOX_WRITE(mbox, BCM2835_MBOX_CHAN_PROP, (uint32_t)sc->dma_phys);
	MBOX_READ(mbox, BCM2835_MBOX_CHAN_PROP, &err);
	bus_dmamap_sync(sc->dma_tag, sc->dma_map, BUS_DMASYNC_POSTREAD);
#ifdef PROP_DEBUG
	bcm2835_dump(msg, 64);
#endif

	/* check response code */
	if (msg->code != BCM2835_MBOX_CODE_RESP_SUCCESS) {
		device_printf(sc->dev, "mbox response error\n");
		return (-1);
	}

	/* tag = first tag */
	up = (uint8_t *)msg;
	hdr_size = sizeof(struct bcm2835_mbox_hdr);
	tag = (struct bcm2835_mbox_tag_hdr *)(up + hdr_size);
	/* last = end of buffer specified by header */
	last = (struct bcm2835_mbox_tag_hdr *)(up + msg->buf_size);

	/* loop unitl end tag (=0x0) */
	hdr_size = sizeof(struct bcm2835_mbox_tag_hdr);
	for (idx = 0; tag->tag != 0; idx++) {
		if ((tag->val_len & BCM2835_MBOX_TAG_VAL_LEN_RESPONSE) == 0) {
			device_printf(sc->dev, "tag%d response error\n", idx);
			return (-1);
		}
		/* clear response bit */
		tag->val_len &= ~BCM2835_MBOX_TAG_VAL_LEN_RESPONSE;

		/* get next tag */
		up = (uint8_t *)tag;
		tag = (struct bcm2835_mbox_tag_hdr *)(up + hdr_size +
		    tag->val_buf_size);

		/* check buffer size of header */
		if (tag > last) {
			device_printf(sc->dev, "mbox buffer size error\n");
			return (-1);
		}
	}

	return (0);
}