diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2017-07-01 16:14:11 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2017-07-01 16:14:11 +0000 |
commit | a179af3b318310fa649e880a100ecf8343d8b4f2 (patch) | |
tree | e5c5646c701afa0877c9c3c9257aa609d73230c1 /sys/dev/pci/drm/radeon | |
parent | 05920c732cee7e34543c9fa518683b1cb92d0461 (diff) |
Update inteldrm(4) to code based on Linux 4.4.70. This brings us support for
Skylake and Cherryview and better support for Broadwell and Valleyview. Also
adds MST support. Some tweaks to the TTM code and radeondrm(4) to keep it
working with the updated generic DRM code needed for inteldrm(4).
Tested by many.
Diffstat (limited to 'sys/dev/pci/drm/radeon')
-rw-r--r-- | sys/dev/pci/drm/radeon/atombios_crtc.c | 18 | ||||
-rw-r--r-- | sys/dev/pci/drm/radeon/atombios_dp.c | 543 | ||||
-rw-r--r-- | sys/dev/pci/drm/radeon/atombios_i2c.c | 8 | ||||
-rw-r--r-- | sys/dev/pci/drm/radeon/nid.h | 48 | ||||
-rw-r--r-- | sys/dev/pci/drm/radeon/r100.c | 6 | ||||
-rw-r--r-- | sys/dev/pci/drm/radeon/radeon.h | 5 | ||||
-rw-r--r-- | sys/dev/pci/drm/radeon/radeon_connectors.c | 72 | ||||
-rw-r--r-- | sys/dev/pci/drm/radeon/radeon_device.c | 4 | ||||
-rw-r--r-- | sys/dev/pci/drm/radeon/radeon_display.c | 20 | ||||
-rw-r--r-- | sys/dev/pci/drm/radeon/radeon_dp_auxch.c | 204 | ||||
-rw-r--r-- | sys/dev/pci/drm/radeon/radeon_fb.c | 16 | ||||
-rw-r--r-- | sys/dev/pci/drm/radeon/radeon_i2c.c | 124 | ||||
-rw-r--r-- | sys/dev/pci/drm/radeon/radeon_irq_kms.c | 4 | ||||
-rw-r--r-- | sys/dev/pci/drm/radeon/radeon_kms.c | 44 | ||||
-rw-r--r-- | sys/dev/pci/drm/radeon/radeon_legacy_crtc.c | 14 | ||||
-rw-r--r-- | sys/dev/pci/drm/radeon/radeon_legacy_encoders.c | 4 | ||||
-rw-r--r-- | sys/dev/pci/drm/radeon/radeon_mode.h | 22 | ||||
-rw-r--r-- | sys/dev/pci/drm/radeon/radeon_pm.c | 9 |
18 files changed, 653 insertions, 512 deletions
diff --git a/sys/dev/pci/drm/radeon/atombios_crtc.c b/sys/dev/pci/drm/radeon/atombios_crtc.c index 76da1f90ad6..33a8ca403c6 100644 --- a/sys/dev/pci/drm/radeon/atombios_crtc.c +++ b/sys/dev/pci/drm/radeon/atombios_crtc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: atombios_crtc.c,v 1.6 2014/08/08 16:33:27 jsg Exp $ */ +/* $OpenBSD: atombios_crtc.c,v 1.7 2017/07/01 16:14:10 kettenis Exp $ */ /* * Copyright 2007-8 Advanced Micro Devices, Inc. * Copyright 2008 Red Hat Inc. @@ -1084,7 +1084,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, int r; /* no fb bound */ - if (!atomic && !crtc->fb) { + if (!atomic && !crtc->primary->fb) { DRM_DEBUG_KMS("No FB bound\n"); return 0; } @@ -1094,8 +1094,8 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, target_fb = fb; } else { - radeon_fb = to_radeon_framebuffer(crtc->fb); - target_fb = crtc->fb; + radeon_fb = to_radeon_framebuffer(crtc->primary->fb); + target_fb = crtc->primary->fb; } /* If atomic, assume fb object is pinned & idle & fenced and @@ -1252,7 +1252,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, /* set pageflip to happen anywhere in vblank interval */ WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); - if (!atomic && fb && fb != crtc->fb) { + if (!atomic && fb && fb != crtc->primary->fb) { radeon_fb = to_radeon_framebuffer(fb); rbo = gem_to_radeon_bo(radeon_fb->obj); r = radeon_bo_reserve(rbo, false); @@ -1286,7 +1286,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, int r; /* no fb bound */ - if (!atomic && !crtc->fb) { + if (!atomic && !crtc->primary->fb) { DRM_DEBUG_KMS("No FB bound\n"); return 0; } @@ -1296,8 +1296,8 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, target_fb = fb; } else { - radeon_fb = to_radeon_framebuffer(crtc->fb); - target_fb = crtc->fb; + radeon_fb = to_radeon_framebuffer(crtc->primary->fb); + target_fb = crtc->primary->fb; } obj = radeon_fb->obj; @@ -1421,7 +1421,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, /* set pageflip to happen anywhere in vblank interval */ WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); - if (!atomic && fb && fb != crtc->fb) { + if (!atomic && fb && fb != crtc->primary->fb) { radeon_fb = to_radeon_framebuffer(fb); rbo = gem_to_radeon_bo(radeon_fb->obj); r = radeon_bo_reserve(rbo, false); diff --git a/sys/dev/pci/drm/radeon/atombios_dp.c b/sys/dev/pci/drm/radeon/atombios_dp.c index 1a08b611c3d..0fef9a1f028 100644 --- a/sys/dev/pci/drm/radeon/atombios_dp.c +++ b/sys/dev/pci/drm/radeon/atombios_dp.c @@ -1,4 +1,3 @@ -/* $OpenBSD: atombios_dp.c,v 1.6 2015/04/18 14:47:34 jsg Exp $ */ /* * Copyright 2007-8 Advanced Micro Devices, Inc. * Copyright 2008 Red Hat Inc. @@ -98,6 +97,7 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan, int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction); unsigned char *base; int recv_bytes; + int r = 0; memset(&args, 0, sizeof(args)); @@ -120,19 +120,22 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan, /* timeout */ if (args.v1.ucReplyStatus == 1) { DRM_DEBUG_KMS("dp_aux_ch timeout\n"); - return -ETIMEDOUT; + r = -ETIMEDOUT; + goto done; } /* flags not zero */ if (args.v1.ucReplyStatus == 2) { DRM_DEBUG_KMS("dp_aux_ch flags not zero\n"); - return -EBUSY; + r = -EIO; + goto done; } /* error */ if (args.v1.ucReplyStatus == 3) { DRM_DEBUG_KMS("dp_aux_ch error\n"); - return -EIO; + r = -EIO; + goto done; } recv_bytes = args.v1.ucDataOutLen; @@ -142,193 +145,113 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan, if (recv && recv_size) radeon_atom_copy_swap(recv, base + 16, recv_bytes, false); - return recv_bytes; + r = recv_bytes; +done: + return r; } -static int radeon_dp_aux_native_write(struct radeon_connector *radeon_connector, - u16 address, u8 *send, u8 send_bytes, u8 delay) -{ - struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; - int ret; - u8 msg[20]; - int msg_bytes = send_bytes + 4; - u8 ack; - unsigned retry; +#define BARE_ADDRESS_SIZE 3 +#define HEADER_SIZE (BARE_ADDRESS_SIZE + 1) - if (send_bytes > 16) - return -1; - - msg[0] = address; - msg[1] = address >> 8; - msg[2] = AUX_NATIVE_WRITE << 4; - msg[3] = (msg_bytes << 4) | (send_bytes - 1); - memcpy(&msg[4], send, send_bytes); - - for (retry = 0; retry < 4; retry++) { - ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, - msg, msg_bytes, NULL, 0, delay, &ack); - if (ret == -EBUSY) - continue; - else if (ret < 0) - return ret; - if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) - return send_bytes; - else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) - udelay(400); - else - return -EIO; - } - - return -EIO; -} - -static int radeon_dp_aux_native_read(struct radeon_connector *radeon_connector, - u16 address, u8 *recv, int recv_bytes, u8 delay) +static ssize_t +radeon_dp_aux_transfer_atom(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) { - struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; - u8 msg[4]; - int msg_bytes = 4; - u8 ack; + struct radeon_i2c_chan *chan = + container_of(aux, struct radeon_i2c_chan, aux); int ret; - unsigned retry; - - msg[0] = address; - msg[1] = address >> 8; - msg[2] = AUX_NATIVE_READ << 4; - msg[3] = (msg_bytes << 4) | (recv_bytes - 1); - - for (retry = 0; retry < 4; retry++) { - ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, - msg, msg_bytes, recv, recv_bytes, delay, &ack); - if (ret == -EBUSY) - continue; - else if (ret < 0) - return ret; - if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) - return ret; - else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) - udelay(400); + u8 tx_buf[20]; + size_t tx_size; + u8 ack, delay = 0; + + if (WARN_ON(msg->size > 16)) + return -E2BIG; + + tx_buf[0] = msg->address & 0xff; + 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) { + 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 + * payloads for reads. The hw itself supports up to 16 bytes of payload. + */ + if (WARN_ON_ONCE(msg->size > 12)) + return -E2BIG; + /* tx_size needs to be 4 even for bare address packets since the atom + * table needs the info in tx_buf[3]. + */ + tx_size = HEADER_SIZE + msg->size; + if (msg->size == 0) + tx_buf[3] |= BARE_ADDRESS_SIZE << 4; else - return -EIO; + tx_buf[3] |= tx_size << 4; + memcpy(tx_buf + HEADER_SIZE, msg->buffer, msg->size); + ret = radeon_process_aux_ch(chan, + tx_buf, tx_size, NULL, 0, delay, &ack); + if (ret >= 0) + /* Return payload size. */ + ret = msg->size; + break; + case DP_AUX_NATIVE_READ: + case DP_AUX_I2C_READ: + /* tx_size needs to be 4 even for bare address packets since the atom + * table needs the info in tx_buf[3]. + */ + tx_size = HEADER_SIZE; + if (msg->size == 0) + tx_buf[3] |= BARE_ADDRESS_SIZE << 4; + else + tx_buf[3] |= tx_size << 4; + ret = radeon_process_aux_ch(chan, + tx_buf, tx_size, msg->buffer, msg->size, delay, &ack); + break; + default: + ret = -EINVAL; + break; } - return -EIO; -} - -static void radeon_write_dpcd_reg(struct radeon_connector *radeon_connector, - u16 reg, u8 val) -{ - radeon_dp_aux_native_write(radeon_connector, reg, &val, 1, 0); -} - -static u8 radeon_read_dpcd_reg(struct radeon_connector *radeon_connector, - u16 reg) -{ - u8 val = 0; + if (ret >= 0) + msg->reply = ack >> 4; - radeon_dp_aux_native_read(radeon_connector, reg, &val, 1, 0); - - return val; + return ret; } -int radeon_dp_i2c_aux_ch(struct i2c_controller *adapter, int mode, - u8 write_byte, u8 *read_byte) +void radeon_dp_aux_init(struct radeon_connector *radeon_connector) { - struct i2c_algo_dp_aux_data *algo_data = adapter->ic_cookie; - struct radeon_i2c_chan *auxch = (struct radeon_i2c_chan *)adapter; - u16 address = algo_data->address; - u8 msg[5]; - u8 reply[2]; - unsigned retry; - int msg_bytes; - int reply_bytes = 1; + struct drm_device *dev = radeon_connector->base.dev; + struct radeon_device *rdev = dev->dev_private; int ret; - u8 ack; - /* Set up the command byte */ - if (mode & MODE_I2C_READ) - msg[2] = AUX_I2C_READ << 4; - else - msg[2] = AUX_I2C_WRITE << 4; - - if (!(mode & MODE_I2C_STOP)) - msg[2] |= AUX_I2C_MOT << 4; - - msg[0] = address; - msg[1] = address >> 8; - - switch (mode) { - case MODE_I2C_WRITE: - msg_bytes = 5; - msg[3] = msg_bytes << 4; - msg[4] = write_byte; - break; - case MODE_I2C_READ: - msg_bytes = 4; - msg[3] = msg_bytes << 4; - break; - default: - msg_bytes = 4; - msg[3] = 3 << 4; - break; + radeon_connector->ddc_bus->rec.hpd = radeon_connector->hpd.hpd; + radeon_connector->ddc_bus->aux.dev = radeon_connector->base.kdev; + if (ASIC_IS_DCE5(rdev)) { + if (radeon_auxch) + radeon_connector->ddc_bus->aux.transfer = radeon_dp_aux_transfer_native; + else + radeon_connector->ddc_bus->aux.transfer = radeon_dp_aux_transfer_atom; + } else { + radeon_connector->ddc_bus->aux.transfer = radeon_dp_aux_transfer_atom; } - for (retry = 0; retry < 4; retry++) { - ret = radeon_process_aux_ch(auxch, - msg, msg_bytes, reply, reply_bytes, 0, &ack); - if (ret == -EBUSY) - continue; - else if (ret < 0) { - DRM_DEBUG_KMS("aux_ch failed %d\n", ret); - return ret; - } + ret = drm_dp_aux_register(&radeon_connector->ddc_bus->aux); + if (!ret) + radeon_connector->ddc_bus->has_aux = true; - switch (ack & AUX_NATIVE_REPLY_MASK) { - case AUX_NATIVE_REPLY_ACK: - /* I2C-over-AUX Reply field is only valid - * when paired with AUX ACK. - */ - break; - case AUX_NATIVE_REPLY_NACK: - DRM_DEBUG_KMS("aux_ch native nack\n"); - return -EREMOTEIO; - case AUX_NATIVE_REPLY_DEFER: - DRM_DEBUG_KMS("aux_ch native defer\n"); - udelay(400); - continue; - default: - DRM_ERROR("aux_ch invalid native reply 0x%02x\n", ack); - return -EREMOTEIO; - } - - switch (ack & AUX_I2C_REPLY_MASK) { - case AUX_I2C_REPLY_ACK: - if (mode == MODE_I2C_READ) - *read_byte = reply[0]; - return ret; - case AUX_I2C_REPLY_NACK: - DRM_DEBUG_KMS("aux_i2c nack\n"); - return -EREMOTEIO; - case AUX_I2C_REPLY_DEFER: - DRM_DEBUG_KMS("aux_i2c defer\n"); - udelay(400); - break; - default: - DRM_ERROR("aux_i2c invalid reply 0x%02x\n", ack); - return -EREMOTEIO; - } - } - - DRM_DEBUG_KMS("aux i2c too many retries, giving up\n"); - return -EREMOTEIO; + WARN(ret, "drm_dp_aux_register() failed with error %d\n", ret); } /***** general DP utility functions *****/ -#define DP_VOLTAGE_MAX DP_TRAIN_VOLTAGE_SWING_1200 -#define DP_PRE_EMPHASIS_MAX DP_TRAIN_PRE_EMPHASIS_9_5 +#define DP_VOLTAGE_MAX DP_TRAIN_VOLTAGE_SWING_LEVEL_3 +#define DP_PRE_EMPHASIS_MAX DP_TRAIN_PRE_EMPH_LEVEL_3 -static void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE], +static void dp_get_adjust_train(const u8 link_status[DP_LINK_STATUS_SIZE], int lane_count, u8 train_set[4]) { @@ -375,77 +298,43 @@ static int convert_bpc_to_bpp(int bpc) return bpc * 3; } -/* get the max pix clock supported by the link rate and lane num */ -static int dp_get_max_dp_pix_clock(int link_rate, - int lane_num, - int bpp) -{ - return (link_rate * lane_num * 8) / bpp; -} - /***** radeon specific DP functions *****/ -static int radeon_dp_get_max_link_rate(struct drm_connector *connector, - u8 dpcd[DP_DPCD_SIZE]) -{ - int max_link_rate; - - if (radeon_connector_is_dp12_capable(connector)) - max_link_rate = min(drm_dp_max_link_rate(dpcd), 540000); - else - max_link_rate = min(drm_dp_max_link_rate(dpcd), 270000); - - return max_link_rate; -} - -/* First get the min lane# when low rate is used according to pixel clock - * (prefer low rate), second check max lane# supported by DP panel, - * if the max lane# < low rate lane# then use max lane# instead. - */ -static int radeon_dp_get_dp_lane_number(struct drm_connector *connector, - u8 dpcd[DP_DPCD_SIZE], - int pix_clock) -{ - int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector)); - int max_link_rate = radeon_dp_get_max_link_rate(connector, dpcd); - int max_lane_num = drm_dp_max_lane_count(dpcd); - int lane_num; - int max_dp_pix_clock; - - for (lane_num = 1; lane_num < max_lane_num; lane_num <<= 1) { - max_dp_pix_clock = dp_get_max_dp_pix_clock(max_link_rate, lane_num, bpp); - if (pix_clock <= max_dp_pix_clock) - break; - } - - return lane_num; -} - -static int radeon_dp_get_dp_link_clock(struct drm_connector *connector, - u8 dpcd[DP_DPCD_SIZE], - int pix_clock) +int radeon_dp_get_dp_link_config(struct drm_connector *connector, + const u8 dpcd[DP_DPCD_SIZE], + unsigned pix_clock, + unsigned *dp_lanes, unsigned *dp_rate) { int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector)); - int lane_num, max_pix_clock; + static const unsigned link_rates[3] = { 162000, 270000, 540000 }; + unsigned max_link_rate = drm_dp_max_link_rate(dpcd); + unsigned max_lane_num = drm_dp_max_lane_count(dpcd); + unsigned lane_num, i, max_pix_clock; if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == - ENCODER_OBJECT_ID_NUTMEG) - return 270000; - - lane_num = radeon_dp_get_dp_lane_number(connector, dpcd, pix_clock); - max_pix_clock = dp_get_max_dp_pix_clock(162000, lane_num, bpp); - if (pix_clock <= max_pix_clock) - return 162000; - max_pix_clock = dp_get_max_dp_pix_clock(270000, lane_num, bpp); - if (pix_clock <= max_pix_clock) - return 270000; - if (radeon_connector_is_dp12_capable(connector)) { - max_pix_clock = dp_get_max_dp_pix_clock(540000, lane_num, bpp); - if (pix_clock <= max_pix_clock) - return 540000; + ENCODER_OBJECT_ID_NUTMEG) { + for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) { + max_pix_clock = (lane_num * 270000 * 8) / bpp; + if (max_pix_clock >= pix_clock) { + *dp_lanes = lane_num; + *dp_rate = 270000; + return 0; + } + } + } else { + for (i = 0; i < ARRAY_SIZE(link_rates) && link_rates[i] <= max_link_rate; i++) { + for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) { + max_pix_clock = (lane_num * link_rates[i] * 8) / bpp; + if (max_pix_clock >= pix_clock) { + *dp_lanes = lane_num; + *dp_rate = link_rates[i]; + return 0; + } + } + } } - return radeon_dp_get_max_link_rate(connector, dpcd); + return -EINVAL; } static u8 radeon_dp_encoder_service(struct radeon_device *rdev, @@ -468,12 +357,11 @@ static u8 radeon_dp_encoder_service(struct radeon_device *rdev, u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector) { - struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; struct drm_device *dev = radeon_connector->base.dev; struct radeon_device *rdev = dev->dev_private; return radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_GET_SINK_TYPE, 0, - dig_connector->dp_i2c_bus->rec.i2c_id, 0); + radeon_connector->ddc_bus->rec.i2c_id, 0); } static void radeon_dp_probe_oui(struct radeon_connector *radeon_connector) @@ -484,11 +372,11 @@ static void radeon_dp_probe_oui(struct radeon_connector *radeon_connector) if (!(dig_connector->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT)) return; - if (radeon_dp_aux_native_read(radeon_connector, DP_SINK_OUI, buf, 3, 0)) + if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_SINK_OUI, buf, 3) == 3) DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n", buf[0], buf[1], buf[2]); - if (radeon_dp_aux_native_read(radeon_connector, DP_BRANCH_OUI, buf, 3, 0)) + if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_BRANCH_OUI, buf, 3) == 3) DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n", buf[0], buf[1], buf[2]); } @@ -499,18 +387,19 @@ bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector) u8 msg[DP_DPCD_SIZE]; int ret, i; - ret = radeon_dp_aux_native_read(radeon_connector, DP_DPCD_REV, msg, - DP_DPCD_SIZE, 0); - if (ret > 0) { - memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE); - DRM_DEBUG_KMS("DPCD: "); - for (i = 0; i < DP_DPCD_SIZE; i++) - DRM_DEBUG_KMS("%02x ", msg[i]); - DRM_DEBUG_KMS("\n"); + for (i = 0; i < 7; i++) { + ret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_DPCD_REV, msg, + DP_DPCD_SIZE); + if (ret == DP_DPCD_SIZE) { + memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE); - radeon_dp_probe_oui(radeon_connector); + DRM_DEBUG_KMS("DPCD: %*ph\n", (int)sizeof(dig_connector->dpcd), + dig_connector->dpcd); - return true; + radeon_dp_probe_oui(radeon_connector); + + return true; + } } dig_connector->dpcd[0] = 0; return false; @@ -522,6 +411,7 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder, struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; struct radeon_connector *radeon_connector = to_radeon_connector(connector); + struct radeon_connector_atom_dig *dig_connector; int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; u16 dp_bridge = radeon_connector_encoder_get_dp_bridge_encoder_id(connector); u8 tmp; @@ -529,21 +419,30 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder, if (!ASIC_IS_DCE4(rdev)) return panel_mode; + if (!radeon_connector->con_priv) + return panel_mode; + + dig_connector = radeon_connector->con_priv; + if (dp_bridge != ENCODER_OBJECT_ID_NONE) { /* DP bridge chips */ - tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); - if (tmp & 1) - panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; - else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) || - (dp_bridge == ENCODER_OBJECT_ID_TRAVIS)) - panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; - else - panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; + if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, + DP_EDP_CONFIGURATION_CAP, &tmp) == 1) { + if (tmp & 1) + panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; + else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) || + (dp_bridge == ENCODER_OBJECT_ID_TRAVIS)) + panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; + else + panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; + } } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { /* eDP */ - tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); - if (tmp & 1) - panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; + if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, + DP_EDP_CONFIGURATION_CAP, &tmp) == 1) { + if (tmp & 1) + panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; + } } return panel_mode; @@ -554,6 +453,7 @@ void radeon_dp_set_link_config(struct drm_connector *connector, { struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct radeon_connector_atom_dig *dig_connector; + int ret; if (!radeon_connector->con_priv) return; @@ -561,10 +461,14 @@ void radeon_dp_set_link_config(struct drm_connector *connector, if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) { - dig_connector->dp_clock = - radeon_dp_get_dp_link_clock(connector, dig_connector->dpcd, mode->clock); - dig_connector->dp_lane_count = - radeon_dp_get_dp_lane_number(connector, dig_connector->dpcd, mode->clock); + ret = radeon_dp_get_dp_link_config(connector, dig_connector->dpcd, + mode->clock, + &dig_connector->dp_lane_count, + &dig_connector->dp_clock); + if (ret) { + dig_connector->dp_clock = 0; + dig_connector->dp_lane_count = 0; + } } } @@ -573,14 +477,23 @@ int radeon_dp_mode_valid_helper(struct drm_connector *connector, { struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct radeon_connector_atom_dig *dig_connector; - int dp_clock; + unsigned dp_clock, dp_lanes; + int ret; + + if ((mode->clock > 340000) && + (!radeon_connector_is_dp12_capable(connector))) + return MODE_CLOCK_HIGH; if (!radeon_connector->con_priv) return MODE_CLOCK_HIGH; dig_connector = radeon_connector->con_priv; - dp_clock = - radeon_dp_get_dp_link_clock(connector, dig_connector->dpcd, mode->clock); + ret = radeon_dp_get_dp_link_config(connector, dig_connector->dpcd, + mode->clock, + &dp_lanes, + &dp_clock); + if (ret) + return MODE_CLOCK_HIGH; if ((dp_clock == 540000) && (!radeon_connector_is_dp12_capable(connector))) @@ -589,37 +502,43 @@ int radeon_dp_mode_valid_helper(struct drm_connector *connector, return MODE_OK; } -static bool radeon_dp_get_link_status(struct radeon_connector *radeon_connector, - u8 link_status[DP_LINK_STATUS_SIZE]) -{ - int ret; - ret = radeon_dp_aux_native_read(radeon_connector, DP_LANE0_1_STATUS, - link_status, DP_LINK_STATUS_SIZE, 100); - if (ret <= 0) { - return false; - } - - DRM_DEBUG_KMS("link status %*ph\n", 6, link_status); - return true; -} - bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector) { u8 link_status[DP_LINK_STATUS_SIZE]; struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; - if (!radeon_dp_get_link_status(radeon_connector, link_status)) + if (drm_dp_dpcd_read_link_status(&radeon_connector->ddc_bus->aux, link_status) + <= 0) return false; if (drm_dp_channel_eq_ok(link_status, dig->dp_lane_count)) return false; return true; } +void radeon_dp_set_rx_power_state(struct drm_connector *connector, + u8 power_state) +{ + struct radeon_connector *radeon_connector = to_radeon_connector(connector); + struct radeon_connector_atom_dig *dig_connector; + + if (!radeon_connector->con_priv) + return; + + dig_connector = radeon_connector->con_priv; + + /* power up/down the sink */ + if (dig_connector->dpcd[0] >= 0x11) { + drm_dp_dpcd_writeb(&radeon_connector->ddc_bus->aux, + DP_SET_POWER, power_state); + usleep_range(1000, 2000); + } +} + + struct radeon_dp_link_train_info { struct radeon_device *rdev; struct drm_encoder *encoder; struct drm_connector *connector; - struct radeon_connector *radeon_connector; int enc_id; int dp_clock; int dp_lane_count; @@ -629,6 +548,7 @@ struct radeon_dp_link_train_info { u8 link_status[DP_LINK_STATUS_SIZE]; u8 tries; bool use_dpencoder; + struct drm_dp_aux *aux; }; static void radeon_dp_update_vs_emph(struct radeon_dp_link_train_info *dp_info) @@ -639,8 +559,8 @@ static void radeon_dp_update_vs_emph(struct radeon_dp_link_train_info *dp_info) 0, dp_info->train_set[0]); /* sets all lanes at once */ /* set the vs/emph on the sink */ - radeon_dp_aux_native_write(dp_info->radeon_connector, DP_TRAINING_LANE0_SET, - dp_info->train_set, dp_info->dp_lane_count, 0); + drm_dp_dpcd_write(dp_info->aux, DP_TRAINING_LANE0_SET, + dp_info->train_set, dp_info->dp_lane_count); } static void radeon_dp_set_tp(struct radeon_dp_link_train_info *dp_info, int tp) @@ -675,7 +595,7 @@ static void radeon_dp_set_tp(struct radeon_dp_link_train_info *dp_info, int tp) } /* enable training pattern on the sink */ - radeon_write_dpcd_reg(dp_info->radeon_connector, DP_TRAINING_PATTERN_SET, tp); + drm_dp_dpcd_writeb(dp_info->aux, DP_TRAINING_PATTERN_SET, tp); } static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info) @@ -685,33 +605,28 @@ static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info) u8 tmp; /* power up the sink */ - if (dp_info->dpcd[0] >= 0x11) - radeon_write_dpcd_reg(dp_info->radeon_connector, - DP_SET_POWER, DP_SET_POWER_D0); + radeon_dp_set_rx_power_state(dp_info->connector, DP_SET_POWER_D0); /* possibly enable downspread on the sink */ if (dp_info->dpcd[3] & 0x1) - radeon_write_dpcd_reg(dp_info->radeon_connector, - DP_DOWNSPREAD_CTRL, DP_SPREAD_AMP_0_5); + drm_dp_dpcd_writeb(dp_info->aux, + DP_DOWNSPREAD_CTRL, DP_SPREAD_AMP_0_5); else - radeon_write_dpcd_reg(dp_info->radeon_connector, - DP_DOWNSPREAD_CTRL, 0); + drm_dp_dpcd_writeb(dp_info->aux, + DP_DOWNSPREAD_CTRL, 0); - if ((dp_info->connector->connector_type == DRM_MODE_CONNECTOR_eDP) && - (dig->panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)) { - radeon_write_dpcd_reg(dp_info->radeon_connector, DP_EDP_CONFIGURATION_SET, 1); - } + if (dig->panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE) + drm_dp_dpcd_writeb(dp_info->aux, DP_EDP_CONFIGURATION_SET, 1); /* set the lane count on the sink */ tmp = dp_info->dp_lane_count; - if (dp_info->dpcd[DP_DPCD_REV] >= 0x11 && - dp_info->dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP) + if (drm_dp_enhanced_frame_cap(dp_info->dpcd)) tmp |= DP_LANE_COUNT_ENHANCED_FRAME_EN; - radeon_write_dpcd_reg(dp_info->radeon_connector, DP_LANE_COUNT_SET, tmp); + drm_dp_dpcd_writeb(dp_info->aux, DP_LANE_COUNT_SET, tmp); /* set the link rate on the sink */ tmp = drm_dp_link_rate_to_bw_code(dp_info->dp_clock); - radeon_write_dpcd_reg(dp_info->radeon_connector, DP_LINK_BW_SET, tmp); + drm_dp_dpcd_writeb(dp_info->aux, DP_LINK_BW_SET, tmp); /* start training on the source */ if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) @@ -722,9 +637,9 @@ static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info) dp_info->dp_clock, dp_info->enc_id, 0); /* disable the training pattern on the sink */ - radeon_write_dpcd_reg(dp_info->radeon_connector, - DP_TRAINING_PATTERN_SET, - DP_TRAINING_PATTERN_DISABLE); + drm_dp_dpcd_writeb(dp_info->aux, + DP_TRAINING_PATTERN_SET, + DP_TRAINING_PATTERN_DISABLE); return 0; } @@ -734,9 +649,9 @@ static int radeon_dp_link_train_finish(struct radeon_dp_link_train_info *dp_info udelay(400); /* disable the training pattern on the sink */ - radeon_write_dpcd_reg(dp_info->radeon_connector, - DP_TRAINING_PATTERN_SET, - DP_TRAINING_PATTERN_DISABLE); + drm_dp_dpcd_writeb(dp_info->aux, + DP_TRAINING_PATTERN_SET, + DP_TRAINING_PATTERN_DISABLE); /* disable the training pattern on the source */ if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) @@ -768,7 +683,8 @@ static int radeon_dp_link_train_cr(struct radeon_dp_link_train_info *dp_info) while (1) { drm_dp_link_train_clock_recovery_delay(dp_info->dpcd); - if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) { + if (drm_dp_dpcd_read_link_status(dp_info->aux, + dp_info->link_status) <= 0) { DRM_ERROR("displayport link status failed\n"); break; } @@ -830,7 +746,8 @@ static int radeon_dp_link_train_ce(struct radeon_dp_link_train_info *dp_info) while (1) { drm_dp_link_train_channel_eq_delay(dp_info->dpcd); - if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) { + if (drm_dp_dpcd_read_link_status(dp_info->aux, + dp_info->link_status) <= 0) { DRM_ERROR("displayport link status failed\n"); break; } @@ -913,19 +830,23 @@ void radeon_dp_link_train(struct drm_encoder *encoder, else dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A; - tmp = radeon_read_dpcd_reg(radeon_connector, DP_MAX_LANE_COUNT); - if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED)) - dp_info.tp3_supported = true; - else + if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, DP_MAX_LANE_COUNT, &tmp) + == 1) { + if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED)) + dp_info.tp3_supported = true; + else + dp_info.tp3_supported = false; + } else { dp_info.tp3_supported = false; + } memcpy(dp_info.dpcd, dig_connector->dpcd, DP_RECEIVER_CAP_SIZE); dp_info.rdev = rdev; dp_info.encoder = encoder; dp_info.connector = connector; - dp_info.radeon_connector = radeon_connector; dp_info.dp_lane_count = dig_connector->dp_lane_count; dp_info.dp_clock = dig_connector->dp_clock; + dp_info.aux = &radeon_connector->ddc_bus->aux; if (radeon_dp_link_train_init(&dp_info)) goto done; diff --git a/sys/dev/pci/drm/radeon/atombios_i2c.c b/sys/dev/pci/drm/radeon/atombios_i2c.c index dde3dfa2be6..17abedfe0d5 100644 --- a/sys/dev/pci/drm/radeon/atombios_i2c.c +++ b/sys/dev/pci/drm/radeon/atombios_i2c.c @@ -1,4 +1,4 @@ -/* $OpenBSD: atombios_i2c.c,v 1.5 2015/04/06 07:38:49 jsg Exp $ */ +/* $OpenBSD: atombios_i2c.c,v 1.6 2017/07/01 16:14:10 kettenis Exp $ */ /* * Copyright 2011 Advanced Micro Devices, Inc. * @@ -36,7 +36,6 @@ extern void radeon_atom_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le); #define ATOM_MAX_HW_I2C_WRITE 2 #define ATOM_MAX_HW_I2C_READ 255 -#ifdef notyet static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan, u8 slave_addr, u8 flags, u8 *buf, u8 num) @@ -95,7 +94,7 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan, return 0; } -int radeon_atom_hw_i2c_xfer(struct i2c_controller *i2c_adap, +int radeon_atom_hw_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) { struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); @@ -145,7 +144,8 @@ int radeon_atom_hw_i2c_xfer(struct i2c_controller *i2c_adap, return num; } -u32 radeon_atom_hw_i2c_func(struct i2c_controller *adap) +#ifdef notyet +u32 radeon_atom_hw_i2c_func(struct i2c_adapter *adap) { return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; } diff --git a/sys/dev/pci/drm/radeon/nid.h b/sys/dev/pci/drm/radeon/nid.h index 8b89e5de807..99043e10ebb 100644 --- a/sys/dev/pci/drm/radeon/nid.h +++ b/sys/dev/pci/drm/radeon/nid.h @@ -1,4 +1,4 @@ -/* $OpenBSD: nid.h,v 1.2 2014/02/15 14:28:13 jsg Exp $ */ +/* $OpenBSD: nid.h,v 1.3 2017/07/01 16:14:10 kettenis Exp $ */ /* * Copyright 2010 Advanced Micro Devices, Inc. * @@ -476,6 +476,52 @@ # define CACHE_FLUSH_AND_INV_EVENT_TS (0x14 << 0) # define CACHE_FLUSH_AND_INV_EVENT (0x16 << 0) +#define AUX_CONTROL 0x6200 +#define AUX_EN (1 << 0) +#define AUX_LS_READ_EN (1 << 8) +#define AUX_LS_UPDATE_DISABLE(x) (((x) & 0x1) << 12) +#define AUX_HPD_DISCON(x) (((x) & 0x1) << 16) +#define AUX_DET_EN (1 << 18) +#define AUX_HPD_SEL(x) (((x) & 0x7) << 20) +#define AUX_IMPCAL_REQ_EN (1 << 24) +#define AUX_TEST_MODE (1 << 28) +#define AUX_DEGLITCH_EN (1 << 29) +#define AUX_SW_CONTROL 0x6204 +#define AUX_SW_GO (1 << 0) +#define AUX_LS_READ_TRIG (1 << 2) +#define AUX_SW_START_DELAY(x) (((x) & 0xf) << 4) +#define AUX_SW_WR_BYTES(x) (((x) & 0x1f) << 16) + +#define AUX_SW_INTERRUPT_CONTROL 0x620c +#define AUX_SW_DONE_INT (1 << 0) +#define AUX_SW_DONE_ACK (1 << 1) +#define AUX_SW_DONE_MASK (1 << 2) +#define AUX_SW_LS_DONE_INT (1 << 4) +#define AUX_SW_LS_DONE_MASK (1 << 6) +#define AUX_SW_STATUS 0x6210 +#define AUX_SW_DONE (1 << 0) +#define AUX_SW_REQ (1 << 1) +#define AUX_SW_RX_TIMEOUT_STATE(x) (((x) & 0x7) << 4) +#define AUX_SW_RX_TIMEOUT (1 << 7) +#define AUX_SW_RX_OVERFLOW (1 << 8) +#define AUX_SW_RX_HPD_DISCON (1 << 9) +#define AUX_SW_RX_PARTIAL_BYTE (1 << 10) +#define AUX_SW_NON_AUX_MODE (1 << 11) +#define AUX_SW_RX_MIN_COUNT_VIOL (1 << 12) +#define AUX_SW_RX_INVALID_STOP (1 << 14) +#define AUX_SW_RX_SYNC_INVALID_L (1 << 17) +#define AUX_SW_RX_SYNC_INVALID_H (1 << 18) +#define AUX_SW_RX_INVALID_START (1 << 19) +#define AUX_SW_RX_RECV_NO_DET (1 << 20) +#define AUX_SW_RX_RECV_INVALID_H (1 << 22) +#define AUX_SW_RX_RECV_INVALID_V (1 << 23) + +#define AUX_SW_DATA 0x6218 +#define AUX_SW_DATA_RW (1 << 0) +#define AUX_SW_DATA_MASK(x) (((x) & 0xff) << 8) +#define AUX_SW_DATA_INDEX(x) (((x) & 0x1f) << 16) +#define AUX_SW_AUTOINCREMENT_DISABLE (1 << 31) + /* * PM4 */ diff --git a/sys/dev/pci/drm/radeon/r100.c b/sys/dev/pci/drm/radeon/r100.c index 1c4fe9ea7b4..1e09e94adc9 100644 --- a/sys/dev/pci/drm/radeon/r100.c +++ b/sys/dev/pci/drm/radeon/r100.c @@ -1,4 +1,4 @@ -/* $OpenBSD: r100.c,v 1.15 2015/04/06 14:10:59 jsg Exp $ */ +/* $OpenBSD: r100.c,v 1.16 2017/07/01 16:14:10 kettenis Exp $ */ /* * Copyright 2008 Advanced Micro Devices, Inc. * Copyright 2008 Red Hat Inc. @@ -3303,12 +3303,12 @@ void r100_bandwidth_update(struct radeon_device *rdev) if (rdev->mode_info.crtcs[0]->base.enabled) { mode1 = &rdev->mode_info.crtcs[0]->base.mode; - pixel_bytes1 = rdev->mode_info.crtcs[0]->base.fb->bits_per_pixel / 8; + pixel_bytes1 = rdev->mode_info.crtcs[0]->base.primary->fb->bits_per_pixel / 8; } if (!(rdev->flags & RADEON_SINGLE_CRTC)) { if (rdev->mode_info.crtcs[1]->base.enabled) { mode2 = &rdev->mode_info.crtcs[1]->base.mode; - pixel_bytes2 = rdev->mode_info.crtcs[1]->base.fb->bits_per_pixel / 8; + pixel_bytes2 = rdev->mode_info.crtcs[1]->base.primary->fb->bits_per_pixel / 8; } } diff --git a/sys/dev/pci/drm/radeon/radeon.h b/sys/dev/pci/drm/radeon/radeon.h index 9da386dbd7d..9b3eeff7b82 100644 --- a/sys/dev/pci/drm/radeon/radeon.h +++ b/sys/dev/pci/drm/radeon/radeon.h @@ -1,4 +1,4 @@ -/* $OpenBSD: radeon.h,v 1.17 2015/09/27 11:09:26 jsg Exp $ */ +/* $OpenBSD: radeon.h,v 1.18 2017/07/01 16:14:10 kettenis Exp $ */ /* * Copyright 2008 Advanced Micro Devices, Inc. * Copyright 2008 Red Hat Inc. @@ -99,6 +99,7 @@ extern int radeon_hw_i2c; extern int radeon_pcie_gen2; extern int radeon_msi; extern int radeon_lockup_timeout; +extern int radeon_auxch; /* * Copy from radeon_drv.h so we don't have to include both and have conflicting @@ -1570,7 +1571,7 @@ struct radeon_device { int console; struct task burner_task; - int burner_dpms_mode; + int burner_fblank; #ifdef __sparc64__ struct sunfb sf; diff --git a/sys/dev/pci/drm/radeon/radeon_connectors.c b/sys/dev/pci/drm/radeon/radeon_connectors.c index 5705874cbf0..f0dc6e28006 100644 --- a/sys/dev/pci/drm/radeon/radeon_connectors.c +++ b/sys/dev/pci/drm/radeon/radeon_connectors.c @@ -1,4 +1,4 @@ -/* $OpenBSD: radeon_connectors.c,v 1.6 2015/04/18 14:47:35 jsg Exp $ */ +/* $OpenBSD: radeon_connectors.c,v 1.7 2017/07/01 16:14:10 kettenis Exp $ */ /* * Copyright 2007-8 Advanced Micro Devices, Inc. * Copyright 2008 Red Hat Inc. @@ -97,7 +97,7 @@ static void radeon_property_change_mode(struct drm_encoder *encoder) if (crtc && crtc->enabled) { drm_crtc_helper_set_mode(crtc, &crtc->mode, - crtc->x, crtc->y, crtc->fb); + crtc->x, crtc->y, crtc->primary->fb); } } @@ -140,7 +140,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector) if (connector->display_info.bpc) bpc = connector->display_info.bpc; else if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { - struct drm_connector_helper_funcs *connector_funcs = + const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; struct drm_encoder *encoder = connector_funcs->best_encoder(connector); struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); @@ -163,7 +163,7 @@ radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_c struct radeon_device *rdev = dev->dev_private; struct drm_encoder *best_encoder = NULL; struct drm_encoder *encoder = NULL; - struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; + const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; struct drm_mode_object *obj; bool connected; int i; @@ -268,13 +268,13 @@ radeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector, continue; if (priority == true) { - DRM_DEBUG_KMS("1: conflicting encoders switching off %s\n", drm_get_connector_name(conflict)); - DRM_DEBUG_KMS("in favor of %s\n", drm_get_connector_name(connector)); + DRM_DEBUG_KMS("1: conflicting encoders switching off %s\n", conflict->name); + DRM_DEBUG_KMS("in favor of %s\n", connector->name); conflict->status = connector_status_disconnected; radeon_connector_update_scratch_regs(conflict, connector_status_disconnected); } else { - DRM_DEBUG_KMS("2: conflicting encoders switching off %s\n", drm_get_connector_name(connector)); - DRM_DEBUG_KMS("in favor of %s\n", drm_get_connector_name(conflict)); + DRM_DEBUG_KMS("2: conflicting encoders switching off %s\n", connector->name); + DRM_DEBUG_KMS("in favor of %s\n", conflict->name); current_status = connector_status_disconnected; } break; @@ -647,7 +647,7 @@ static void radeon_connector_destroy(struct drm_connector *connector) if (radeon_connector->edid) kfree(radeon_connector->edid); kfree(radeon_connector->con_priv); - drm_sysfs_connector_remove(connector); + drm_connector_unregister(connector); drm_connector_cleanup(connector); kfree(connector); } @@ -667,7 +667,7 @@ static int radeon_lvds_set_property(struct drm_connector *connector, if (connector->encoder) radeon_encoder = to_radeon_encoder(connector->encoder); else { - struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; + const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector)); } @@ -733,7 +733,7 @@ radeon_vga_detect(struct drm_connector *connector, bool force) struct radeon_device *rdev = dev->dev_private; struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct drm_encoder *encoder; - struct drm_encoder_helper_funcs *encoder_funcs; + const struct drm_encoder_helper_funcs *encoder_funcs; bool dret = false; enum drm_connector_status ret = connector_status_disconnected; @@ -753,7 +753,7 @@ radeon_vga_detect(struct drm_connector *connector, bool force) if (!radeon_connector->edid) { DRM_ERROR("%s: probed a monitor but no|invalid EDID\n", - drm_get_connector_name(connector)); + connector->name); ret = connector_status_connected; } else { radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); @@ -856,7 +856,7 @@ static enum drm_connector_status radeon_tv_detect(struct drm_connector *connector, bool force) { struct drm_encoder *encoder; - struct drm_encoder_helper_funcs *encoder_funcs; + const struct drm_encoder_helper_funcs *encoder_funcs; struct radeon_connector *radeon_connector = to_radeon_connector(connector); enum drm_connector_status ret = connector_status_disconnected; @@ -938,7 +938,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) struct radeon_device *rdev = dev->dev_private; struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct drm_encoder *encoder = NULL; - struct drm_encoder_helper_funcs *encoder_funcs; + const struct drm_encoder_helper_funcs *encoder_funcs; struct drm_mode_object *obj; int i; enum drm_connector_status ret = connector_status_disconnected; @@ -959,12 +959,12 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) if (!radeon_connector->edid) { DRM_ERROR("%s: probed a monitor but no|invalid EDID\n", - drm_get_connector_name(connector)); + connector->name); /* rs690 seems to have a problem with connectors not existing and always * return a block of 0's. If we see this just stop polling on this output */ if ((rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) && radeon_connector->base.null_edid_counter) { ret = connector_status_disconnected; - DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n", drm_get_connector_name(connector)); + DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n", connector->name); radeon_connector->ddc_bus = NULL; } else { ret = connector_status_connected; @@ -1215,7 +1215,7 @@ static void radeon_dp_connector_destroy(struct drm_connector *connector) if (radeon_dig_connector->dp_i2c_bus) radeon_i2c_destroy(radeon_dig_connector->dp_i2c_bus); kfree(radeon_connector->con_priv); - drm_sysfs_connector_remove(connector); + drm_connector_unregister(connector); drm_connector_cleanup(connector); kfree(connector); } @@ -1406,7 +1406,7 @@ radeon_dp_detect(struct drm_connector *connector, bool force) if (radeon_ddc_probe(radeon_connector, true)) /* try DDC */ ret = connector_status_connected; else if (radeon_connector->dac_load_detect) { /* try load detection */ - struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; + const struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; ret = encoder_funcs->detect(encoder, connector); } } @@ -1528,6 +1528,7 @@ radeon_add_atom_connector(struct drm_device *dev, uint32_t subpixel_order = SubPixelNone; bool shared_ddc = false; bool is_dp_bridge = false; + bool has_aux = false; if (connector_type == DRM_MODE_CONNECTOR_Unknown) return; @@ -1600,15 +1601,10 @@ radeon_add_atom_connector(struct drm_device *dev, radeon_dig_connector->igp_lane_info = igp_lane_info; radeon_connector->con_priv = radeon_dig_connector; if (i2c_bus->valid) { - /* add DP i2c bus */ - if (connector_type == DRM_MODE_CONNECTOR_eDP) - radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "eDP-auxch"); - else - radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch"); - if (!radeon_dig_connector->dp_i2c_bus) - DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n"); radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); - if (!radeon_connector->ddc_bus) + if (radeon_connector->ddc_bus) + has_aux = true; + else DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); } switch (connector_type) { @@ -1793,12 +1789,10 @@ radeon_add_atom_connector(struct drm_device *dev, drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type); drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs); if (i2c_bus->valid) { - /* add DP i2c bus */ - radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch"); - if (!radeon_dig_connector->dp_i2c_bus) - DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n"); radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); - if (!radeon_connector->ddc_bus) + if (radeon_connector->ddc_bus) + has_aux = true; + else DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); } subpixel_order = SubPixelHorizontalRGB; @@ -1829,12 +1823,10 @@ radeon_add_atom_connector(struct drm_device *dev, drm_connector_init(dev, &radeon_connector->base, &radeon_edp_connector_funcs, connector_type); drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs); if (i2c_bus->valid) { - /* add DP i2c bus */ - radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "eDP-auxch"); - if (!radeon_dig_connector->dp_i2c_bus) - DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n"); radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); - if (!radeon_connector->ddc_bus) + if (radeon_connector->ddc_bus) + has_aux = true; + else DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); } drm_object_attach_property(&radeon_connector->base.base, @@ -1891,7 +1883,11 @@ radeon_add_atom_connector(struct drm_device *dev, connector->polled = DRM_CONNECTOR_POLL_HPD; connector->display_info.subpixel_order = subpixel_order; - drm_sysfs_connector_add(connector); + drm_connector_register(connector); + + if (has_aux) + radeon_dp_aux_init(radeon_connector); + return; failed: @@ -2048,5 +2044,5 @@ radeon_add_legacy_connector(struct drm_device *dev, } else connector->polled = DRM_CONNECTOR_POLL_HPD; connector->display_info.subpixel_order = subpixel_order; - drm_sysfs_connector_add(connector); + drm_connector_register(connector); } diff --git a/sys/dev/pci/drm/radeon/radeon_device.c b/sys/dev/pci/drm/radeon/radeon_device.c index 085d94c7d40..cb5f0e0c158 100644 --- a/sys/dev/pci/drm/radeon/radeon_device.c +++ b/sys/dev/pci/drm/radeon/radeon_device.c @@ -1,4 +1,4 @@ -/* $OpenBSD: radeon_device.c,v 1.13 2015/04/12 03:54:10 jsg Exp $ */ +/* $OpenBSD: radeon_device.c,v 1.14 2017/07/01 16:14:10 kettenis Exp $ */ /* * Copyright 2008 Advanced Micro Devices, Inc. * Copyright 2008 Red Hat Inc. @@ -1231,7 +1231,7 @@ int radeon_suspend_kms(struct drm_device *dev) /* unpin the front buffers */ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->fb); + struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->primary->fb); struct radeon_bo *robj; if (rfb == NULL || rfb->obj == NULL) { diff --git a/sys/dev/pci/drm/radeon/radeon_display.c b/sys/dev/pci/drm/radeon/radeon_display.c index 62e15f918fa..06f58148b3f 100644 --- a/sys/dev/pci/drm/radeon/radeon_display.c +++ b/sys/dev/pci/drm/radeon/radeon_display.c @@ -1,4 +1,4 @@ -/* $OpenBSD: radeon_display.c,v 1.12 2015/09/26 19:52:16 kettenis Exp $ */ +/* $OpenBSD: radeon_display.c,v 1.13 2017/07/01 16:14:10 kettenis Exp $ */ /* * Copyright 2007-8 Advanced Micro Devices, Inc. * Copyright 2008 Red Hat Inc. @@ -31,6 +31,7 @@ #include "atom.h" #include <dev/pci/drm/drm_crtc_helper.h> +#include <dev/pci/drm/drm_plane_helper.h> #include <dev/pci/drm/drm_edid.h> static void avivo_crtc_load_lut(struct drm_crtc *crtc) @@ -298,8 +299,9 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id) * to complete in this vblank? */ if (update_pending && - (DRM_SCANOUTPOS_VALID & radeon_get_crtc_scanoutpos(rdev->ddev, crtc_id, 0, - &vpos, &hpos, NULL, NULL)) && + (DRM_SCANOUTPOS_VALID & radeon_get_crtc_scanoutpos(rdev->ddev, + crtc_id, 0, + &vpos, &hpos, NULL, NULL, &rdev->mode_info.crtcs[crtc_id]->base.hwmode)) && ((vpos >= (99 * rdev->mode_info.crtcs[crtc_id]->base.hwmode.crtc_vdisplay)/100) || (vpos < 0 && !ASIC_IS_AVIVO(rdev)))) { /* crtc didn't flip in this target vblank interval, @@ -361,7 +363,7 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc, work->event = event; work->rdev = rdev; work->crtc_id = radeon_crtc->crtc_id; - old_radeon_fb = to_radeon_framebuffer(crtc->fb); + old_radeon_fb = to_radeon_framebuffer(crtc->primary->fb); new_radeon_fb = to_radeon_framebuffer(fb); /* schedule unpin of the old buffer */ obj = old_radeon_fb->obj; @@ -452,7 +454,7 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc, spin_unlock_irqrestore(&dev->event_lock, flags); /* update crtc fb */ - crtc->fb = fb; + crtc->primary->fb = fb; r = drm_vblank_get(dev, radeon_crtc->crtc_id); if (r) { @@ -595,7 +597,7 @@ static void radeon_print_display_setup(struct drm_device *dev) list_for_each_entry(connector, &dev->mode_config.connector_list, head) { radeon_connector = to_radeon_connector(connector); DRM_INFO("Connector %d:\n", i); - DRM_INFO(" %s\n", drm_get_connector_name(connector)); + DRM_INFO(" %s\n", connector->name); if (radeon_connector->hpd.hpd != RADEON_HPD_NONE) DRM_INFO(" %s\n", hpd_names[radeon_connector->hpd.hpd]); if (radeon_connector->ddc_bus) { @@ -1537,8 +1539,8 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, * unknown small number of scanlines wrt. real scanout position. * */ -int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int flags, - int *vpos, int *hpos, ktime_t *stime, ktime_t *etime) +int radeon_get_crtc_scanoutpos(struct drm_device *dev, unsigned int crtc, unsigned int flags, + int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode) { u32 stat_crtc = 0, vbl = 0, position = 0; int vbl_start, vbl_end, vtotal, ret = 0; @@ -1678,7 +1680,7 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int fl /* In vblank? */ if (in_vbl) - ret |= DRM_SCANOUTPOS_INVBL; + ret |= DRM_SCANOUTPOS_IN_VBLANK; return ret; } diff --git a/sys/dev/pci/drm/radeon/radeon_dp_auxch.c b/sys/dev/pci/drm/radeon/radeon_dp_auxch.c new file mode 100644 index 00000000000..2bb7f05fe09 --- /dev/null +++ b/sys/dev/pci/drm/radeon/radeon_dp_auxch.c @@ -0,0 +1,204 @@ +/* + * Copyright 2015 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Dave Airlie + */ +#include <dev/pci/drm/drmP.h> +#include <dev/pci/drm/radeon_drm.h> +#include "radeon.h" +#include "nid.h" + +#define AUX_RX_ERROR_FLAGS (AUX_SW_RX_OVERFLOW | \ + AUX_SW_RX_HPD_DISCON | \ + AUX_SW_RX_PARTIAL_BYTE | \ + AUX_SW_NON_AUX_MODE | \ + AUX_SW_RX_SYNC_INVALID_L | \ + AUX_SW_RX_SYNC_INVALID_H | \ + AUX_SW_RX_INVALID_START | \ + AUX_SW_RX_RECV_NO_DET | \ + AUX_SW_RX_RECV_INVALID_H | \ + AUX_SW_RX_RECV_INVALID_V) + +#define AUX_SW_REPLY_GET_BYTE_COUNT(x) (((x) >> 24) & 0x1f) + +#define BARE_ADDRESS_SIZE 3 + +static const u32 aux_offset[] = +{ + 0x6200 - 0x6200, + 0x6250 - 0x6200, + 0x62a0 - 0x6200, + 0x6300 - 0x6200, + 0x6350 - 0x6200, + 0x63a0 - 0x6200, +}; + +ssize_t +radeon_dp_aux_transfer_native(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) +{ + struct radeon_i2c_chan *chan = + container_of(aux, struct radeon_i2c_chan, aux); + struct drm_device *dev = chan->dev; + struct radeon_device *rdev = dev->dev_private; + int ret = 0, i; + uint32_t tmp, ack = 0; + int instance = chan->rec.i2c_id & 0xf; + u8 byte; + u8 *buf = msg->buffer; + int retry_count = 0; + int bytes; + int msize; + bool is_write = false; + + if (WARN_ON(msg->size > 16)) + return -E2BIG; + + switch (msg->request & ~DP_AUX_I2C_MOT) { + case DP_AUX_NATIVE_WRITE: + case DP_AUX_I2C_WRITE: + is_write = true; + break; + case DP_AUX_NATIVE_READ: + case DP_AUX_I2C_READ: + break; + default: + return -EINVAL; + } + + /* work out two sizes required */ + msize = 0; + bytes = BARE_ADDRESS_SIZE; + if (msg->size) { + msize = msg->size - 1; + bytes++; + if (is_write) + bytes += msg->size; + } + + mutex_lock(&chan->mutex); + + /* switch the pad to aux mode */ + tmp = RREG32(chan->rec.mask_clk_reg); + tmp |= (1 << 16); + WREG32(chan->rec.mask_clk_reg, tmp); + + /* setup AUX control register with correct HPD pin */ + tmp = RREG32(AUX_CONTROL + aux_offset[instance]); + + tmp &= AUX_HPD_SEL(0x7); + tmp |= AUX_HPD_SEL(chan->rec.hpd); + tmp |= AUX_EN | AUX_LS_READ_EN; + + WREG32(AUX_CONTROL + aux_offset[instance], tmp); + + /* atombios appears to write this twice lets copy it */ + WREG32(AUX_SW_CONTROL + aux_offset[instance], + AUX_SW_WR_BYTES(bytes)); + WREG32(AUX_SW_CONTROL + aux_offset[instance], + AUX_SW_WR_BYTES(bytes)); + + /* write the data header into the registers */ + /* request, address, msg size */ + byte = (msg->request << 4) | ((msg->address >> 16) & 0xf); + WREG32(AUX_SW_DATA + aux_offset[instance], + AUX_SW_DATA_MASK(byte) | AUX_SW_AUTOINCREMENT_DISABLE); + + byte = (msg->address >> 8) & 0xff; + WREG32(AUX_SW_DATA + aux_offset[instance], + AUX_SW_DATA_MASK(byte)); + + byte = msg->address & 0xff; + WREG32(AUX_SW_DATA + aux_offset[instance], + AUX_SW_DATA_MASK(byte)); + + byte = msize; + WREG32(AUX_SW_DATA + aux_offset[instance], + AUX_SW_DATA_MASK(byte)); + + /* if we are writing - write the msg buffer */ + if (is_write) { + for (i = 0; i < msg->size; i++) { + WREG32(AUX_SW_DATA + aux_offset[instance], + AUX_SW_DATA_MASK(buf[i])); + } + } + + /* clear the ACK */ + WREG32(AUX_SW_INTERRUPT_CONTROL + aux_offset[instance], AUX_SW_DONE_ACK); + + /* write the size and GO bits */ + WREG32(AUX_SW_CONTROL + aux_offset[instance], + AUX_SW_WR_BYTES(bytes) | AUX_SW_GO); + + /* poll the status registers - TODO irq support */ + do { + tmp = RREG32(AUX_SW_STATUS + aux_offset[instance]); + if (tmp & AUX_SW_DONE) { + break; + } + usleep_range(100, 200); + } while (retry_count++ < 1000); + + if (retry_count >= 1000) { + DRM_ERROR("auxch hw never signalled completion, error %08x\n", tmp); + ret = -EIO; + goto done; + } + + if (tmp & AUX_SW_RX_TIMEOUT) { + DRM_DEBUG_KMS("dp_aux_ch timed out\n"); + ret = -ETIMEDOUT; + goto done; + } + if (tmp & AUX_RX_ERROR_FLAGS) { + DRM_DEBUG_KMS("dp_aux_ch flags not zero: %08x\n", tmp); + ret = -EIO; + goto done; + } + + bytes = AUX_SW_REPLY_GET_BYTE_COUNT(tmp); + if (bytes) { + WREG32(AUX_SW_DATA + aux_offset[instance], + AUX_SW_DATA_RW | AUX_SW_AUTOINCREMENT_DISABLE); + + tmp = RREG32(AUX_SW_DATA + aux_offset[instance]); + ack = (tmp >> 8) & 0xff; + + for (i = 0; i < bytes - 1; i++) { + tmp = RREG32(AUX_SW_DATA + aux_offset[instance]); + if (buf) + buf[i] = (tmp >> 8) & 0xff; + } + if (buf) + ret = bytes - 1; + } + + WREG32(AUX_SW_INTERRUPT_CONTROL + aux_offset[instance], AUX_SW_DONE_ACK); + + if (is_write) + ret = msg->size; +done: + mutex_unlock(&chan->mutex); + + if (ret >= 0) + msg->reply = ack >> 4; + return ret; +} diff --git a/sys/dev/pci/drm/radeon/radeon_fb.c b/sys/dev/pci/drm/radeon/radeon_fb.c index e318c825d94..b6e079d3005 100644 --- a/sys/dev/pci/drm/radeon/radeon_fb.c +++ b/sys/dev/pci/drm/radeon/radeon_fb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: radeon_fb.c,v 1.9 2015/09/27 21:28:14 kettenis Exp $ */ +/* $OpenBSD: radeon_fb.c,v 1.10 2017/07/01 16:14:10 kettenis Exp $ */ /* * Copyright © 2007 David Airlie * @@ -407,7 +407,9 @@ int radeon_fbdev_init(struct radeon_device *rdev) rfbdev->rdev = rdev; rdev->mode_info.rfbdev = rfbdev; - rfbdev->helper.funcs = &radeon_fb_helper_funcs; + + drm_fb_helper_prepare(rdev->ddev, &rfbdev->helper, + &radeon_fb_helper_funcs); ret = drm_fb_helper_init(rdev->ddev, &rfbdev->helper, rdev->num_crtc, @@ -432,7 +434,7 @@ int radeon_fbdev_init(struct radeon_device *rdev) fb_helper_conn = fb_helper->connector_info[i]; connector = fb_helper_conn->connector; - mode = &fb_helper_conn->cmdline_mode; + mode = &connector->cmdline_mode; mode->specified = true; mode->xres = rdev->sf.sf_width; @@ -491,12 +493,12 @@ radeondrm_burner(void *v, u_int on, u_int flags) task_del(systq, &rdev->burner_task); if (on) - rdev->burner_dpms_mode = DRM_MODE_DPMS_ON; + rdev->burner_fblank = FB_BLANK_UNBLANK; else { if (flags & WSDISPLAY_BURN_VBLANK) - rdev->burner_dpms_mode = DRM_MODE_DPMS_OFF; + rdev->burner_fblank = FB_BLANK_VSYNC_SUSPEND; else - rdev->burner_dpms_mode = DRM_MODE_DPMS_STANDBY; + rdev->burner_fblank = FB_BLANK_NORMAL; } /* @@ -512,5 +514,5 @@ radeondrm_burner_cb(void *arg1) struct radeon_device *rdev = arg1; struct drm_fb_helper *helper = &rdev->mode_info.rfbdev->helper; - drm_fb_helper_dpms(helper, rdev->burner_dpms_mode); + drm_fb_helper_blank(rdev->burner_fblank, helper->fbdev); } diff --git a/sys/dev/pci/drm/radeon/radeon_i2c.c b/sys/dev/pci/drm/radeon/radeon_i2c.c index 12119b03677..33a942b4ab4 100644 --- a/sys/dev/pci/drm/radeon/radeon_i2c.c +++ b/sys/dev/pci/drm/radeon/radeon_i2c.c @@ -1,4 +1,4 @@ -/* $OpenBSD: radeon_i2c.c,v 1.5 2015/04/06 07:38:49 jsg Exp $ */ +/* $OpenBSD: radeon_i2c.c,v 1.6 2017/07/01 16:14:10 kettenis Exp $ */ /* * Copyright 2007-8 Advanced Micro Devices, Inc. * Copyright 2008 Red Hat Inc. @@ -34,11 +34,9 @@ #include <dev/i2c/i2cvar.h> #include <dev/i2c/i2c_bitbang.h> -#ifdef notyet -extern int radeon_atom_hw_i2c_xfer(struct i2c_controller *i2c_adap, +extern int radeon_atom_hw_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num); -#endif -extern u32 radeon_atom_hw_i2c_func(struct i2c_controller *adap); +extern u32 radeon_atom_hw_i2c_func(struct i2c_adapter *adap); /** * radeon_ddc_probe @@ -49,23 +47,32 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool use_aux) u8 out = 0x0; u8 buf[8]; int ret; + struct i2c_msg msgs[] = { + { + .addr = DDC_ADDR, + .flags = 0, + .len = 1, + .buf = &out, + }, + { + .addr = DDC_ADDR, + .flags = I2C_M_RD, + .len = 8, + .buf = buf, + } + }; /* on hw with routers, select right port */ if (radeon_connector->router.ddc_valid) radeon_router_select_ddc_port(radeon_connector); if (use_aux) { - struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; - iic_acquire_bus(&dig->dp_i2c_bus->adapter, 0); - ret = iic_exec(&dig->dp_i2c_bus->adapter, I2C_OP_READ_WITH_STOP, DDC_ADDR, &out, 1, buf, 8, 0); - iic_release_bus(&dig->dp_i2c_bus->adapter, 0); + ret = i2c_transfer(&radeon_connector->ddc_bus->aux.ddc, msgs, 2); } else { - iic_acquire_bus(&radeon_connector->ddc_bus->adapter, 0); - ret = iic_exec(&radeon_connector->ddc_bus->adapter, I2C_OP_READ_WITH_STOP, DDC_ADDR, &out, 1, buf, 8, 0); - iic_release_bus(&radeon_connector->ddc_bus->adapter, 0); + ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2); } - if (ret) + if (ret != 2) /* Couldn't find an accessible DDC on this connector */ return false; /* Probe also for valid EDID header @@ -315,7 +322,6 @@ radeon_write_byte(void *cookie, u_int8_t byte, int flags) /* hw i2c */ -#ifdef notyet static u32 radeon_get_i2c_prescale(struct radeon_device *rdev) { u32 sclk = rdev->pm.current_sclk; @@ -406,7 +412,7 @@ static u32 radeon_get_i2c_prescale(struct radeon_device *rdev) /* hw i2c engine for r1xx-4xx hardware * hw can buffer up to 15 bytes */ -static int r100_hw_i2c_xfer(struct i2c_controller *i2c_adap, +static int r100_hw_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) { struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); @@ -659,7 +665,7 @@ done: /* hw i2c engine for r5xx hardware * hw can buffer up to 15 bytes */ -static int r500_hw_i2c_xfer(struct i2c_controller *i2c_adap, +static int r500_hw_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) { struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); @@ -892,7 +898,7 @@ done: return ret; } -static int radeon_hw_i2c_xfer(struct i2c_controller *i2c_adap, +static int radeon_hw_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) { struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); @@ -969,21 +975,26 @@ static int radeon_hw_i2c_xfer(struct i2c_controller *i2c_adap, return ret; } +#ifdef notyet static u32 radeon_hw_i2c_func(struct i2c_controller *adap) { return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; } +#endif static const struct i2c_algorithm radeon_i2c_algo = { .master_xfer = radeon_hw_i2c_xfer, +#ifdef notyet .functionality = radeon_hw_i2c_func, +#endif }; static const struct i2c_algorithm radeon_atom_i2c_algo = { .master_xfer = radeon_atom_hw_i2c_xfer, +#ifdef notyet .functionality = radeon_atom_hw_i2c_func, +#endif }; -#endif // notyet struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, struct radeon_i2c_bus_rec *rec, @@ -1006,32 +1017,19 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, i2c->adapter.owner = THIS_MODULE; i2c->adapter.class = I2C_CLASS_DDC; i2c->adapter.dev.parent = &dev->pdev->dev; -#else - i2c->adapter.ic_cookie = i2c; - i2c->adapter.ic_acquire_bus = radeon_acquire_bus; - i2c->adapter.ic_release_bus = radeon_release_bus; - i2c->adapter.ic_send_start = radeon_send_start; - i2c->adapter.ic_send_stop = radeon_send_stop; - i2c->adapter.ic_initiate_xfer = radeon_initiate_xfer; - i2c->adapter.ic_read_byte = radeon_read_byte; - i2c->adapter.ic_write_byte = radeon_write_byte; #endif i2c->dev = dev; -#ifdef notyet i2c_set_adapdata(&i2c->adapter, i2c); -#endif if (rec->mm_i2c || (rec->hw_capable && radeon_hw_i2c && ((rdev->family <= CHIP_RS480) || ((rdev->family >= CHIP_RV515) && (rdev->family <= CHIP_R580))))) { /* set the radeon hw i2c adapter */ -#ifdef notyet snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), "Radeon i2c hw bus %s", name); i2c->adapter.algo = &radeon_i2c_algo; ret = i2c_add_adapter(&i2c->adapter); -#endif if (ret) { DRM_ERROR("Failed to register hw i2c %s\n", name); goto out_free; @@ -1040,21 +1038,19 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, radeon_hw_i2c && ASIC_IS_DCE3(rdev)) { /* hw i2c using atom */ -#ifdef notyet snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), "Radeon i2c hw bus %s", name); i2c->adapter.algo = &radeon_atom_i2c_algo; ret = i2c_add_adapter(&i2c->adapter); -#endif if (ret) { DRM_ERROR("Failed to register hw i2c %s\n", name); goto out_free; } } else { /* set the radeon bit adapter */ -#ifdef notyet snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), "Radeon i2c bit bus %s", name); +#ifdef notyet i2c->adapter.algo_data = &i2c->algo.bit; i2c->algo.bit.pre_xfer = pre_xfer; i2c->algo.bit.post_xfer = post_xfer; @@ -1066,6 +1062,15 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, i2c->algo.bit.timeout = usecs_to_jiffies(2200); /* from VESA */ i2c->algo.bit.data = i2c; ret = i2c_bit_add_bus(&i2c->adapter); +#else + i2c->adapter.ic.ic_cookie = i2c; + i2c->adapter.ic.ic_acquire_bus = radeon_acquire_bus; + i2c->adapter.ic.ic_release_bus = radeon_release_bus; + i2c->adapter.ic.ic_send_start = radeon_send_start; + i2c->adapter.ic.ic_send_stop = radeon_send_stop; + i2c->adapter.ic.ic_initiate_xfer = radeon_initiate_xfer; + i2c->adapter.ic.ic_read_byte = radeon_read_byte; + i2c->adapter.ic.ic_write_byte = radeon_write_byte; #endif if (ret) { DRM_ERROR("Failed to register bit i2c %s\n", name); @@ -1079,55 +1084,14 @@ out_free: return NULL; } -struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev, - struct radeon_i2c_bus_rec *rec, - const char *name) -{ - struct radeon_i2c_chan *i2c; - int ret = 0; - - i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL); - if (i2c == NULL) - return NULL; - - i2c->rec = *rec; -#ifdef notyet - i2c->adapter.owner = THIS_MODULE; - i2c->adapter.class = I2C_CLASS_DDC; - i2c->adapter.dev.parent = &dev->pdev->dev; -#endif - i2c->dev = dev; -#ifdef notyet - snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), - "Radeon aux bus %s", name); - i2c_set_adapdata(&i2c->adapter, i2c); - i2c->adapter.algo_data = &i2c->algo.dp; -#endif - i2c->adapter.ic_cookie = &i2c->algo.dp; - i2c->algo.dp.aux_ch = radeon_dp_i2c_aux_ch; - i2c->algo.dp.adapter = &i2c->adapter; - i2c->algo.dp.address = 0; - ret = i2c_dp_aux_add_bus(&i2c->adapter); - if (ret) { - DRM_INFO("Failed to register i2c %s\n", name); - goto out_free; - } - - return i2c; -out_free: - kfree(i2c); - return NULL; -} - void radeon_i2c_destroy(struct radeon_i2c_chan *i2c) { - printf("%s stub\n", __func__); -#ifdef notyet if (!i2c) return; i2c_del_adapter(&i2c->adapter); + if (i2c->has_aux) + drm_dp_aux_unregister(&i2c->aux); kfree(i2c); -#endif } /* Add the default buses */ @@ -1196,8 +1160,6 @@ void radeon_i2c_get_byte(struct radeon_i2c_chan *i2c_bus, u8 addr, u8 *val) { - printf("%s stub\n", __func__); -#ifdef notyet u8 out_buf[2]; u8 in_buf[2]; struct i2c_msg msgs[] = { @@ -1225,7 +1187,6 @@ void radeon_i2c_get_byte(struct radeon_i2c_chan *i2c_bus, DRM_DEBUG("i2c 0x%02x 0x%02x read failed\n", addr, *val); } -#endif } void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c_bus, @@ -1233,8 +1194,6 @@ void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c_bus, u8 addr, u8 val) { - printf("%s stub\n", __func__); -#ifdef notyet uint8_t out_buf[2]; struct i2c_msg msg = { .addr = slave_addr, @@ -1249,7 +1208,6 @@ void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c_bus, if (i2c_transfer(&i2c_bus->adapter, &msg, 1) != 1) DRM_DEBUG("i2c 0x%02x 0x%02x write failed\n", addr, val); -#endif } /* ddc router switching */ diff --git a/sys/dev/pci/drm/radeon/radeon_irq_kms.c b/sys/dev/pci/drm/radeon/radeon_irq_kms.c index 53ffc6bbf09..955957a8502 100644 --- a/sys/dev/pci/drm/radeon/radeon_irq_kms.c +++ b/sys/dev/pci/drm/radeon/radeon_irq_kms.c @@ -1,4 +1,4 @@ -/* $OpenBSD: radeon_irq_kms.c,v 1.9 2015/04/18 14:47:35 jsg Exp $ */ +/* $OpenBSD: radeon_irq_kms.c,v 1.10 2017/07/01 16:14:10 kettenis Exp $ */ /* * Copyright 2008 Advanced Micro Devices, Inc. * Copyright 2008 Red Hat Inc. @@ -265,7 +265,7 @@ int radeon_irq_kms_init(struct radeon_device *rdev) } #endif rdev->irq.installed = true; - r = drm_irq_install(rdev->ddev); + r = drm_irq_install(rdev->ddev, rdev->ddev->pdev->irq); if (r) { rdev->irq.installed = false; return r; diff --git a/sys/dev/pci/drm/radeon/radeon_kms.c b/sys/dev/pci/drm/radeon/radeon_kms.c index 4b5dfd595ac..89aa2ba9057 100644 --- a/sys/dev/pci/drm/radeon/radeon_kms.c +++ b/sys/dev/pci/drm/radeon/radeon_kms.c @@ -1,4 +1,4 @@ -/* $OpenBSD: radeon_kms.c,v 1.50 2017/06/19 11:03:30 fcambus Exp $ */ +/* $OpenBSD: radeon_kms.c,v 1.51 2017/07/01 16:14:10 kettenis Exp $ */ /* * Copyright 2008 Advanced Micro Devices, Inc. * Copyright 2008 Red Hat Inc. @@ -74,11 +74,11 @@ void radeon_driver_lastclose_kms(struct drm_device *); int radeon_driver_open_kms(struct drm_device *, struct drm_file *); void radeon_driver_postclose_kms(struct drm_device *, struct drm_file *); void radeon_driver_preclose_kms(struct drm_device *, struct drm_file *); -u32 radeon_get_vblank_counter_kms(struct drm_device *, int); -int radeon_enable_vblank_kms(struct drm_device *, int); -void radeon_disable_vblank_kms(struct drm_device *, int); -int radeon_get_vblank_timestamp_kms(struct drm_device *, int, int *, - struct timeval *, unsigned); +u32 radeon_get_vblank_counter_kms(struct drm_device *, unsigned int); +int radeon_enable_vblank_kms(struct drm_device *, unsigned int); +void radeon_disable_vblank_kms(struct drm_device *, unsigned int); +int radeon_get_vblank_timestamp_kms(struct drm_device *, unsigned int, + int *, struct timeval *, unsigned); int radeon_dma_ioctl_kms(struct drm_device *, struct drm_dma *, struct drm_file *); @@ -146,6 +146,7 @@ int radeon_hw_i2c = 0; int radeon_pcie_gen2 = -1; int radeon_msi = -1; int radeon_lockup_timeout = 10000; +int radeon_auxch = -1; MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); module_param_named(no_wb, radeon_no_wb, int, 0444); @@ -208,7 +209,7 @@ const struct drm_pcidev radeondrm_pciidlist[] = { radeon_PCI_IDS }; -static struct drm_driver_info kms_driver = { +static struct drm_driver kms_driver = { .driver_features = DRIVER_USE_AGP | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | @@ -435,9 +436,7 @@ radeondrm_doswitch(void *v) #ifdef __sparc64__ fbwscons_setcolormap(&rdev->sf, radeondrm_setcolor); #endif - drm_modeset_lock_all(rdev->ddev); - drm_fb_helper_restore_fbdev_mode((void *)rdev->mode_info.rfbdev); - drm_modeset_unlock_all(rdev->ddev); + drm_fb_helper_restore_fbdev_mode_unlocked((void *)rdev->mode_info.rfbdev); if (rdev->switchcb) (rdev->switchcb)(rdev->switchcbarg, 0, 0); @@ -636,6 +635,7 @@ radeondrm_attach_kms(struct device *parent, struct device *self, void *aux) rdev->dev.dv_xname); return; } + rdev->pdev->irq = -1; #ifdef __sparc64__ { @@ -727,6 +727,7 @@ radeondrm_attachhook(struct device *self) } { + struct drm_fb_helper *fb_helper = (void *)rdev->mode_info.rfbdev; struct wsemuldisplaydev_attach_args aa; struct rasops_info *ri = &rdev->ro; @@ -738,9 +739,7 @@ radeondrm_attachhook(struct device *self) #ifdef __sparc64__ fbwscons_setcolormap(&rdev->sf, radeondrm_setcolor); #endif - drm_modeset_lock_all(rdev->ddev); - drm_fb_helper_restore_fbdev_mode((void *)rdev->mode_info.rfbdev); - drm_modeset_unlock_all(rdev->ddev); + drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper); #ifndef __sparc64__ ri->ri_flg = RI_CENTER | RI_VCONS | RI_WRONLY; @@ -1117,11 +1116,8 @@ void radeon_driver_lastclose_kms(struct drm_device *dev) #ifdef __sparc64__ fbwscons_setcolormap(&rdev->sf, radeondrm_setcolor); #endif - if (rdev->mode_info.mode_config_initialized) { - drm_modeset_lock_all(dev); - drm_fb_helper_restore_fbdev_mode(fb_helper); - drm_modeset_unlock_all(dev); - } + if (rdev->mode_info.mode_config_initialized) + drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper); #ifdef notyet vga_switcheroo_process_delayed_switch(); #endif @@ -1250,7 +1246,7 @@ void radeon_driver_preclose_kms(struct drm_device *dev, * Gets the frame count on the requested crtc (all asics). * Returns frame count on success, -EINVAL on failure. */ -u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc) +u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int crtc) { struct radeon_device *rdev = dev->dev_private; @@ -1271,7 +1267,7 @@ u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc) * Enable the interrupt on the requested crtc (all asics). * Returns 0 on success, -EINVAL on failure. */ -int radeon_enable_vblank_kms(struct drm_device *dev, int crtc) +int radeon_enable_vblank_kms(struct drm_device *dev, unsigned int crtc) { struct radeon_device *rdev = dev->dev_private; unsigned long irqflags; @@ -1297,7 +1293,7 @@ int radeon_enable_vblank_kms(struct drm_device *dev, int crtc) * * Disable the interrupt on the requested crtc (all asics). */ -void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) +void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int crtc) { struct radeon_device *rdev = dev->dev_private; unsigned long irqflags; @@ -1326,7 +1322,7 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) * scanout position. (all asics). * Returns postive status flags on success, negative error on failure. */ -int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, +int radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int crtc, int *max_error, struct timeval *vblank_time, unsigned flags) @@ -1341,11 +1337,13 @@ int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, /* Get associated drm_crtc: */ drmcrtc = &rdev->mode_info.crtcs[crtc]->base; + if (!drmcrtc) + return -EINVAL; /* Helper routine in DRM core does all the work: */ return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, vblank_time, flags, - drmcrtc, &drmcrtc->hwmode); + &drmcrtc->hwmode); } /* diff --git a/sys/dev/pci/drm/radeon/radeon_legacy_crtc.c b/sys/dev/pci/drm/radeon/radeon_legacy_crtc.c index c4236800b75..ea4bcc97531 100644 --- a/sys/dev/pci/drm/radeon/radeon_legacy_crtc.c +++ b/sys/dev/pci/drm/radeon/radeon_legacy_crtc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: radeon_legacy_crtc.c,v 1.3 2014/02/10 01:22:10 jsg Exp $ */ +/* $OpenBSD: radeon_legacy_crtc.c,v 1.4 2017/07/01 16:14:10 kettenis Exp $ */ /* * Copyright 2007-8 Advanced Micro Devices, Inc. * Copyright 2008 Red Hat Inc. @@ -386,7 +386,7 @@ int radeon_crtc_do_set_base(struct drm_crtc *crtc, DRM_DEBUG_KMS("\n"); /* no fb bound */ - if (!atomic && !crtc->fb) { + if (!atomic && !crtc->primary->fb) { DRM_DEBUG_KMS("No FB bound\n"); return 0; } @@ -396,8 +396,8 @@ int radeon_crtc_do_set_base(struct drm_crtc *crtc, target_fb = fb; } else { - radeon_fb = to_radeon_framebuffer(crtc->fb); - target_fb = crtc->fb; + radeon_fb = to_radeon_framebuffer(crtc->primary->fb); + target_fb = crtc->primary->fb; } switch (target_fb->bits_per_pixel) { @@ -445,7 +445,7 @@ retry: * We don't shutdown the display controller because new buffer * will end up in same spot. */ - if (!atomic && fb && fb != crtc->fb) { + if (!atomic && fb && fb != crtc->primary->fb) { struct radeon_bo *old_rbo; unsigned long nsize, osize; @@ -556,7 +556,7 @@ retry: WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, crtc_offset); WREG32(RADEON_CRTC_PITCH + radeon_crtc->crtc_offset, crtc_pitch); - if (!atomic && fb && fb != crtc->fb) { + if (!atomic && fb && fb != crtc->primary->fb) { radeon_fb = to_radeon_framebuffer(fb); rbo = gem_to_radeon_bo(radeon_fb->obj); r = radeon_bo_reserve(rbo, false); @@ -600,7 +600,7 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod } } - switch (crtc->fb->bits_per_pixel) { + switch (crtc->primary->fb->bits_per_pixel) { case 8: format = 2; break; diff --git a/sys/dev/pci/drm/radeon/radeon_legacy_encoders.c b/sys/dev/pci/drm/radeon/radeon_legacy_encoders.c index 686fa1d9634..3f26f128451 100644 --- a/sys/dev/pci/drm/radeon/radeon_legacy_encoders.c +++ b/sys/dev/pci/drm/radeon/radeon_legacy_encoders.c @@ -1,4 +1,4 @@ -/* $OpenBSD: radeon_legacy_encoders.c,v 1.4 2015/09/23 23:12:12 kettenis Exp $ */ +/* $OpenBSD: radeon_legacy_encoders.c,v 1.5 2017/07/01 16:14:10 kettenis Exp $ */ /* * Copyright 2007-8 Advanced Micro Devices, Inc. * Copyright 2008 Red Hat Inc. @@ -38,7 +38,7 @@ void radeon_add_legacy_encoder(struct drm_device *, uint32_t, uint32_t); static void radeon_legacy_encoder_disable(struct drm_encoder *encoder) { struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_encoder_helper_funcs *encoder_funcs; + const struct drm_encoder_helper_funcs *encoder_funcs; encoder_funcs = encoder->helper_private; encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF); diff --git a/sys/dev/pci/drm/radeon/radeon_mode.h b/sys/dev/pci/drm/radeon/radeon_mode.h index 9f571c49e8c..65e069baf60 100644 --- a/sys/dev/pci/drm/radeon/radeon_mode.h +++ b/sys/dev/pci/drm/radeon/radeon_mode.h @@ -1,4 +1,4 @@ -/* $OpenBSD: radeon_mode.h,v 1.3 2015/09/23 23:12:12 kettenis Exp $ */ +/* $OpenBSD: radeon_mode.h,v 1.4 2017/07/01 16:14:10 kettenis Exp $ */ /* * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and * VA Linux Systems Inc., Fremont, California. @@ -184,11 +184,17 @@ struct radeon_pll { }; struct radeon_i2c_chan { - struct i2c_controller adapter; + struct i2c_adapter adapter; struct drm_device *dev; +#if 0 union { struct i2c_algo_dp_aux_data dp; } algo; +#else + struct drm_dp_aux aux; + bool has_aux; + struct rwlock mutex; +#endif struct radeon_i2c_bus_rec rec; }; @@ -520,6 +526,10 @@ extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector); extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector); extern int radeon_dp_get_panel_mode(struct drm_encoder *encoder, struct drm_connector *connector); +extern void radeon_dp_aux_init(struct radeon_connector *radeon_connector); +extern ssize_t +radeon_dp_aux_transfer_native(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg); + extern void atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode); extern void radeon_atom_encoder_init(struct radeon_device *rdev); extern void radeon_atom_disp_eng_pll_init(struct radeon_device *rdev); @@ -629,10 +639,10 @@ extern int radeon_crtc_cursor_set(struct drm_crtc *crtc, extern int radeon_crtc_cursor_move(struct drm_crtc *crtc, int x, int y); -extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, - unsigned int flags, - int *vpos, int *hpos, ktime_t *stime, - ktime_t *etime); +extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, + unsigned int flags, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode); extern bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev); extern struct edid * diff --git a/sys/dev/pci/drm/radeon/radeon_pm.c b/sys/dev/pci/drm/radeon/radeon_pm.c index c8a597d48c4..f331d8a9f8f 100644 --- a/sys/dev/pci/drm/radeon/radeon_pm.c +++ b/sys/dev/pci/drm/radeon/radeon_pm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: radeon_pm.c,v 1.14 2015/09/23 23:12:12 kettenis Exp $ */ +/* $OpenBSD: radeon_pm.c,v 1.15 2017/07/01 16:14:10 kettenis Exp $ */ /* * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -764,9 +764,12 @@ static bool radeon_pm_in_vbl(struct radeon_device *rdev) */ for (crtc = 0; (crtc < rdev->num_crtc) && in_vbl; crtc++) { if (rdev->pm.active_crtcs & (1 << crtc)) { - vbl_status = radeon_get_crtc_scanoutpos(rdev->ddev, crtc, 0, &vpos, &hpos, NULL, NULL); + vbl_status = radeon_get_crtc_scanoutpos(rdev->ddev, + crtc, 0, + &vpos, &hpos, NULL, NULL, + &rdev->mode_info.crtcs[crtc]->base.hwmode); if ((vbl_status & DRM_SCANOUTPOS_VALID) && - !(vbl_status & DRM_SCANOUTPOS_INVBL)) + !(vbl_status & DRM_SCANOUTPOS_IN_VBLANK)) in_vbl = false; } } |