Пример #1
0
/* This is the function that scans the DIO space and works out what
 * hardware is actually present.
 */
static int __init dio_init(void)
{
        int scode;
        struct dioboard *b, *bprev = NULL;
   
        printk("Scanning for DIO devices...\n");
        
        for (scode = 0; scode < DIO_SCMAX; ++scode)
        {
                u_char prid, secid = 0;        /* primary, secondary ID bytes */
                u_char *va;
                
                if (DIO_SCINHOLE(scode))
                        continue;
                
                va = dio_scodetoviraddr(scode);
                if (!va || !hwreg_present(va + DIO_IDOFF))
                        continue;              /* no board present at that select code */

                /* Found a board, allocate it an entry in the list */
                b = kmalloc(sizeof(struct dioboard), GFP_KERNEL);
                
                /* read the ID byte(s) and encode if necessary. Note workaround 
                 * for broken internal HPIB devices...
                 */
                if (!DIO_ISIHPIB(scode))
                        prid = DIO_ID(va);
                else 
                        prid = DIO_ID_IHPIB;
                
                if (DIO_NEEDSSECID(prid))
                {
                        secid = DIO_SECID(va);
                        b->id = DIO_ENCODE_ID(prid, secid);
                }
                else
                        b->id = prid;
      
                b->configured = 0;
                b->scode = scode;
                b->ipl = DIO_IPL(va);
                b->name = dio_getname(b->id);
                printk("select code %3d: ipl %d: ID %02X", scode, b->ipl, prid);
                if (DIO_NEEDSSECID(b->id))
                        printk(":%02X", secid);
                printk(": %s\n", b->name);
                
                b->next = NULL;

                if (bprev)
                        bprev->next = b;
                else
                        blist = b;
                bprev = b;
        }
	return 0;
}
Пример #2
0
int __init dio_find(int deviceid)
{
	/* Called to find a DIO device before the full bus scan has run.
	 * Only used by the console driver.
	 */
	int scode, id;
	u_char prid, secid, i;
	mm_segment_t fs;

	for (scode = 0; scode < DIO_SCMAX; scode++) {
		void *va;
		unsigned long pa;

                if (DIO_SCINHOLE(scode))
                        continue;

                pa = dio_scodetophysaddr(scode);

		if (!pa)
			continue;

		if (scode < DIOII_SCBASE)
			va = (void *)(pa + DIO_VIRADDRBASE);
		else
			va = ioremap(pa, PAGE_SIZE);

		fs = get_fs();
		set_fs(KERNEL_DS);

                if (get_user(i, (unsigned char *)va + DIO_IDOFF)) {
			set_fs(fs);
			if (scode >= DIOII_SCBASE)
				iounmap(va);
                        continue;             /* no board present at that select code */
		}

		set_fs(fs);
		prid = DIO_ID(va);

                if (DIO_NEEDSSECID(prid)) {
                        secid = DIO_SECID(va);
                        id = DIO_ENCODE_ID(prid, secid);
                } else
			id = prid;

		if (id == deviceid) {
			if (scode >= DIOII_SCBASE)
				iounmap(va);
			return scode;
		}
	}

	return -1;
}
Пример #3
0
int __init dio_find(int deviceid)
{
	int scode, id;
	u_char prid, secid, i;
	mm_segment_t fs;

	for (scode = 0; scode < DIO_SCMAX; scode++) {
		void *va;
		unsigned long pa;

                if (DIO_SCINHOLE(scode))
                        continue;

                pa = dio_scodetophysaddr(scode);

		if (!pa)
			continue;

		if (scode < DIOII_SCBASE)
			va = (void *)(pa + DIO_VIRADDRBASE);
		else
			va = ioremap(pa, PAGE_SIZE);

		fs = get_fs();
		set_fs(KERNEL_DS);

                if (get_user(i, (unsigned char *)va + DIO_IDOFF)) {
			set_fs(fs);
			if (scode >= DIOII_SCBASE)
				iounmap(va);
                        continue;             
		}

		set_fs(fs);
		prid = DIO_ID(va);

                if (DIO_NEEDSSECID(prid)) {
                        secid = DIO_SECID(va);
                        id = DIO_ENCODE_ID(prid, secid);
                } else
			id = prid;

		if (id == deviceid) {
			if (scode >= DIOII_SCBASE)
				iounmap(va);
			return scode;
		}
	}

	return -1;
}
Пример #4
0
int __init hpfb_init(void)
{
	unsigned int sid;
	mm_segment_t fs;
	unsigned char i;
	int err;

	/*                                                           
                                                         
                                                         
                                           
   
                                                           
                                                               
  */
#define INTFBVADDR 0xf0560000
#define INTFBPADDR 0x560000

	if (!MACH_IS_HP300)
		return -ENODEV;

	if (fb_get_options("hpfb", NULL))
		return -ENODEV;

	err = dio_register_driver(&hpfb_driver);
	if (err)
		return err;

	fs = get_fs();
	set_fs(KERNEL_DS);
	err = get_user(i, (unsigned char *)INTFBVADDR + DIO_IDOFF);
	set_fs(fs);

	if (!err && (i == DIO_ID_FBUFFER) && topcat_sid_ok(sid = DIO_SECID(INTFBVADDR))) {
		if (!request_mem_region(INTFBPADDR, DIO_DEVSIZE, "Internal Topcat"))
			return -EBUSY;
		printk(KERN_INFO "Internal Topcat found (secondary id %02x)\n", sid);
		if (hpfb_init_one(INTFBPADDR, INTFBVADDR)) {
			return -ENOMEM;
		}
	}
	return 0;
}
Пример #5
0
int __init hpfb_init(void)
{
	unsigned int sid;
	mm_segment_t fs;
	unsigned char i;
	int err;

	/* Topcats can be on the internal IO bus or real DIO devices.
	 * The internal variant sits at 0x560000; it has primary
	 * and secondary ID registers just like the DIO version.
	 * So we merge the two detection routines.
	 *
	 * Perhaps this #define should be in a global header file:
	 * I believe it's common to all internal fbs, not just topcat.
	 */
#define INTFBVADDR 0xf0560000
#define INTFBPADDR 0x560000

	if (!MACH_IS_HP300)
		return -ENXIO;

	if (fb_get_options("hpfb", NULL))
		return -ENODEV;

	err = dio_register_driver(&hpfb_driver);
	if (err)
		return err;

	fs = get_fs();
	set_fs(KERNEL_DS);
	err = get_user(i, (unsigned char *)INTFBVADDR + DIO_IDOFF);
	set_fs(fs);

	if (!err && (i == DIO_ID_FBUFFER) && topcat_sid_ok(sid = DIO_SECID(INTFBVADDR))) {
		if (!request_mem_region(INTFBPADDR, DIO_DEVSIZE, "Internal Topcat"))
			return -EBUSY;
		printk(KERN_INFO "Internal Topcat found (secondary id %02x)\n", sid);
		if (hpfb_init_one(INTFBPADDR, INTFBVADDR)) {
			return -ENOMEM;
		}
	}
	return 0;
}
Пример #6
0
static int __devinit hpfb_init_one(unsigned long phys_base,
				   unsigned long virt_base)
{
	unsigned long fboff, fb_width, fb_height, fb_start;

	fb_regs = virt_base;
	fboff = (in_8(fb_regs + HPFB_FBOMSB) << 8) | in_8(fb_regs + HPFB_FBOLSB);

	fb_info.fix.smem_start = (in_8(fb_regs + fboff) << 16);

	if (phys_base >= DIOII_BASE) {
		fb_info.fix.smem_start += phys_base;
	}

	if (DIO_SECID(fb_regs) != DIO_ID2_TOPCAT) {
		/* This is the magic incantation the HP X server uses to make Catseye boards work. */
		while (in_be16(fb_regs+0x4800) & 1)
			;
		out_be16(fb_regs+0x4800, 0);	/* Catseye status */
		out_be16(fb_regs+0x4510, 0);	/* VB */
		out_be16(fb_regs+0x4512, 0);	/* TCNTRL */
		out_be16(fb_regs+0x4514, 0);	/* ACNTRL */
		out_be16(fb_regs+0x4516, 0);	/* PNCNTRL */
		out_be16(fb_regs+0x4206, 0x90);	/* RUG Command/Status */
		out_be16(fb_regs+0x60a2, 0);	/* Overlay Mask */
		out_be16(fb_regs+0x60bc, 0);	/* Ram Select */
	}

	/*
	 *	Fill in the available video resolution
	 */
	fb_width = (in_8(fb_regs + HPFB_FBWMSB) << 8) | in_8(fb_regs + HPFB_FBWLSB);
	fb_info.fix.line_length = fb_width;
	fb_height = (in_8(fb_regs + HPFB_FBHMSB) << 8) | in_8(fb_regs + HPFB_FBHLSB);
	fb_info.fix.smem_len = fb_width * fb_height;
	fb_start = (unsigned long)ioremap_writethrough(fb_info.fix.smem_start,
						       fb_info.fix.smem_len);
	hpfb_defined.xres = (in_8(fb_regs + HPFB_DWMSB) << 8) | in_8(fb_regs + HPFB_DWLSB);
	hpfb_defined.yres = (in_8(fb_regs + HPFB_DHMSB) << 8) | in_8(fb_regs + HPFB_DHLSB);
	hpfb_defined.xres_virtual = hpfb_defined.xres;
	hpfb_defined.yres_virtual = hpfb_defined.yres;
	hpfb_defined.bits_per_pixel = in_8(fb_regs + HPFB_NUMPLANES);

	printk(KERN_INFO "hpfb: framebuffer at 0x%lx, mapped to 0x%lx, size %dk\n",
	       fb_info.fix.smem_start, fb_start, fb_info.fix.smem_len/1024);
	printk(KERN_INFO "hpfb: mode is %dx%dx%d, linelength=%d\n",
	       hpfb_defined.xres, hpfb_defined.yres, hpfb_defined.bits_per_pixel, fb_info.fix.line_length);

	/*
	 *	Give the hardware a bit of a prod and work out how many bits per
	 *	pixel are supported.
	 */
	out_8(fb_regs + TC_WEN, 0xff);
	out_8(fb_regs + TC_PRR, RR_COPY);
	out_8(fb_regs + TC_FBEN, 0xff);
	out_8(fb_start, 0xff);
	fb_bitmask = in_8(fb_start);
	out_8(fb_start, 0);

	/*
	 *	Enable reading/writing of all the planes.
	 */
	out_8(fb_regs + TC_WEN, fb_bitmask);
	out_8(fb_regs + TC_PRR, RR_COPY);
	out_8(fb_regs + TC_REN, fb_bitmask);
	out_8(fb_regs + TC_FBEN, fb_bitmask);

	/*
	 *	Clear the screen.
	 */
	topcat_blit(0, 0, 0, 0, fb_width, fb_height, RR_CLEAR);

	/*
	 *	Let there be consoles..
	 */
	if (DIO_SECID(fb_regs) == DIO_ID2_TOPCAT)
		strcat(fb_info.fix.id, "Topcat");
	else
		strcat(fb_info.fix.id, "Catseye");
	fb_info.fbops = &hpfb_ops;
	fb_info.flags = FBINFO_DEFAULT;
	fb_info.var   = hpfb_defined;
	fb_info.screen_base = (char *)fb_start;

	fb_alloc_cmap(&fb_info.cmap, 1 << hpfb_defined.bits_per_pixel, 0);

	if (register_framebuffer(&fb_info) < 0) {
		fb_dealloc_cmap(&fb_info.cmap);
		iounmap(fb_info.screen_base);
		fb_info.screen_base = NULL;
		return 1;
	}

	printk(KERN_INFO "fb%d: %s frame buffer device\n",
	       fb_info.node, fb_info.fix.id);

	return 0;
}
Пример #7
0
static int __devinit hpfb_init_one(unsigned long phys_base,
				   unsigned long virt_base)
{
	unsigned long fboff, fb_width, fb_height, fb_start;

	fb_regs = virt_base;
	fboff = (in_8(fb_regs + HPFB_FBOMSB) << 8) | in_8(fb_regs + HPFB_FBOLSB);

	fb_info.fix.smem_start = (in_8(fb_regs + fboff) << 16);

	if (phys_base >= DIOII_BASE) {
		fb_info.fix.smem_start += phys_base;
	}

	if (DIO_SECID(fb_regs) != DIO_ID2_TOPCAT) {
		/*                                                                                 */
		while (in_be16(fb_regs+0x4800) & 1)
			;
		out_be16(fb_regs+0x4800, 0);	/*                */
		out_be16(fb_regs+0x4510, 0);	/*    */
		out_be16(fb_regs+0x4512, 0);	/*        */
		out_be16(fb_regs+0x4514, 0);	/*        */
		out_be16(fb_regs+0x4516, 0);	/*         */
		out_be16(fb_regs+0x4206, 0x90);	/*                    */
		out_be16(fb_regs+0x60a2, 0);	/*              */
		out_be16(fb_regs+0x60bc, 0);	/*            */
	}

	/*
                                          
  */
	fb_width = (in_8(fb_regs + HPFB_FBWMSB) << 8) | in_8(fb_regs + HPFB_FBWLSB);
	fb_info.fix.line_length = fb_width;
	fb_height = (in_8(fb_regs + HPFB_FBHMSB) << 8) | in_8(fb_regs + HPFB_FBHLSB);
	fb_info.fix.smem_len = fb_width * fb_height;
	fb_start = (unsigned long)ioremap_writethrough(fb_info.fix.smem_start,
						       fb_info.fix.smem_len);
	hpfb_defined.xres = (in_8(fb_regs + HPFB_DWMSB) << 8) | in_8(fb_regs + HPFB_DWLSB);
	hpfb_defined.yres = (in_8(fb_regs + HPFB_DHMSB) << 8) | in_8(fb_regs + HPFB_DHLSB);
	hpfb_defined.xres_virtual = hpfb_defined.xres;
	hpfb_defined.yres_virtual = hpfb_defined.yres;
	hpfb_defined.bits_per_pixel = in_8(fb_regs + HPFB_NUMPLANES);

	printk(KERN_INFO "hpfb: framebuffer at 0x%lx, mapped to 0x%lx, size %dk\n",
	       fb_info.fix.smem_start, fb_start, fb_info.fix.smem_len/1024);
	printk(KERN_INFO "hpfb: mode is %dx%dx%d, linelength=%d\n",
	       hpfb_defined.xres, hpfb_defined.yres, hpfb_defined.bits_per_pixel, fb_info.fix.line_length);

	/*
                                                                    
                        
  */
	out_8(fb_regs + TC_WEN, 0xff);
	out_8(fb_regs + TC_PRR, RR_COPY);
	out_8(fb_regs + TC_FBEN, 0xff);
	out_8(fb_start, 0xff);
	fb_bitmask = in_8(fb_start);
	out_8(fb_start, 0);

	/*
                                             
  */
	out_8(fb_regs + TC_WEN, fb_bitmask);
	out_8(fb_regs + TC_PRR, RR_COPY);
	out_8(fb_regs + TC_REN, fb_bitmask);
	out_8(fb_regs + TC_FBEN, fb_bitmask);

	/*
                     
  */
	topcat_blit(0, 0, 0, 0, fb_width, fb_height, RR_CLEAR);

	/*
                           
  */
	if (DIO_SECID(fb_regs) == DIO_ID2_TOPCAT)
		strcat(fb_info.fix.id, "Topcat");
	else
		strcat(fb_info.fix.id, "Catseye");
	fb_info.fbops = &hpfb_ops;
	fb_info.flags = FBINFO_DEFAULT;
	fb_info.var   = hpfb_defined;
	fb_info.screen_base = (char *)fb_start;

	fb_alloc_cmap(&fb_info.cmap, 1 << hpfb_defined.bits_per_pixel, 0);

	if (register_framebuffer(&fb_info) < 0) {
		fb_dealloc_cmap(&fb_info.cmap);
		iounmap(fb_info.screen_base);
		fb_info.screen_base = NULL;
		return 1;
	}

	printk(KERN_INFO "fb%d: %s frame buffer device\n",
	       fb_info.node, fb_info.fix.id);

	return 0;
}
Пример #8
0
/* This is the function that scans the DIO space and works out what
 * hardware is actually present.
 */
