- 10 May, 2017 34 commits
-
-
Ville Syrjälä authored
Bspec tells us that gen3 platforms need 4KiB alignment for CURBASE rather than the 256 byte alignment required by i85x. Let's fix that and pull the code to determine the correct alignment to a helper function. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170327185546.2977-13-ville.syrjala@linux.intel.comReviewed-by: Imre Deak <imre.deak@intel.com>
-
Ville Syrjälä authored
IVB introduced the CUR_FBC_CTL register which allows reducing the cursor height down to 8 lines from the otherwise square cursor dimensions. Implement support for it. CUR_FBC_CTL can't be used when the cursor is rotated. Commandeer the otherwise unused cursor->cursor.size to track the current value of CUR_FBC_CTL to optimize away redundant CUR_FBC_CTL writes, and to notice when we need to arm the update via CURBASE if just CUR_FBC_CTL changes. v2: Reverse the gen check to make it sane v3: Only enable CUR_FBC_CTL when cursor is enabled, adapt to earlier code changes which means we now actually turn off the cursor when we're supposed to unlike v2 v4: Add a comment about rotation vs. CUR_FBC_CTL, rebase due to 'dirty' (Chris) v5: Rebase to the atomic world Handle 180 degree rotation Add HAS_CUR_FBC() v6: Rebase v7: Rebase due to I915_WRITE_FW/uncore.lock s/size/fbc_ctl/ Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170327185546.2977-12-ville.syrjala@linux.intel.comReviewed-by: Imre Deak <imre.deak@intel.com>
-
Ville Syrjälä authored
The cursor code currently ignores fb->pitches[0] (except when creating the fb itself), and just uses the cursor_width*4 as the stride. Let's make sure fb->pitches[0] actually matches what we expect it to be. We can also relax the stride vs. cursor width relationship on 845/865 since the stride is programmed separately. The only constraint is that width*cpp doesn't exceed the stride, and that's already been checked by the core since it makes sure the entire plane fits within the fb. We can also drop the bo size check as that's already checked when we create the fb. That is the fb is guaranteed to fit within the bo. v2: Rebase due to i845_cursor_ctl() and i9xx_cursor_ctl() Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> #v1 Link: http://patchwork.freedesktop.org/patch/msgid/20170327185546.2977-11-ville.syrjala@linux.intel.com
-
Ville Syrjälä authored
We have the maximum cursor dimensions stored in the mode_config, so let's just consult that information instead of hardcoding the same information in multiple places. We still need to keep some per-platform checks as the limitations are quite diverse. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170327185546.2977-10-ville.syrjala@linux.intel.comReviewed-by: Imre Deak <imre.deak@intel.com>
-
Ville Syrjälä authored
The 845/865 and 830/855/9xx+ style cursor don't have that much in common with each other, so let's just split the .check_plane() hook into two variants as well. v2: Keep the common stuff in one place (Chris) v3: s/DRM_FORMAT_MOD_NONE/DRM_FORMAT_MOD_LINEAR/ Cc: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> #v1 Link: http://patchwork.freedesktop.org/patch/msgid/20170327185546.2977-9-ville.syrjala@linux.intel.com
-
Ville Syrjälä authored
There should be no need to do posting reads between all the cursor register accessess. Let's just drop them. v2: Rebase due to I915_WRITE_FW() and uncore.lock Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> #v1 Link: http://patchwork.freedesktop.org/patch/msgid/20170327185546.2977-8-ville.syrjala@linux.intel.com
-
Ville Syrjälä authored
Supposedly on some platforms we can get extra atomicity guarantees for CURPOS if we write it between the CURCNTR and CURBASE. Let's move the CURPOS handling into the platform specific hooks to make the possible without having to pass the calculated CURPOS around. And while at it, do the same for the CURBASE to avoid passing that either. v2: Use I915_WRITE_FW() and grab uncore.lock Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> #v1 Link: http://patchwork.freedesktop.org/patch/msgid/20170327185546.2977-7-ville.syrjala@linux.intel.com
-
Ville Syrjälä authored
Move the CURPOS calculations to seprate function. This will allow sharing the code between the 845/865 vs. others codepaths when we otherwise split them apart. v2: Don't pass intel_plane as it's not needed Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/20170327185546.2977-6-ville.syrjala@linux.intel.com
-
Ville Syrjälä authored
Move cursor_base, cursor_cntl, and cursor_size from intel_crtc into intel_plane so that we don't need the crtc for cursor stuff so much. Also entirely nuke cursor_addr which IMO doesn't provide any benefit since it's not actually used by the cursor code itself. I'm not 100% sure what the SKL+ DDB is code is after by looking at cursor_addr so I just make it do its checks unconditionally. If that's not correct then we should likely replace it with somehting like plane_state->visible. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170327185546.2977-5-ville.syrjala@linux.intel.comReviewed-by: Imre Deak <imre.deak@intel.com>
-
Ville Syrjälä authored
The remaining cursor base address calculations are spread around into several different locations. Just pull it all into one place. v2: Don't pass intel_plane as we don't really need it Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/20170327185546.2977-4-ville.syrjala@linux.intel.com
-
Ville Syrjälä authored
Streamline things by passing intel_plane and intel_crtc instead of the drm types to our plane hooks. v2: s/ilk/g4x/ in sprite code Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/20170327185546.2977-3-ville.syrjala@linux.intel.com
-
Ville Syrjälä authored
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/20170327185546.2977-2-ville.syrjala@linux.intel.com
-
Ville Syrjälä authored
Now that the watermarks are in order, it should be safe to enable sprite planes on g4x. We alreday have the code in fact, we just call it ilk_. Let's rename to g4x_ and let it loose. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170421181432.15216-16-ville.syrjala@linux.intel.comReviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
-
Ville Syrjälä authored
Add a tracepoint for watermark programming on g4x, similar to what we have on vlv/chv. Should help in debugging watermark programming sequence issues. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170421181432.15216-15-ville.syrjala@linux.intel.comReviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
-
Ville Syrjälä authored
I don't see why we couldn't use the HPLL watermarks on g4x. So let's enable them. Let's assume a 35 usec memory latency for the HPLL mode. That's roughly what PNV uses. Based on the behaviour of the ELK box I have 35 usec is probably overkill. Actually all the current latency values used seem overkill as I can reduce them pretty drastically before I start to see underruns. But let's play things a bit safe for now. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170421181432.15216-14-ville.syrjala@linux.intel.comReviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
-
Ville Syrjälä authored
Implement proper two stage watermark programming for g4x. As with other pre-SKL platforms, the watermark registers aren't double buffered on g4x. Hence we must sequence the watermark update carefully around plane updates. The code is quite heavily modelled on the VLV/CHV code, with some fairly significant differences due to the different hardware architecture: * g4x doesn't use inverted watermark values * CxSR actually affects the watermarks since it controls memory self refresh in addition to the max FIFO mode * A further HPLL SR mode is possible with higher memory wakeup latency * g4x has FBC2 and so it also has FBC watermarks * max FIFO mode for primary plane only (cursor is allowed, sprite is not) * g4x has no manual FIFO repartitioning * some TLB miss related workarounds are needed for the watermarks Actually the hardware is quite similar to ILK+ in many ways. The most visible differences are in the actual watermakr register layout. ILK revamped that part quite heavily whereas g4x is still using the layout inherited from earlier platforms. Note that we didn't previously enable the HPLL SR on g4x. So in order to not introduce too many functional changes in this patch I've not actually enabled it here either, even though the code is now fully ready for it. We'll enable it separately later on. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170421181432.15216-13-ville.syrjala@linux.intel.comReviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
-
Ville Syrjälä authored
The documentation I've seen doesn't actually specify which watermarks need the TLB miss w/a. Currently we only apply the w/a to the normal watermarks for both primary and cursor planes. Since the documentation doesn't explicitly say anything I'm going to assume that the w/a should equally apply to the SR/HPLL watermarks. So let's do that. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170421181432.15216-12-ville.syrjala@linux.intel.comReviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
-
Ville Syrjälä authored
All platforms until SKL compute their watermarks essentially using the same method1/small buffer and method2/large buffer formulas. Most just open code it in slightly different ways. Let's pull it all into common helpers. This makes it a little easier to spot the actual differences. While at it try to add some docs explainign what the formulas are trying to do. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170421181432.15216-11-ville.syrjala@linux.intel.comReviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
-
Ville Syrjälä authored
Pull the g4x TLB miss w/a calculation into a small helper. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170421181432.15216-10-ville.syrjala@linux.intel.comReviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
-
Ville Syrjälä authored
The g4x watermark TLB miss workaround requires that we bump up the watermark by the difference between 8 full lines and the FIFO size. Unfortunately the way we compute it at the moment ignores the size of the pixels. The code also used the primary plane width as the cursor width when computing the TLB miss w/a for the cursor. Let's fix both problems. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170421181432.15216-9-ville.syrjala@linux.intel.comReviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
-
Ville Syrjälä authored
The watermark code for the old platforms (g4x and older) uses the primary plane cpp when computing cursor watermarks. To keep the fix simple let's just hardcode cpp=4 for the cursor on those platforms since that's all we support. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170421181432.15216-8-ville.syrjala@linux.intel.comReviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
-
Ville Syrjälä authored
Add some documentation explaining what CxSR actually is. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170421181432.15216-7-ville.syrjala@linux.intel.comReviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
-
Ville Syrjälä authored
The magic numbers 0,1,2 aren't all that interesting for users perhaps. Since we know what these watermark levels mean for VLV/CHV let's print their names. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170421181432.15216-6-ville.syrjala@linux.intel.comReviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
-
Ville Syrjälä authored
We'll be wanting to share some of these watermark structures on g4x, so let's rename them to have a g4x_ prefix instead of vlv_. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170421181432.15216-5-ville.syrjala@linux.intel.comReviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
-
Ville Syrjälä authored
Rename the VLV/CHV max_level->num_levels helper to have an intel_ prefix since it's not VLV/CHV specific and I'll want to use it on other platforms as well. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170421181432.15216-4-ville.syrjala@linux.intel.comReviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
-
Ville Syrjälä authored
Seeing the display FIFO sizes at driver load time doesn't really provide anything useful for us, so let's just drop the debug message. One can always use eg. intel_watermarks to dump out the hardware settings prior to loading the driver. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170421181432.15216-3-ville.syrjala@linux.intel.comReviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
-
Ville Syrjälä authored
Rename some of the vlv wm functions to reflect the fact that they operate on the "raw" watermarks. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170421181432.15216-2-ville.syrjala@linux.intel.comReviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
-
Imre Deak authored
This looks like a left-over from enabling work. The spec defines CH7017_LVDS_PLL_FEEDBACK_DEFAULT_RESERVED as reserved set, so follow this in the programming. v2: - Follow the spec to set CH7017_LVDS_PLL_FEEDBACK_DEFAULT_RESERVED. (Ville) Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1494408113-379-7-git-send-email-imre.deak@intel.com
-
Imre Deak authored
On GEN8+ (not counting CHV) the calculation can in theory result in an incorrect sign extension with all upper bits set. In practice this is unlikely to happen since it would require 4GB of stolen memory set aside. For consistency still prevent the sign extension explicitly everywhere. Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1494408113-379-6-git-send-email-imre.deak@intel.com
-
Imre Deak authored
An error from intel_get_pipe_from_connector() would mean a bug somewhere else, but we still should check for it to prevent some other more obscure bug later. v2: - Fall back to a reasonable default instead of bailing out in case of error. (Jani) v3: - Fix s/PIPE_INVALID/INVALID_PIPE/ typo. (Jani) v4: - Fix bogus bracing around WARN() condition. (Ville) Cc: Jani Nikula <jani.nikula@intel.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1494408113-379-5-git-send-email-imre.deak@intel.com
-
Imre Deak authored
Even though an error from these functions isn't fatal we still want to have a diagnostic message about it. v2: - Don't do assignments in if statements. (Jani) Cc: Jani Nikula <jani.nikula@intel.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1494408113-379-4-git-send-email-imre.deak@intel.com
-
Imre Deak authored
The current code assumes that 'enhancements' won't change in case of an error, but this isn't guaranteed. Fix things by treating any error as a lack of the given capability. v2: - Remove the now redundant init of enhancements. (Ville) Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1494408113-379-3-git-send-email-imre.deak@intel.com
-
Imre Deak authored
The assumptions of these users of drm_dp_dpcd_readb() is that the passed in output buffer won't change in case of error, but this isn't guaranteed. Fix this by treating any error as the lack of the given capability. In case of DP_SINK_DEVICE_AUX_FRAME_SYNC_CAP an error would leave the buffer uninitialized even with the above assumption. Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1494408113-379-2-git-send-email-imre.deak@intel.com
-
Imre Deak authored
The current code looks like a typo, the specification calls for setting bits 31:24 to 0x8C, while preserving bits 23:0. Fix things accordingly. I'm not aware of the typo causing a real problem, so the fix is only for consistency. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1494408113-379-1-git-send-email-imre.deak@intel.com
-
- 09 May, 2017 2 commits
-
-
Mika Kuoppala authored
The assumption is that the registers offsets are identical as with skl. Also all the published kbl firmwares support the debug registers. So let kbl show the debug counts. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100975 Cc: Imre Deak <imre.deak@intel.com> Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com> Reviewed-by: Imre Deak <imre.deak@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1494324322-28193-1-git-send-email-mika.kuoppala@intel.com
-
Michal Wajdeczko authored
In order to allow use of e.g. forcewake_domains in a other feature headers included from the top of i915_drv.h, move all uncore related definitions into their own header. v2: move __mask_next_bit macro to utils header (Mika) Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Suggested-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Cc: Mika Kuoppala <mika.kuoppala@intel.com> Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com> Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
-
- 08 May, 2017 1 commit
-
-
Geliang Tang authored
Use memdup_user_nul() helper instead of open-coding to simplify the code. Signed-off-by: Geliang Tang <geliangtang@gmail.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/6baf3aa45d0b5e0fd016b508bac905ebf8443aac.1493779294.git.geliangtang@gmail.com
-
- 05 May, 2017 1 commit
-
-
Ville Syrjälä authored
Turns out our skills in decoding the CLKCFG register weren't good enough. On this particular elk the answer we got was 400 MHz when in reality the clock was running at 266 MHz, which then caused us to program a bogus AUX clock divider that caused all AUX communication to fail. Sadly the docs are now in bit heaven, so the fix will have to be based on empirical evidence. Using another elk machine I was able to frob the FSB frequency from the BIOS and see how it affects the CLKCFG register. The machine seesm to use a frequency of 266 MHz by default, and fortunately it still boot even with the 50% CPU overclock that we get when we bump the FSB up to 400 MHz. It turns out the actual FSB frequency and the register have no real link whatsoever. The register value is based on some straps or something, but fortunately those too can be configured from the BIOS on this board, although it doesn't seem to respect the settings 100%. In the end I was able to derive the following relationship: BIOS FSB / strap | CLKCFG ------------------------- 200 | 0x2 266 | 0x0 333 | 0x4 400 | 0x4 So only the 200 and 400 MHz cases actually match how we're currently decoding that register. But as the comment next to some of the defines says, we have been just guessing anyway. So let's fix things up so that at least the 266 MHz case will work correctly as that is actually the setting used by both the buggy machine and my test machine. The fact that 333 and 400 MHz BIOS settings result in the same register value is a little disappointing, as that means we can't tell them apart. However, according to the gmch datasheet for both elk and ctg 400 Mhz is not even a supported FSB frequency, so I'm going to make the assumption that we should decode it as 333 MHz instead. Cc: stable@vger.kernel.org Cc: Tomi Sarvela <tomi.p.sarvela@intel.com> Reported-by: Tomi Sarvela <tomi.p.sarvela@intel.com> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100926Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170504181530.6908-1-ville.syrjala@linux.intel.comAcked-by: Jani Nikula <jani.nikula@intel.com> Tested-by: Tomi Sarvela <tomi.p.sarvela@intel.com>
-
- 04 May, 2017 2 commits
-
-
Chris Wilson authored
Typically, there is space available within the ring and if not we have to wait (by definition a slow path). Rearrange the code to reduce the number of branches and stack size for the hotpath, accomodating a slight growth for the wait. v2: Fix the new assert that packets are not larger than the actual ring. v3: Make the parameters unsigned as well to make usage. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170504130846.4807-3-chris@chris-wilson.co.uk
-
Chris Wilson authored
Some callers immediately want to know the current ring->space after calling intel_ring_update_space(), which we can freely provide via the return parameter. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170504130846.4807-2-chris@chris-wilson.co.uk
-