- 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:
parent
4fabde5686
commit
ae3b789193
@ -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", ®,
|
||||
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
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user