static void sba_hw_init()

in sba_iommu.c [1521:1674]


static void sba_hw_init(struct sba_device *sba_dev)
{ 
	int i;
	int num_ioc;
	u64 ioc_ctl;

	if (!is_pdc_pat()) {
		/* Shutdown the USB controller on Astro-based workstations.
		** Once we reprogram the IOMMU, the next DMA performed by
		** USB will HPMC the box. USB is only enabled if a
		** keyboard is present and found.
		**
		** With serial console, j6k v5.0 firmware says:
		**   mem_kbd hpa 0xfee003f8 sba 0x0 pad 0x0 cl_class 0x7
		**
		** FIXME: Using GFX+USB console at power up but direct
		**	linux to serial console is still broken.
		**	USB could generate DMA so we must reset USB.
		**	The proper sequence would be:
		**	o block console output
		**	o reset USB device
		**	o reprogram serial port
		**	o unblock console output
		*/
		if (PAGE0->mem_kbd.cl_class == CL_KEYBD) {
			pdc_io_reset_devices();
		}

	}


#if 0
printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa,
	PAGE0->mem_boot.spa, PAGE0->mem_boot.pad, PAGE0->mem_boot.cl_class);

	/*
	** Need to deal with DMA from LAN.
	**	Maybe use page zero boot device as a handle to talk
	**	to PDC about which device to shutdown.
	**
	** Netbooting, j6k v5.0 firmware says:
	** 	mem_boot hpa 0xf4008000 sba 0x0 pad 0x0 cl_class 0x1002
	** ARGH! invalid class.
	*/
	if ((PAGE0->mem_boot.cl_class != CL_RANDOM)
		&& (PAGE0->mem_boot.cl_class != CL_SEQU)) {
			pdc_io_reset();
	}
#endif

	if (!IS_PLUTO(sba_dev->dev)) {
		ioc_ctl = READ_REG(sba_dev->sba_hpa+IOC_CTRL);
		DBG_INIT("%s() hpa 0x%lx ioc_ctl 0x%Lx ->",
			__func__, sba_dev->sba_hpa, ioc_ctl);
		ioc_ctl &= ~(IOC_CTRL_RM | IOC_CTRL_NC | IOC_CTRL_CE);
		ioc_ctl |= IOC_CTRL_DD | IOC_CTRL_D4 | IOC_CTRL_TC;
			/* j6700 v1.6 firmware sets 0x294f */
			/* A500 firmware sets 0x4d */

		WRITE_REG(ioc_ctl, sba_dev->sba_hpa+IOC_CTRL);

#ifdef DEBUG_SBA_INIT
		ioc_ctl = READ_REG64(sba_dev->sba_hpa+IOC_CTRL);
		DBG_INIT(" 0x%Lx\n", ioc_ctl);
#endif
	} /* if !PLUTO */

	if (IS_ASTRO(sba_dev->dev)) {
		int err;
		sba_dev->ioc[0].ioc_hpa = ioc_remap(sba_dev, ASTRO_IOC_OFFSET);
		num_ioc = 1;

		sba_dev->chip_resv.name = "Astro Intr Ack";
		sba_dev->chip_resv.start = PCI_F_EXTEND | 0xfef00000UL;
		sba_dev->chip_resv.end   = PCI_F_EXTEND | (0xff000000UL - 1) ;
		err = request_resource(&iomem_resource, &(sba_dev->chip_resv));
		BUG_ON(err < 0);

	} else if (IS_PLUTO(sba_dev->dev)) {
		int err;

		sba_dev->ioc[0].ioc_hpa = ioc_remap(sba_dev, PLUTO_IOC_OFFSET);
		num_ioc = 1;

		sba_dev->chip_resv.name = "Pluto Intr/PIOP/VGA";
		sba_dev->chip_resv.start = PCI_F_EXTEND | 0xfee00000UL;
		sba_dev->chip_resv.end   = PCI_F_EXTEND | (0xff200000UL - 1);
		err = request_resource(&iomem_resource, &(sba_dev->chip_resv));
		WARN_ON(err < 0);

		sba_dev->iommu_resv.name = "IOVA Space";
		sba_dev->iommu_resv.start = 0x40000000UL;
		sba_dev->iommu_resv.end   = 0x50000000UL - 1;
		err = request_resource(&iomem_resource, &(sba_dev->iommu_resv));
		WARN_ON(err < 0);
	} else {
		/* IKE, REO */
		sba_dev->ioc[0].ioc_hpa = ioc_remap(sba_dev, IKE_IOC_OFFSET(0));
		sba_dev->ioc[1].ioc_hpa = ioc_remap(sba_dev, IKE_IOC_OFFSET(1));
		num_ioc = 2;

		/* TODO - LOOKUP Ike/Stretch chipset mem map */
	}
	/* XXX: What about Reo Grande? */

	sba_dev->num_ioc = num_ioc;
	for (i = 0; i < num_ioc; i++) {
		void __iomem *ioc_hpa = sba_dev->ioc[i].ioc_hpa;
		unsigned int j;

		for (j=0; j < sizeof(u64) * ROPES_PER_IOC; j+=sizeof(u64)) {

			/*
			 * Clear ROPE(N)_CONFIG AO bit.
			 * Disables "NT Ordering" (~= !"Relaxed Ordering")
			 * Overrides bit 1 in DMA Hint Sets.
			 * Improves netperf UDP_STREAM by ~10% for bcm5701.
			 */
			if (IS_PLUTO(sba_dev->dev)) {
				void __iomem *rope_cfg;
				unsigned long cfg_val;

				rope_cfg = ioc_hpa + IOC_ROPE0_CFG + j;
				cfg_val = READ_REG(rope_cfg);
				cfg_val &= ~IOC_ROPE_AO;
				WRITE_REG(cfg_val, rope_cfg);
			}

			/*
			** Make sure the box crashes on rope errors.
			*/
			WRITE_REG(HF_ENABLE, ioc_hpa + ROPE0_CTL + j);
		}

		/* flush out the last writes */
		READ_REG(sba_dev->ioc[i].ioc_hpa + ROPE7_CTL);

		DBG_INIT("	ioc[%d] ROPE_CFG 0x%Lx  ROPE_DBG 0x%Lx\n",
				i,
				READ_REG(sba_dev->ioc[i].ioc_hpa + 0x40),
				READ_REG(sba_dev->ioc[i].ioc_hpa + 0x50)
			);
		DBG_INIT("	STATUS_CONTROL 0x%Lx  FLUSH_CTRL 0x%Lx\n",
				READ_REG(sba_dev->ioc[i].ioc_hpa + 0x108),
				READ_REG(sba_dev->ioc[i].ioc_hpa + 0x400)
			);

		if (IS_PLUTO(sba_dev->dev)) {
			sba_ioc_init_pluto(sba_dev->dev, &(sba_dev->ioc[i]), i);
		} else {
			sba_ioc_init(sba_dev->dev, &(sba_dev->ioc[i]), i);
		}
	}
}