From: Ville Syrjälä ville.syrjala@linux.intel.com
I found these lying around in a branch. Most have r-b or ack from last time [1] (the tegra patch doesn't). I also included the radeon 20bit AUX address fix that seems to have fallen through the cracks as well.
I rebased these on top of my i2c-over-aux retry count series [2] since that fixes a regression and so it's more urgent to get in.
[1] http://lists.freedesktop.org/archives/dri-devel/2015-March/079254.html [2] http://lists.freedesktop.org/archives/dri-devel/2015-August/089250.html
Ville Syrjälä (6): drm/dp: s/I2C_STATUS/I2C_WRITE_STATUS_UPDATE/ drm/i915: Handle DP_AUX_I2C_WRITE_STATUS_UPDATE drm/radeon: Handle DP_AUX_I2C_WRITE_STATUS_UPDATE drm/tegra: Handle I2C_WRITE_STATUS_UPDATE for address only writes drm/dp: Use I2C_WRITE_STATUS_UPDATE to drain partial I2C_WRITE requests drm/radeon: Send out the full AUX address
drivers/gpu/drm/drm_dp_helper.c | 43 ++++++++++++++++++++++++++++++++---- drivers/gpu/drm/i915/intel_dp.c | 1 + drivers/gpu/drm/radeon/atombios_dp.c | 6 +++-- drivers/gpu/drm/tegra/dpaux.c | 3 ++- include/drm/drm_dp_helper.h | 2 +- 5 files changed, 47 insertions(+), 8 deletions(-)
From: Ville Syrjälä ville.syrjala@linux.intel.com
Rename the I2C_STATUS request to I2C_WRITE_STATUS_UPDATE to match the spec.
Acked-by: Alex Deucher alexander.deucher@amd.com Reviewed-by: Jani Nikula jani.nikula@intel.com Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com --- drivers/gpu/drm/tegra/dpaux.c | 2 +- include/drm/drm_dp_helper.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c index 224a7dc..1cc09ff 100644 --- a/drivers/gpu/drm/tegra/dpaux.c +++ b/drivers/gpu/drm/tegra/dpaux.c @@ -149,7 +149,7 @@ static ssize_t tegra_dpaux_transfer(struct drm_dp_aux *aux,
break;
- case DP_AUX_I2C_STATUS: + case DP_AUX_I2C_WRITE_STATUS_UPDATE: if (msg->request & DP_AUX_I2C_MOT) value |= DPAUX_DP_AUXCTL_CMD_MOT_RQ; else diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 499e9f6..d0c8810 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -46,7 +46,7 @@
#define DP_AUX_I2C_WRITE 0x0 #define DP_AUX_I2C_READ 0x1 -#define DP_AUX_I2C_STATUS 0x2 +#define DP_AUX_I2C_WRITE_STATUS_UPDATE 0x2 #define DP_AUX_I2C_MOT 0x4 #define DP_AUX_NATIVE_WRITE 0x8 #define DP_AUX_NATIVE_READ 0x9
From: Ville Syrjälä ville.syrjala@linux.intel.com
When we get an i2c defer or short ack for i2c-over-aux write we need to switch to WRITE_STATUS_UPDATE to poll for the completion of the original request.
i915 doesn't try to interpret wht request type apart from separating reads from writes, and so we should be able to treat this the same as a normal i2c write.
Reviewed-by: Jani Nikula jani.nikula@intel.com Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_dp.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 8a66a44..acd01da 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -974,6 +974,7 @@ intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) switch (msg->request & ~DP_AUX_I2C_MOT) { case DP_AUX_NATIVE_WRITE: case DP_AUX_I2C_WRITE: + case DP_AUX_I2C_WRITE_STATUS_UPDATE: txsize = msg->size ? HEADER_SIZE + msg->size : BARE_ADDRESS_SIZE; rxsize = 2; /* 0 or 1 data bytes */
From: Ville Syrjälä ville.syrjala@linux.intel.com
When we get an i2c defer or short ack for i2c-over-aux write we need to switch to WRITE_STATUS_UPDATE to poll for the completion of the original request.
Looks like radeon doesn't do anything special with the request type, so hopefully just treating it the same as a i2c write is enough.
Cc: Alex Deucher alexander.deucher@amd.com Cc: "Christian König" christian.koenig@amd.com Acked-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com --- drivers/gpu/drm/radeon/atombios_dp.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index f81e0d7..ca372c5 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -178,6 +178,7 @@ radeon_dp_aux_transfer_atom(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) switch (msg->request & ~DP_AUX_I2C_MOT) { case DP_AUX_NATIVE_WRITE: case DP_AUX_I2C_WRITE: + case DP_AUX_I2C_WRITE_STATUS_UPDATE: /* The atom implementation only supports writes with a max payload of * 12 bytes since it uses 4 bits for the total count (header + payload) * in the parameter space. The atom interface supports 16 byte
From: Ville Syrjälä ville.syrjala@linux.intel.com
A address-only I2C_WRITE can't be replied with a short i2c ack, but I suppose it could be replied with an i2c defer. So the code should be prepared for an address-only I2C_WRITE_STATUS_UPDATE.
Cc: Thierry Reding thierry.reding@gmail.com Cc: "Terje Bergström" tbergstrom@nvidia.com Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com --- drivers/gpu/drm/tegra/dpaux.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c index 1cc09ff..6aecb66 100644 --- a/drivers/gpu/drm/tegra/dpaux.c +++ b/drivers/gpu/drm/tegra/dpaux.c @@ -119,6 +119,7 @@ static ssize_t tegra_dpaux_transfer(struct drm_dp_aux *aux, */ if (msg->size < 1) { switch (msg->request & ~DP_AUX_I2C_MOT) { + case DP_AUX_I2C_WRITE_STATUS_UPDATE: case DP_AUX_I2C_WRITE: case DP_AUX_I2C_READ: value = DPAUX_DP_AUXCTL_CMD_ADDRESS_ONLY;
On Thu, Aug 27, 2015 at 05:23:29PM +0300, ville.syrjala@linux.intel.com wrote:
From: Ville Syrjälä ville.syrjala@linux.intel.com
A address-only I2C_WRITE can't be replied with a short i2c ack, but I suppose it could be replied with an i2c defer. So the code should be prepared for an address-only I2C_WRITE_STATUS_UPDATE.
Cc: Thierry Reding thierry.reding@gmail.com Cc: "Terje Bergström" tbergstrom@nvidia.com Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com
drivers/gpu/drm/tegra/dpaux.c | 1 + 1 file changed, 1 insertion(+)
Acked-by: Thierry Reding treding@nvidia.com
From: Ville Syrjälä ville.syrjala@linux.intel.com
When an i2c WRITE gets an i2c defer or short i2c ack reply, we are supposed to switch the request from I2C_WRITE to I2C_WRITE_STATUS_UPDATE when we continue to poll for the completion of the request.
v2: Don't assume DP_AUX_I2C_WRITE is 0 even though it is, to make the code more obvious to the casual reader (Jani)
Acked-by: Alex Deucher alexander.deucher@amd.com Reviewed-by: Jani Nikula jani.nikula@intel.com Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com --- drivers/gpu/drm/drm_dp_helper.c | 43 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index ee5cd86..a717f4c 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -496,6 +496,27 @@ static int drm_dp_i2c_retry_count(const struct drm_dp_aux_msg *msg, return DIV_ROUND_UP(i2c_len, aux_len + AUX_RETRY_INTERVAL); }
+static void drm_dp_i2c_msg_set_request(struct drm_dp_aux_msg *msg, + const struct i2c_msg *i2c_msg) +{ + msg->request = (i2c_msg->flags & I2C_M_RD) ? + DP_AUX_I2C_READ : DP_AUX_I2C_WRITE; + msg->request |= DP_AUX_I2C_MOT; +} + +static void drm_dp_i2c_msg_write_status_update(struct drm_dp_aux_msg *msg) +{ + /* + * In case of i2c defer or short i2c ack reply to a write, + * we need to switch to WRITE_STATUS_UPDATE to drain the + * rest of the message + */ + if ((msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_I2C_WRITE) { + msg->request &= DP_AUX_I2C_MOT; + msg->request |= DP_AUX_I2C_WRITE_STATUS_UPDATE; + } +} + /* * FIXME currently assumes 10 kHz as some real world devices seem * to require it. We should query/set the speed via DPCD if supported. @@ -576,6 +597,8 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) * Both native ACK and I2C ACK replies received. We * can assume the transfer was successful. */ + if (ret != msg->size) + drm_dp_i2c_msg_write_status_update(msg); return ret;
case DP_AUX_I2C_REPLY_NACK: @@ -593,6 +616,7 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) if (defer_i2c < 7) defer_i2c++; usleep_range(AUX_RETRY_INTERVAL, AUX_RETRY_INTERVAL + 100); + drm_dp_i2c_msg_write_status_update(msg); continue;
default: @@ -658,10 +682,7 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
for (i = 0; i < num; i++) { msg.address = msgs[i].addr; - msg.request = (msgs[i].flags & I2C_M_RD) ? - DP_AUX_I2C_READ : - DP_AUX_I2C_WRITE; - msg.request |= DP_AUX_I2C_MOT; + drm_dp_i2c_msg_set_request(&msg, &msgs[i]); /* Send a bare address packet to start the transaction. * Zero sized messages specify an address only (bare * address) transaction. @@ -669,6 +690,13 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, msg.buffer = NULL; msg.size = 0; err = drm_dp_i2c_do_msg(aux, &msg); + + /* + * Reset msg.request in case in case it got + * changed into a WRITE_STATUS_UPDATE. + */ + drm_dp_i2c_msg_set_request(&msg, &msgs[i]); + if (err < 0) break; /* We want each transaction to be as large as possible, but @@ -681,6 +709,13 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, msg.size = min(transfer_size, msgs[i].len - j);
err = drm_dp_i2c_drain_msg(aux, &msg); + + /* + * Reset msg.request in case in case it got + * changed into a WRITE_STATUS_UPDATE. + */ + drm_dp_i2c_msg_set_request(&msg, &msgs[i]); + if (err < 0) break; transfer_size = err;
On Thu, Aug 27, 2015 at 05:23:30PM +0300, ville.syrjala@linux.intel.com wrote:
From: Ville Syrjälä ville.syrjala@linux.intel.com
When an i2c WRITE gets an i2c defer or short i2c ack reply, we are supposed to switch the request from I2C_WRITE to I2C_WRITE_STATUS_UPDATE when we continue to poll for the completion of the request.
v2: Don't assume DP_AUX_I2C_WRITE is 0 even though it is, to make the code more obvious to the casual reader (Jani)
Acked-by: Alex Deucher alexander.deucher@amd.com Reviewed-by: Jani Nikula jani.nikula@intel.com Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com
Applied patches 1-5 to drm-misc, thanks. Some minor context conflicts in this one here that I resolved by juggling drm_dp_i2c_msg_write_status_update a bit upwards.
Thanks, Daniel
drivers/gpu/drm/drm_dp_helper.c | 43 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index ee5cd86..a717f4c 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -496,6 +496,27 @@ static int drm_dp_i2c_retry_count(const struct drm_dp_aux_msg *msg, return DIV_ROUND_UP(i2c_len, aux_len + AUX_RETRY_INTERVAL); }
+static void drm_dp_i2c_msg_set_request(struct drm_dp_aux_msg *msg,
const struct i2c_msg *i2c_msg)
+{
- msg->request = (i2c_msg->flags & I2C_M_RD) ?
DP_AUX_I2C_READ : DP_AUX_I2C_WRITE;
- msg->request |= DP_AUX_I2C_MOT;
+}
+static void drm_dp_i2c_msg_write_status_update(struct drm_dp_aux_msg *msg) +{
- /*
* In case of i2c defer or short i2c ack reply to a write,
* we need to switch to WRITE_STATUS_UPDATE to drain the
* rest of the message
*/
- if ((msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_I2C_WRITE) {
msg->request &= DP_AUX_I2C_MOT;
msg->request |= DP_AUX_I2C_WRITE_STATUS_UPDATE;
- }
+}
/*
- FIXME currently assumes 10 kHz as some real world devices seem
- to require it. We should query/set the speed via DPCD if supported.
@@ -576,6 +597,8 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) * Both native ACK and I2C ACK replies received. We * can assume the transfer was successful. */
if (ret != msg->size)
drm_dp_i2c_msg_write_status_update(msg); return ret;
case DP_AUX_I2C_REPLY_NACK:
@@ -593,6 +616,7 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) if (defer_i2c < 7) defer_i2c++; usleep_range(AUX_RETRY_INTERVAL, AUX_RETRY_INTERVAL + 100);
drm_dp_i2c_msg_write_status_update(msg); continue;
default:
@@ -658,10 +682,7 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
for (i = 0; i < num; i++) { msg.address = msgs[i].addr;
msg.request = (msgs[i].flags & I2C_M_RD) ?
DP_AUX_I2C_READ :
DP_AUX_I2C_WRITE;
msg.request |= DP_AUX_I2C_MOT;
/* Send a bare address packet to start the transaction.drm_dp_i2c_msg_set_request(&msg, &msgs[i]);
- Zero sized messages specify an address only (bare
- address) transaction.
@@ -669,6 +690,13 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, msg.buffer = NULL; msg.size = 0; err = drm_dp_i2c_do_msg(aux, &msg);
/*
* Reset msg.request in case in case it got
* changed into a WRITE_STATUS_UPDATE.
*/
drm_dp_i2c_msg_set_request(&msg, &msgs[i]);
- if (err < 0) break; /* We want each transaction to be as large as possible, but
@@ -681,6 +709,13 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, msg.size = min(transfer_size, msgs[i].len - j);
err = drm_dp_i2c_drain_msg(aux, &msg);
/*
* Reset msg.request in case in case it got
* changed into a WRITE_STATUS_UPDATE.
*/
drm_dp_i2c_msg_set_request(&msg, &msgs[i]);
if (err < 0) break; transfer_size = err;
-- 2.4.6
dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
From: Ville Syrjälä ville.syrjala@linux.intel.com
AUX addresses are 20 bits long. Send out the entire address instead of just the low 16 bits.
Cc: Alex Deucher alexander.deucher@amd.com Cc: "Christian König" christian.koenig@amd.com Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com --- drivers/gpu/drm/radeon/atombios_dp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index ca372c5..bd73b40 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -171,8 +171,9 @@ radeon_dp_aux_transfer_atom(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) return -E2BIG;
tx_buf[0] = msg->address & 0xff; - tx_buf[1] = msg->address >> 8; - tx_buf[2] = msg->request << 4; + tx_buf[1] = (msg->address >> 8) & 0xff; + tx_buf[2] = (msg->request << 4) | + ((msg->address >> 16) & 0xf); tx_buf[3] = msg->size ? (msg->size - 1) : 0;
switch (msg->request & ~DP_AUX_I2C_MOT) {
On Thu, Aug 27, 2015 at 10:23 AM, ville.syrjala@linux.intel.com wrote:
From: Ville Syrjälä ville.syrjala@linux.intel.com
AUX addresses are 20 bits long. Send out the entire address instead of just the low 16 bits.
Cc: Alex Deucher alexander.deucher@amd.com Cc: "Christian König" christian.koenig@amd.com Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com
Applied. thanks!
Alex
drivers/gpu/drm/radeon/atombios_dp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index ca372c5..bd73b40 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -171,8 +171,9 @@ radeon_dp_aux_transfer_atom(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) return -E2BIG;
tx_buf[0] = msg->address & 0xff;
tx_buf[1] = msg->address >> 8;
tx_buf[2] = msg->request << 4;
tx_buf[1] = (msg->address >> 8) & 0xff;
tx_buf[2] = (msg->request << 4) |
((msg->address >> 16) & 0xf); tx_buf[3] = msg->size ? (msg->size - 1) : 0; switch (msg->request & ~DP_AUX_I2C_MOT) {
-- 2.4.6
dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
On Thu, 27 Aug 2015, ville.syrjala@linux.intel.com wrote:
From: Ville Syrjälä ville.syrjala@linux.intel.com
I found these lying around in a branch. Most have r-b or ack from last time [1] (the tegra patch doesn't). I also included the radeon 20bit AUX address fix that seems to have fallen through the cracks as well.
I rebased these on top of my i2c-over-aux retry count series [2] since that fixes a regression and so it's more urgent to get in.
How about pushing both to a branch on some repo, and throwing them at some of the bugs we have open?
BR, Jani.
[1] http://lists.freedesktop.org/archives/dri-devel/2015-March/079254.html [2] http://lists.freedesktop.org/archives/dri-devel/2015-August/089250.html
Ville Syrjälä (6): drm/dp: s/I2C_STATUS/I2C_WRITE_STATUS_UPDATE/ drm/i915: Handle DP_AUX_I2C_WRITE_STATUS_UPDATE drm/radeon: Handle DP_AUX_I2C_WRITE_STATUS_UPDATE drm/tegra: Handle I2C_WRITE_STATUS_UPDATE for address only writes drm/dp: Use I2C_WRITE_STATUS_UPDATE to drain partial I2C_WRITE requests drm/radeon: Send out the full AUX address
drivers/gpu/drm/drm_dp_helper.c | 43 ++++++++++++++++++++++++++++++++---- drivers/gpu/drm/i915/intel_dp.c | 1 + drivers/gpu/drm/radeon/atombios_dp.c | 6 +++-- drivers/gpu/drm/tegra/dpaux.c | 3 ++- include/drm/drm_dp_helper.h | 2 +- 5 files changed, 47 insertions(+), 8 deletions(-)
-- 2.4.6
dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
On Thu, Aug 27, 2015 at 05:34:45PM +0300, Jani Nikula wrote:
On Thu, 27 Aug 2015, ville.syrjala@linux.intel.com wrote:
From: Ville Syrjälä ville.syrjala@linux.intel.com
I found these lying around in a branch. Most have r-b or ack from last time [1] (the tegra patch doesn't). I also included the radeon 20bit AUX address fix that seems to have fallen through the cracks as well.
I rebased these on top of my i2c-over-aux retry count series [2] since that fixes a regression and so it's more urgent to get in.
How about pushing both to a branch on some repo, and throwing them at some of the bugs we have open?
Pushed the lot to: git://github.com/vsyrjala/linux.git i2c_aux_short_write_4
It's sitting top of drm-intel-nightly from a few days ago.
BR, Jani.
[1] http://lists.freedesktop.org/archives/dri-devel/2015-March/079254.html [2] http://lists.freedesktop.org/archives/dri-devel/2015-August/089250.html
Ville Syrjälä (6): drm/dp: s/I2C_STATUS/I2C_WRITE_STATUS_UPDATE/ drm/i915: Handle DP_AUX_I2C_WRITE_STATUS_UPDATE drm/radeon: Handle DP_AUX_I2C_WRITE_STATUS_UPDATE drm/tegra: Handle I2C_WRITE_STATUS_UPDATE for address only writes drm/dp: Use I2C_WRITE_STATUS_UPDATE to drain partial I2C_WRITE requests drm/radeon: Send out the full AUX address
drivers/gpu/drm/drm_dp_helper.c | 43 ++++++++++++++++++++++++++++++++---- drivers/gpu/drm/i915/intel_dp.c | 1 + drivers/gpu/drm/radeon/atombios_dp.c | 6 +++-- drivers/gpu/drm/tegra/dpaux.c | 3 ++- include/drm/drm_dp_helper.h | 2 +- 5 files changed, 47 insertions(+), 8 deletions(-)
-- 2.4.6
dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
-- Jani Nikula, Intel Open Source Technology Center
dri-devel@lists.freedesktop.org