[PATCH] drm/tegra: dp: Support address-only I2C-over-AUX transactions
Christian König
deathsimple at vodafone.de
Tue Apr 8 07:06:46 PDT 2014
Am 07.04.2014 10:37, schrieb Thierry Reding:
> From: Thierry Reding <treding at nvidia.com>
>
> Certain types of I2C-over-AUX transactions require that only the address
> is transferred. Detect this by looking at the AUX message's size and set
> the address-only bit appropriately.
>
> Signed-off-by: Thierry Reding <treding at nvidia.com>
> ---
> Hi Alex,
>
> This patch is required to make eDP work properly on Tegra with your I2C-
> over-AUX patch series applied. Would you consider carrying this in your
> series so that bisectability can be maintained? It would need to be
> applied prior to the core change (patch 2/4 in the latest series) to do
> so.
Hi Thierry,
do you already have this patch in drm-next or should I send it do Dave
together with the pull request for the dp aux helper changes?
Regards,
Christian.
>
> Thanks,
> Thierry
>
> drivers/gpu/drm/tegra/dpaux.c | 44 ++++++++++++++++++++++++++++++-------------
> drivers/gpu/drm/tegra/dpaux.h | 1 +
> 2 files changed, 32 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c
> index d536ed381fbd..005c19bd92df 100644
> --- a/drivers/gpu/drm/tegra/dpaux.c
> +++ b/drivers/gpu/drm/tegra/dpaux.c
> @@ -99,55 +99,73 @@ static void tegra_dpaux_read_fifo(struct tegra_dpaux *dpaux, u8 *buffer,
> static ssize_t tegra_dpaux_transfer(struct drm_dp_aux *aux,
> struct drm_dp_aux_msg *msg)
> {
> - unsigned long value = DPAUX_DP_AUXCTL_TRANSACTREQ;
> unsigned long timeout = msecs_to_jiffies(250);
> struct tegra_dpaux *dpaux = to_dpaux(aux);
> unsigned long status;
> ssize_t ret = 0;
> + u32 value;
>
> - if (msg->size < 1 || msg->size > 16)
> + /* Tegra has 4x4 byte DP AUX transmit and receive FIFOs. */
> + if (msg->size > 16)
> return -EINVAL;
>
> - tegra_dpaux_writel(dpaux, msg->address, DPAUX_DP_AUXADDR);
> + /*
> + * Allow zero-sized messages only for I2C, in which case they specify
> + * address-only transactions.
> + */
> + if (msg->size < 1) {
> + switch (msg->request & ~DP_AUX_I2C_MOT) {
> + case DP_AUX_I2C_WRITE:
> + case DP_AUX_I2C_READ:
> + value = DPAUX_DP_AUXCTL_CMD_ADDRESS_ONLY;
> + break;
> +
> + default:
> + return -EINVAL;
> + }
> + } else {
> + /* For non-zero-sized messages, set the CMDLEN field. */
> + value = DPAUX_DP_AUXCTL_CMDLEN(msg->size - 1);
> + }
>
> switch (msg->request & ~DP_AUX_I2C_MOT) {
> case DP_AUX_I2C_WRITE:
> if (msg->request & DP_AUX_I2C_MOT)
> - value = DPAUX_DP_AUXCTL_CMD_MOT_WR;
> + value |= DPAUX_DP_AUXCTL_CMD_MOT_WR;
> else
> - value = DPAUX_DP_AUXCTL_CMD_I2C_WR;
> + value |= DPAUX_DP_AUXCTL_CMD_I2C_WR;
>
> break;
>
> case DP_AUX_I2C_READ:
> if (msg->request & DP_AUX_I2C_MOT)
> - value = DPAUX_DP_AUXCTL_CMD_MOT_RD;
> + value |= DPAUX_DP_AUXCTL_CMD_MOT_RD;
> else
> - value = DPAUX_DP_AUXCTL_CMD_I2C_RD;
> + value |= DPAUX_DP_AUXCTL_CMD_I2C_RD;
>
> break;
>
> case DP_AUX_I2C_STATUS:
> if (msg->request & DP_AUX_I2C_MOT)
> - value = DPAUX_DP_AUXCTL_CMD_MOT_RQ;
> + value |= DPAUX_DP_AUXCTL_CMD_MOT_RQ;
> else
> - value = DPAUX_DP_AUXCTL_CMD_I2C_RQ;
> + value |= DPAUX_DP_AUXCTL_CMD_I2C_RQ;
>
> break;
>
> case DP_AUX_NATIVE_WRITE:
> - value = DPAUX_DP_AUXCTL_CMD_AUX_WR;
> + value |= DPAUX_DP_AUXCTL_CMD_AUX_WR;
> break;
>
> case DP_AUX_NATIVE_READ:
> - value = DPAUX_DP_AUXCTL_CMD_AUX_RD;
> + value |= DPAUX_DP_AUXCTL_CMD_AUX_RD;
> break;
>
> default:
> return -EINVAL;
> }
>
> - value |= DPAUX_DP_AUXCTL_CMDLEN(msg->size - 1);
> + tegra_dpaux_writel(dpaux, msg->address, DPAUX_DP_AUXADDR);
> tegra_dpaux_writel(dpaux, value, DPAUX_DP_AUXCTL);
>
> if ((msg->request & DP_AUX_I2C_READ) == 0) {
> @@ -198,7 +216,7 @@ static ssize_t tegra_dpaux_transfer(struct drm_dp_aux *aux,
> break;
> }
>
> - if (msg->reply == DP_AUX_NATIVE_REPLY_ACK) {
> + if ((msg->size > 0) && (msg->reply == DP_AUX_NATIVE_REPLY_ACK)) {
> if (msg->request & DP_AUX_I2C_READ) {
> size_t count = value & DPAUX_DP_AUXSTAT_REPLY_MASK;
>
> diff --git a/drivers/gpu/drm/tegra/dpaux.h b/drivers/gpu/drm/tegra/dpaux.h
> index 4f5bf10fdff9..806e245ca787 100644
> --- a/drivers/gpu/drm/tegra/dpaux.h
> +++ b/drivers/gpu/drm/tegra/dpaux.h
> @@ -32,6 +32,7 @@
> #define DPAUX_DP_AUXCTL_CMD_I2C_RQ (2 << 12)
> #define DPAUX_DP_AUXCTL_CMD_I2C_RD (1 << 12)
> #define DPAUX_DP_AUXCTL_CMD_I2C_WR (0 << 12)
> +#define DPAUX_DP_AUXCTL_CMD_ADDRESS_ONLY (1 << 8)
> #define DPAUX_DP_AUXCTL_CMDLEN(x) ((x) & 0xff)
>
> #define DPAUX_DP_AUXSTAT 0x31
More information about the dri-devel
mailing list