static int __init dio_init(void)
{
	int scode;
	mm_segment_t fs;
	int i;
	struct dio_dev *dev;
	int error;

	if (!MACH_IS_HP300)
		return 0;

        printk(KERN_INFO "Scanning for DIO devices...\n");

	/* Initialize the DIO bus */ 
	INIT_LIST_HEAD(&dio_bus.devices);
	dev_set_name(&dio_bus.dev, "dio");
	error = device_register(&dio_bus.dev);
	if (error) {
		pr_err("DIO: Error registering dio_bus\n");
		return error;
	}

	/* Request all resources */
	dio_bus.num_resources = (hp300_model == HP_320 ? 1 : 2);
	for (i = 0; i < dio_bus.num_resources; i++)
		request_resource(&iomem_resource, &dio_bus.resources[i]);

	/* Register all devices */
        for (scode = 0; scode < DIO_SCMAX; ++scode)
        {
                u_char prid, secid = 0;        /* primary, secondary ID bytes */
                u_char *va;
		unsigned long pa;
                
                if (DIO_SCINHOLE(scode))
                        continue;

		pa = dio_scodetophysaddr(scode);

		if (!pa)
			continue;

		if (scode < DIOII_SCBASE)
			va = (void *)(pa + DIO_VIRADDRBASE);
		else
			va = ioremap(pa, PAGE_SIZE);

		fs = get_fs();
		set_fs(KERNEL_DS);

                if (get_user(i, (unsigned char *)va + DIO_IDOFF)) {
			set_fs(fs);
			if (scode >= DIOII_SCBASE)
				iounmap(va);
                        continue;              /* no board present at that select code */
		}

		set_fs(fs);

                /* Found a board, allocate it an entry in the list */
		dev = kzalloc(sizeof(struct dio_dev), GFP_KERNEL);
		if (!dev)
			return 0;

		dev->bus = &dio_bus;
		dev->dev.parent = &dio_bus.dev;
		dev->dev.bus = &dio_bus_type;
		dev->scode = scode;
		dev->resource.start = pa;
		dev->resource.end = pa + DIO_SIZE(scode, va);
		dev_set_name(&dev->dev, "%02x", scode);

                /* read the ID byte(s) and encode if necessary. */
		prid = DIO_ID(va);

                if (DIO_NEEDSSECID(prid)) {
                        secid = DIO_SECID(va);
                        dev->id = DIO_ENCODE_ID(prid, secid);
                } else
                        dev->id = prid;

                dev->ipl = DIO_IPL(va);
                strcpy(dev->name,dio_getname(dev->id));
                printk(KERN_INFO "select code %3d: ipl %d: ID %02X", dev->scode, dev->ipl, prid);
                if (DIO_NEEDSSECID(prid))
                        printk(":%02X", secid);
                printk(": %s\n", dev->name);

		if (scode >= DIOII_SCBASE)
			iounmap(va);
		error = device_register(&dev->dev);
		if (error) {
			pr_err("DIO: Error registering device %s\n",
			       dev->name);
			continue;
		}
		error = dio_create_sysfs_dev_files(dev);
		if (error)
			dev_err(&dev->dev, "Error creating sysfs files\n");
        }
	return 0;
}