- Use the actual clock frequency of the PCI bus instead of assuming

33MHz for calculating the latency timer values for its children.
  Inspired by NetBSD doing the same and Linux as well as OpenSolaris
  using a similar approach.
  While at it rename a variable and change its type to be more
  appropriate fuer values of PCI properties so the variable can be
  more easily reused.
- Initialize the cache line size register of PCI devices to a
  legal value; the cache line size is limited to 64 bytes by the
  Fireplane/Safari, JBus and UPA interconnection busses. Setting
  it to an unsupported value caused bad performance at least with
  GEM as it causes them to not do cache line bursts and to not
  issue cache line commands on the PCI bus.

Approved by:	re (kensmith)
MFC after:	1 week
This commit is contained in:
Marius Strobl 2007-09-26 20:10:36 +00:00
parent 4fabde5686
commit ae3b789193

View File

@ -47,7 +47,6 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/bus_common.h>
#ifndef SUN4V
#include <machine/cache.h>
#include <machine/iommureg.h>
#endif
#include <machine/resource.h>
@ -121,29 +120,31 @@ ofw_pcibus_probe(device_t dev)
static void
ofw_pcibus_setup_device(device_t bridge, u_int busno, u_int slot, u_int func)
{
u_int lat;
#ifndef SUN4V
u_int clnsz;
#endif
uint32_t reg;
/*
* Initialize the latency timer register for busmaster devices to work
* properly. This is another task which the firmware does not always
* perform. The Min_Gnt register can be used to compute it's recommended
* value: it contains the desired latency in units of 1/4 us. To
* calculate the correct latency timer value, a bus clock of 33MHz and
* no wait states should be assumed.
* calculate the correct latency timer value, the clock frequency of
* the bus (defaulting to 33Mhz) should be used and no wait states
* should be assumed.
*/
lat = PCIB_READ_CONFIG(bridge, busno, slot, func, PCIR_MINGNT, 1) *
33 / 4;
if (lat != 0) {
if (OF_getprop(ofw_bus_get_node(bridge), "clock-frequency", &reg,
sizeof(reg)) == -1)
reg = 33000000;
reg = PCIB_READ_CONFIG(bridge, busno, slot, func, PCIR_MINGNT, 1) *
reg / 1000000 / 4;
if (reg != 0) {
#ifdef OFW_PCI_DEBUG
device_printf(bridge, "device %d/%d/%d: latency timer %d -> "
"%d\n", busno, slot, func,
PCIB_READ_CONFIG(bridge, busno, slot, func,
PCIR_LATTIMER, 1), lat);
PCIR_LATTIMER, 1), reg);
#endif /* OFW_PCI_DEBUG */
PCIB_WRITE_CONFIG(bridge, busno, slot, func,
PCIR_LATTIMER, min(lat, 255), 1);
PCIR_LATTIMER, min(reg, 255), 1);
}
#ifndef SUN4V
@ -151,13 +152,11 @@ ofw_pcibus_setup_device(device_t bridge, u_int busno, u_int slot, u_int func)
* Compute a value to write into the cache line size register.
* The role of the streaming cache is unclear in write invalidate
* transfers, so it is made sure that it's line size is always reached.
* Generally, the cache line size is fixed at 64 bytes by Fireplane/
* Safari, JBus and UPA.
*/
clnsz = max(cache.ec_linesize, STRBUF_LINESZ);
KASSERT((clnsz / STRBUF_LINESZ) * STRBUF_LINESZ == clnsz &&
(clnsz / cache.ec_linesize) * cache.ec_linesize == clnsz &&
(clnsz / 4) * 4 == clnsz, ("bogus cache line size %d", clnsz));
PCIB_WRITE_CONFIG(bridge, busno, slot, func, PCIR_CACHELNSZ,
clnsz / 4, 1);
STRBUF_LINESZ / sizeof(uint32_t), 1);
#endif
/*