drm/intel: refactor DP i2c support and DP common header to drm helper
Both radeon and nouveau can re-use this code so move it up a level so they can. However the hw interfaces for aux ch are different enough that the code to translate from mode, address, bytes to actual hw interfaces isn't generic, so move that code into the Intel driver. Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
85bb0c377f
commit
ab2c067298
|
@ -15,7 +15,7 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \
|
||||||
|
|
||||||
drm-$(CONFIG_COMPAT) += drm_ioc32.o
|
drm-$(CONFIG_COMPAT) += drm_ioc32.o
|
||||||
|
|
||||||
drm_kms_helper-y := drm_fb_helper.o drm_crtc_helper.o
|
drm_kms_helper-y := drm_fb_helper.o drm_crtc_helper.o drm_dp_i2c_helper.o
|
||||||
|
|
||||||
obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
|
obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
|
||||||
|
|
||||||
|
|
|
@ -28,84 +28,20 @@
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include "intel_dp.h"
|
#include "drm_dp_helper.h"
|
||||||
#include "drmP.h"
|
#include "drmP.h"
|
||||||
|
|
||||||
/* Run a single AUX_CH I2C transaction, writing/reading data as necessary */
|
/* Run a single AUX_CH I2C transaction, writing/reading data as necessary */
|
||||||
|
|
||||||
#define MODE_I2C_START 1
|
|
||||||
#define MODE_I2C_WRITE 2
|
|
||||||
#define MODE_I2C_READ 4
|
|
||||||
#define MODE_I2C_STOP 8
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter, int mode,
|
i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter, int mode,
|
||||||
uint8_t write_byte, uint8_t *read_byte)
|
uint8_t write_byte, uint8_t *read_byte)
|
||||||
{
|
{
|
||||||
struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
|
struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
|
||||||
uint16_t address = algo_data->address;
|
|
||||||
uint8_t msg[5];
|
|
||||||
uint8_t reply[2];
|
|
||||||
int msg_bytes;
|
|
||||||
int reply_bytes;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Set up the command byte */
|
ret = (*algo_data->aux_ch)(adapter, mode,
|
||||||
if (mode & MODE_I2C_READ)
|
write_byte, read_byte);
|
||||||
msg[0] = AUX_I2C_READ << 4;
|
return ret;
|
||||||
else
|
|
||||||
msg[0] = AUX_I2C_WRITE << 4;
|
|
||||||
|
|
||||||
if (!(mode & MODE_I2C_STOP))
|
|
||||||
msg[0] |= AUX_I2C_MOT << 4;
|
|
||||||
|
|
||||||
msg[1] = address >> 8;
|
|
||||||
msg[2] = address;
|
|
||||||
|
|
||||||
switch (mode) {
|
|
||||||
case MODE_I2C_WRITE:
|
|
||||||
msg[3] = 0;
|
|
||||||
msg[4] = write_byte;
|
|
||||||
msg_bytes = 5;
|
|
||||||
reply_bytes = 1;
|
|
||||||
break;
|
|
||||||
case MODE_I2C_READ:
|
|
||||||
msg[3] = 0;
|
|
||||||
msg_bytes = 4;
|
|
||||||
reply_bytes = 2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
msg_bytes = 3;
|
|
||||||
reply_bytes = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
ret = (*algo_data->aux_ch)(adapter,
|
|
||||||
msg, msg_bytes,
|
|
||||||
reply, reply_bytes);
|
|
||||||
if (ret < 0) {
|
|
||||||
DRM_DEBUG("aux_ch failed %d\n", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
switch (reply[0] & AUX_I2C_REPLY_MASK) {
|
|
||||||
case AUX_I2C_REPLY_ACK:
|
|
||||||
if (mode == MODE_I2C_READ) {
|
|
||||||
*read_byte = reply[1];
|
|
||||||
}
|
|
||||||
return reply_bytes - 1;
|
|
||||||
case AUX_I2C_REPLY_NACK:
|
|
||||||
DRM_DEBUG("aux_ch nack\n");
|
|
||||||
return -EREMOTEIO;
|
|
||||||
case AUX_I2C_REPLY_DEFER:
|
|
||||||
DRM_DEBUG("aux_ch defer\n");
|
|
||||||
udelay(100);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
DRM_ERROR("aux_ch invalid reply 0x%02x\n", reply[0]);
|
|
||||||
return -EREMOTEIO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
|
@ -15,7 +15,6 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \
|
||||||
intel_lvds.o \
|
intel_lvds.o \
|
||||||
intel_bios.o \
|
intel_bios.o \
|
||||||
intel_dp.o \
|
intel_dp.o \
|
||||||
intel_dp_i2c.o \
|
|
||||||
intel_hdmi.o \
|
intel_hdmi.o \
|
||||||
intel_sdvo.o \
|
intel_sdvo.o \
|
||||||
intel_modes.o \
|
intel_modes.o \
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#include "intel_drv.h"
|
#include "intel_drv.h"
|
||||||
#include "i915_drm.h"
|
#include "i915_drm.h"
|
||||||
#include "i915_drv.h"
|
#include "i915_drv.h"
|
||||||
#include "intel_dp.h"
|
#include "drm_dp_helper.h"
|
||||||
|
|
||||||
#include "drm_crtc_helper.h"
|
#include "drm_crtc_helper.h"
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#include "intel_drv.h"
|
#include "intel_drv.h"
|
||||||
#include "i915_drm.h"
|
#include "i915_drm.h"
|
||||||
#include "i915_drv.h"
|
#include "i915_drv.h"
|
||||||
#include "intel_dp.h"
|
#include "drm_dp_helper.h"
|
||||||
|
|
||||||
#define DP_LINK_STATUS_SIZE 6
|
#define DP_LINK_STATUS_SIZE 6
|
||||||
#define DP_LINK_CHECK_TIMEOUT (10 * 1000)
|
#define DP_LINK_CHECK_TIMEOUT (10 * 1000)
|
||||||
|
@ -382,17 +382,77 @@ intel_dp_aux_native_read(struct intel_output *intel_output,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
intel_dp_i2c_aux_ch(struct i2c_adapter *adapter,
|
intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
|
||||||
uint8_t *send, int send_bytes,
|
uint8_t write_byte, uint8_t *read_byte)
|
||||||
uint8_t *recv, int recv_bytes)
|
|
||||||
{
|
{
|
||||||
|
struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
|
||||||
struct intel_dp_priv *dp_priv = container_of(adapter,
|
struct intel_dp_priv *dp_priv = container_of(adapter,
|
||||||
struct intel_dp_priv,
|
struct intel_dp_priv,
|
||||||
adapter);
|
adapter);
|
||||||
struct intel_output *intel_output = dp_priv->intel_output;
|
struct intel_output *intel_output = dp_priv->intel_output;
|
||||||
|
uint16_t address = algo_data->address;
|
||||||
|
uint8_t msg[5];
|
||||||
|
uint8_t reply[2];
|
||||||
|
int msg_bytes;
|
||||||
|
int reply_bytes;
|
||||||
|
int ret;
|
||||||
|
|
||||||
return intel_dp_aux_ch(intel_output,
|
/* Set up the command byte */
|
||||||
send, send_bytes, recv, recv_bytes);
|
if (mode & MODE_I2C_READ)
|
||||||
|
msg[0] = AUX_I2C_READ << 4;
|
||||||
|
else
|
||||||
|
msg[0] = AUX_I2C_WRITE << 4;
|
||||||
|
|
||||||
|
if (!(mode & MODE_I2C_STOP))
|
||||||
|
msg[0] |= AUX_I2C_MOT << 4;
|
||||||
|
|
||||||
|
msg[1] = address >> 8;
|
||||||
|
msg[2] = address;
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case MODE_I2C_WRITE:
|
||||||
|
msg[3] = 0;
|
||||||
|
msg[4] = write_byte;
|
||||||
|
msg_bytes = 5;
|
||||||
|
reply_bytes = 1;
|
||||||
|
break;
|
||||||
|
case MODE_I2C_READ:
|
||||||
|
msg[3] = 0;
|
||||||
|
msg_bytes = 4;
|
||||||
|
reply_bytes = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
msg_bytes = 3;
|
||||||
|
reply_bytes = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
ret = intel_dp_aux_ch(intel_output,
|
||||||
|
msg, msg_bytes,
|
||||||
|
reply, reply_bytes);
|
||||||
|
if (ret < 0) {
|
||||||
|
DRM_DEBUG("aux_ch failed %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
switch (reply[0] & AUX_I2C_REPLY_MASK) {
|
||||||
|
case AUX_I2C_REPLY_ACK:
|
||||||
|
if (mode == MODE_I2C_READ) {
|
||||||
|
*read_byte = reply[1];
|
||||||
|
}
|
||||||
|
return reply_bytes - 1;
|
||||||
|
case AUX_I2C_REPLY_NACK:
|
||||||
|
DRM_DEBUG("aux_ch nack\n");
|
||||||
|
return -EREMOTEIO;
|
||||||
|
case AUX_I2C_REPLY_DEFER:
|
||||||
|
DRM_DEBUG("aux_ch defer\n");
|
||||||
|
udelay(100);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DRM_ERROR("aux_ch invalid reply 0x%02x\n", reply[0]);
|
||||||
|
return -EREMOTEIO;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
* OF THIS SOFTWARE.
|
* OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _INTEL_DP_H_
|
#ifndef _DRM_DP_HELPER_H_
|
||||||
#define _INTEL_DP_H_
|
#define _DRM_DP_HELPER_H_
|
||||||
|
|
||||||
/* From the VESA DisplayPort spec */
|
/* From the VESA DisplayPort spec */
|
||||||
|
|
||||||
|
@ -130,15 +130,20 @@
|
||||||
#define DP_ADJUST_PRE_EMPHASIS_LANE1_MASK 0xc0
|
#define DP_ADJUST_PRE_EMPHASIS_LANE1_MASK 0xc0
|
||||||
#define DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT 6
|
#define DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT 6
|
||||||
|
|
||||||
|
#define MODE_I2C_START 1
|
||||||
|
#define MODE_I2C_WRITE 2
|
||||||
|
#define MODE_I2C_READ 4
|
||||||
|
#define MODE_I2C_STOP 8
|
||||||
|
|
||||||
struct i2c_algo_dp_aux_data {
|
struct i2c_algo_dp_aux_data {
|
||||||
bool running;
|
bool running;
|
||||||
u16 address;
|
u16 address;
|
||||||
int (*aux_ch) (struct i2c_adapter *adapter,
|
int (*aux_ch) (struct i2c_adapter *adapter,
|
||||||
uint8_t *send, int send_bytes,
|
int mode, uint8_t write_byte,
|
||||||
uint8_t *recv, int recv_bytes);
|
uint8_t *read_byte);
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
i2c_dp_aux_add_bus(struct i2c_adapter *adapter);
|
i2c_dp_aux_add_bus(struct i2c_adapter *adapter);
|
||||||
|
|
||||||
#endif /* _INTEL_DP_H_ */
|
#endif /* _DRM_DP_HELPER_H_ */
|
Loading…
Reference in New Issue