aboutsummaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* Merge remote branch 'keithp/drm-intel-next' of /ssd/git/drm-next into ↵Dave Airlie2011-05-16255-2215/+4602
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | drm-core-next * 'keithp/drm-intel-next' of /ssd/git/drm-next: (301 commits) drm/i915: split PCH clock gating init drm/i915: add Ivybridge clock gating init function drm/i915: Update the location of the ringbuffers' HWS_PGA registers for IVB. drm/i915: Add support for fence registers on Ivybridge. drm/i915: Use existing function instead of open-coding fence reg clear. drm/i915: split clock gating init into per-chipset functions drm/i915: set IBX pch type explicitly drm/i915: add Ivy Bridge PCI IDs and driver feature structs drm/i915: add PantherPoint PCH ID agp/intel: add Ivy Bridge support drm/i915: ring support for Ivy Bridge drm/i915: page flip support for Ivy Bridge drm/i915: interrupt & vblank support for Ivy Bridge drm/i915: treat Ivy Bridge watermarks like Sandy Bridge drm/i915: manual FDI training for Ivy Bridge drm/i915: add swizzle/tiling support for Ivy Bridge drm/i915: Ivy Bridge has split display and pipe control drm/i915: add IS_IVYBRIDGE macro for checks drm/i915: add IS_GEN7 macro to cover Ivy Bridge and later drm/i915: split enable/disable vblank code into chipset specific functions ...
| * drm/i915: split PCH clock gating initJesse Barnes2011-05-135-24/+48
| | | | | | | | | | | | | | | | | | Ibex Peak and CougarPoint already require a different setting (added here), and future chips will likely follow that precedent. Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: add Ivybridge clock gating init functionJesse Barnes2011-05-132-1/+29
| | | | | | | | | | | | | | | | | | | | Some of the bits have changed, including one we were setting that enables a VGA test mode, preventing pipe B from working at all. So add a new IVB specific function with the right bits. Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: Update the location of the ringbuffers' HWS_PGA registers for IVB.Eric Anholt2011-05-132-3/+27
| | | | | | | | | | | | | | | | | | They have been moved from the ringbuffer groups to their own group it looks like. Fixes GPU hangs on gnome startup. Signed-off-by: Eric Anholt <eric@anholt.net> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: Add support for fence registers on Ivybridge.Eric Anholt2011-05-131-0/+2
| | | | | | | | | | | | | | | | | | | | The registers are the same as on Sandybridge. Fixes scrambled display in X when it does software drawing to the GTT, and scans the results out as tiled. Signed-off-by: Eric Anholt <eric@anholt.net> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: Use existing function instead of open-coding fence reg clear.Eric Anholt2011-05-131-18/+3
| | | | | | | | | | | | | | | | This is once less place to miss a new INTEL_INFO(dev)->gen update now. Signed-off-by: Eric Anholt <eric@anholt.net> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: split clock gating init into per-chipset functionsJesse Barnes2011-05-133-146/+195
| | | | | | | | | | | | | | | | This helps contain the mess to init_display() instead. Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: set IBX pch type explicitlyJesse Barnes2011-05-131-1/+5
| | | | | | | | | | | | | | | | | | This is a little less confusing than relying on the implicit zeroing of the dev_priv. Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: add Ivy Bridge PCI IDs and driver feature structsJesse Barnes2011-05-131-0/+20
| | | | | | | | | | | | | | | | | | There are several variants, set feature bits appropriately for both mobile and desktop parts. Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: add PantherPoint PCH IDJesse Barnes2011-05-131-0/+5
| | | | | | | | | | | | | | | | We can treat PantherPoint as CougarPoint as far as display goes. Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com>
| * agp/intel: add Ivy Bridge supportJesse Barnes2011-05-133-0/+21
| | | | | | | | | | | | | | | | Just use the Sandy Bridge routines. Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: ring support for Ivy BridgeJesse Barnes2011-05-131-3/+3
| | | | | | | | | | | | | | | | Use Sandy Bridge paths in a few places. Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: page flip support for Ivy BridgeJesse Barnes2011-05-131-0/+1
| | | | | | | | | | | | | | | | | | Treat Ivy Bridge like previous chips as far as flip submission is concerned. Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: interrupt & vblank support for Ivy BridgeJesse Barnes2011-05-134-2/+195
| | | | | | | | | | | | | | | | Add new interrupt handling functions for Ivy Bridge. Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: treat Ivy Bridge watermarks like Sandy BridgeJesse Barnes2011-05-131-1/+8
| | | | | | | | | | | | | | | | Not fully tested. Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: manual FDI training for Ivy BridgeJesse Barnes2011-05-132-4/+136
| | | | | | | | | | | | | | | | | | A0 stepping chips need to use manual training, but the bits have all moved. So fix things up so we can at least train FDI for VGA links. Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: add swizzle/tiling support for Ivy BridgeJesse Barnes2011-05-131-1/+1
| | | | | | | | | | | | | | | | Treat it like Ironlake and Sandy Bridge. Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: Ivy Bridge has split display and pipe controlJesse Barnes2011-05-131-2/+2
| | | | | | | | | | | | | | | | | | | | Ivy Bridge has a similar split display controller to Sandy Bridge, so use HAS_PCH_SPLIT. And gen7 also has the pipe control instruction, so use HAS_PIPE_CONTROL as well. Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: add IS_IVYBRIDGE macro for checksJesse Barnes2011-05-131-0/+2
| | | | | | | | | | Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: add IS_GEN7 macro to cover Ivy Bridge and laterJesse Barnes2011-05-131-0/+7
| | | | | | | | | | | | | | | | | | Note: IS_GEN* are for render related checks. Display and other checks should use IS_MOBILE, IS_$CHIPSET or test for specific features. Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: split enable/disable vblank code into chipset specific functionsJesse Barnes2011-05-133-11/+37
| | | | | | | | | | | | | | | | This makes the Ironlake+ code trivial and generally simplifies things. Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: split irq handling into per-chipset functionsJesse Barnes2011-05-133-20/+43
| | | | | | | | | | | | | | | | | | | | Set the IRQ handling functions in driver load so they'll just be used directly, rather than branching over most of the code in the chipset functions. Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: make FDI training a display functionJesse Barnes2011-05-132-5/+4
| | | | | | | | | | | | | | | | | | Rather than branching in ironlake_pch_enable, add a new train_fdi function to the display function pointer struct and use it instead. Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: forcewake debugfs fixBen Widawsky2011-05-131-2/+2
| | | | | | | | | | | | | | | | | | Forcewake needs to register itself with drm to use the remove function. The file also should be read only. Signed-off-by: Ben Widawsky <ben@bwidawsk.net> Signed-off-by: Keith Packard <keithp@keithp.com>
| * MAINTAINERS: Switch maintainer for drm/i915 to Keith PackardKeith Packard2011-05-111-2/+2
| | | | | | | | Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: debugfs interface for forcewake reference countBen Widawsky2011-05-101-0/+80
| | | | | | | | | | | | | | | | | | forcewake is controlled by the open and close of the debugfs file. This assures that buggy applications cannot cause the GT to stay on forever. Signed-off-by: Ben Widawsky <ben@bwidawsk.net> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: move gen6 rps handling to workqueueBen Widawsky2011-05-105-9/+58
| | | | | | | | | | | | | | | | | | | | | | | | The render P-state handling code requires reading from a GT register. This means that FORCEWAKE must be written to, a resource which is shared and should be protected by struct_mutex. Hence we can not manipulate that register from within the interrupt handling and so must delegate the task to a workqueue. Signed-off-by: Ben Widawsky <ben@bwidawsk.net> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: forcewake struct mutex locking fixesBen Widawsky2011-05-102-2/+17
| | | | | | | | | | | | | | | | | | Found by the new strict checking for the mutex being held whilst manipulating the forcewake status. Signed-off-by: Ben Widawsky <ben@bwidawsk.net> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: reference counted forcewakeBen Widawsky2011-05-105-13/+41
| | | | | | | | | | | | | | | | | | | | | | | | Provide a reference count to track the forcewake state of the GPU and give a safe mechanism for userspace to wake the GT. This also potentially saves a UC read if the GT is known to be awake already. The reference count is atomic, but the register access and hardware wake sequence is protected by struct_mutex. Signed-off-by: Ben Widawsky <ben@bwidawsk.net> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
| * drm/i915: proper use of forcewakeBen Widawsky2011-05-102-46/+37
| | | | | | | | | | | | | | | | | | | | | | | | | | Moved the macros around to properly do reads and writes for the given GPU. This is to address special requirements for gen6 (SNB) reads and writes. Registers in the range 0-0x40000 on gen6 platforms require special handling. Instead of relying on the callers to pick the registers correctly, move the logic into the read and write functions. Signed-off-by: Ben Widawsky <ben@bwidawsk.net> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
| * drm/i915: Disable all outputs early, before KMS takeoverChris Wilson2011-05-103-15/+34
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If the outputs are active and continuing to access the GATT when we teardown the PTEs, then there is a potential for us to hang the GPU. The hang tends to be a PGTBL_ER with either an invalid host access or an invalid display plane fetch. v2: Reorder IRQ initialisation to defer until after GEM is setup. Reported-by: Pekka Enberg <penberg@kernel.org> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Tested-by: Daniel Vetter <daniel.vetter@ffwll.ch> (855GM) Tested-by: Pekka Enberg <penberg@kernel.org> # note that this doesn't fix the underlying problem of the PGTBL_ER and pipe underruns being reported immediately upon init on his 965GM MacBook Reported-and-tested-by: Rick Bramley <richard.bramley@hp.com> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=35635 Reported-and-tested-by: Zdenek Kabelac <zdenek.kabelac@gmail.com> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=36048 Reviewed-by: Ben Widawsky <ben@bwidawsk.net>
| * drm/i915: Do not clflush snooped objectsChris Wilson2011-05-101-0/+11
| | | | | | | | | | | | | | | | | | | | | | Rely on the GPU snooping into the CPU cache for appropriately bound objects on MI_FLUSH. Or perhaps one day we will have a cache-coherent CPU/GPU package... Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Eric Anholt <eric@anholt.net> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: Rename agp_type to cache_levelChris Wilson2011-05-106-18/+48
| | | | | | | | | | | | | | | | | | | | | | ... to clarify just how we use it inside the driver and remove the confusion of the poorly matching agp_type names. We still need to translate through agp_type for interface into the fake AGP driver. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Eric Anholt <eric@anholt.net> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: debugfs for context informationBen Widawsky2011-05-101-0/+25
| | | | | | | | | | | | | | | | | | Currently this is only useful for the rc6 stuff. But this would also be useful when I finally get around to the logical context + ppgtt stuff. Signed-off-by: Ben Widawsky <ben@bwidawsk.net> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: use i915_enable_rc6 on SNB tooJesse Barnes2011-05-101-3/+6
| | | | | | | | | | | | | | | | For debug & testing. Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Reviewed-by: Ben Widawsky <ben@bwidawsk.net> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
| * drm/i915: fix rc6 initialization on IronlakeBen Widawsky2011-05-101-0/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | There is a race condition between setting PWRCTXA and executing MI_SET_CONTEXT. PWRCTXA must not be set until a valid context has been written (or else the GPU could possible go into rc6, and return to an invalid context). Reported-and-Tested-by: Gu Rui <chaos.proton@gmail.com> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=28582 Signed-off-by: Ben Widawsky <ben@bwidawsk.net> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/1915: ringbuffer wait for idle functionBen Widawsky2011-05-103-2/+8
| | | | | | | | | | | | | | | | | | | | | | Added a new function which waits for the ringbuffer space to be equal to (total - 8). This is the empty condition of the ringbuffer, and equivalent to head==tail. Also modified two users of this functionality elsewhere in the code. Signed-off-by: Ben Widawsky <ben@bwidawsk.net> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
| * drm/i915: fix ilk rc6 teardown lockingBen Widawsky2011-05-101-3/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | In the failure cases during rc6 initialization, both the power context and render context may get !refcount without holding struct_mutex. However, on rc6 disabling, the lock is held by the caller. Rearranged the locking so that it's safe in both cases. Signed-off-by: Ben Widawsky <ben@bwidawsk.net> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: Fold the DPLL limit defines into the structs that use them.Eric Anholt2011-05-101-469/+181
| | | | | | | | | | | | | | | | | | | | | | | | | | They're used in one place, and not providing any descriptive value, with their names just being approximately the conjunction of the struct name and the struct field. This diff was produced with gcc -E, copying the new struct definitions out, moving a couple of the old comments into place in the new structs, and reindenting. Signed-off-by: Eric Anholt <eric@anholt.net> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
| * drm/i915: Clean up leftover DPLL and LVDS register choice from pch split.Eric Anholt2011-05-101-35/+22
| | | | | | | | | | | | | | | | | | We used to have these from the product of (pch, non-pch) * (pipe a, pipe b). Now we can just use the nice per-pipe reg macros in the split out crtc_mode_sets. Signed-off-by: Eric Anholt <eric@anholt.net> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
| * drm/i915: Drop remaining pre-Ironlake code from ironlake_crtc_mode_set().Eric Anholt2011-05-101-83/+36
| | | | | | | | | | Signed-off-by: Eric Anholt <eric@anholt.net> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
| * drm/i915: Drop non-HAS_PCH_SPLIT() code from ironlake_crtc_mode_set().Eric Anholt2011-05-101-209/+150
| | | | | | | | | | | | | | Ironlake is where the PCH split started. Signed-off-by: Eric Anholt <eric@anholt.net> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
| * drm/i915: Drop the remaining bit of Ironlake code from i9xx_crtc_mode_set().Eric Anholt2011-05-101-6/+0
| | | | | | | | | | | | Signed-off-by: Eric Anholt <eric@anholt.net> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
| * drm/i915: Drop the eDP paths from the pre-Ironlake crtc_mode_set.Eric Anholt2011-05-101-33/+24
| | | | | | | | | | | | | | | | While g4x had DP, eDP came with Ironlake, so we don't need that code here. Signed-off-by: Eric Anholt <eric@anholt.net> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
| * drm/i915: Remove the PCH paths from the pre-Ironlake crtc_mode_set().Eric Anholt2011-05-101-258/+23
| | | | | | | | | | | | Signed-off-by: Eric Anholt <eric@anholt.net> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
| * drm/i915: Move the vblank pre/post modeset to the common crtc_mode_set.Eric Anholt2011-05-101-10/+6
| | | | | | | | | | | | Signed-off-by: Eric Anholt <eric@anholt.net> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
| * drm/i915: Split the crtc_mode_set function along HAS_PCH_SPLIT() lines.Eric Anholt2011-05-102-7/+680
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This path, which shouldn't be *that* complicated, is now so littered with per-chipset tweaks that it's hard to trace the order of what happens. HAS_PCH_SPLIT() is the most radical change across chipsets, so it seems like a natural split to simplify the code. This first commit just copies the existing code without changing anything. v2: updated to track removal of call to intel_enable_plane from i9xx_crtc_mode_set Signed-off-by: Eric Anholt <eric@anholt.net> Hella-acked-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
| * drm/i915: Attach a fb to the load-detect pipeChris Wilson2011-05-102-17/+128
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We need to ensure that we feed valid memory into the display plane attached to the pipe when switching the pipe on. Otherwise, the display engine may read through an invalid PTE and so throw an PGTBL_ER exception. As we need to perform load detection before even the first object is allocated for the fbdev, there is no pre-existing object large enough for us to borrow to use as the framebuffer. So we need to create one and cleanup afterwards. At other times, the current fbcon may be large enough for us to borrow it for duration of load detection. Found by assert_fb_bound_for_plane(). Reported-by: Knut Petersen <Knut_Petersen@t-online.de> References: https://bugs.freedesktop.org/show_bug.cgi?id=36246 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: Remove dead code from intel_release_load_detect_pipe()Chris Wilson2011-05-101-5/+3
| | | | | | | | | | | | | | | | | | As we now never attempt to steal a crtc for load detection, we either set a mode on a new pipe, or change the dpms mode on an existing pipe. Never both, so we can simplify the code slightly. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Keith Packard <keithp@keithp.com>
| * drm/i915: Remove dead code from intel_get_load_detect_pipe()Chris Wilson2011-05-101-18/+10
| | | | | | | | | | | | | | | | | | As we only allow the use of a disabled CRTC, we don't need to handle the case where we are reusing an already enabled pipe. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com>