View | Details | Raw Unified | Return to bug 205699 | Differences between
and this patch

Collapse All | Expand All

(-)a/drivers/gpu/drm/drm_dp_helper.c (-2 / +16 lines)
Lines 1155-1160 static const struct dpcd_quirk dpcd_quirk_list[] = { Link Here
1155
	{ OUI(0x00, 0x10, 0xfa), DEVICE_ID_ANY, false, BIT(DP_DPCD_QUIRK_NO_PSR) },
1155
	{ OUI(0x00, 0x10, 0xfa), DEVICE_ID_ANY, false, BIT(DP_DPCD_QUIRK_NO_PSR) },
1156
	/* CH7511 seems to leave SINK_COUNT zeroed */
1156
	/* CH7511 seems to leave SINK_COUNT zeroed */
1157
	{ OUI(0x00, 0x00, 0x00), DEVICE_ID('C', 'H', '7', '5', '1', '1'), false, BIT(DP_DPCD_QUIRK_NO_SINK_COUNT) },
1157
	{ OUI(0x00, 0x00, 0x00), DEVICE_ID('C', 'H', '7', '5', '1', '1'), false, BIT(DP_DPCD_QUIRK_NO_SINK_COUNT) },
1158
	/* Samsung eDP panel */
1159
	{ OUI(0xba, 0x41, 0x59), DEVICE_ID_ANY, false, BIT(DP_DPCD_QUIRK_CUSTOMIZE_BRIGHTNESS_CONTROL) },
1158
};
1160
};
1159
1161
1160
#undef OUI
1162
#undef OUI
Lines 1168-1174 static const struct dpcd_quirk dpcd_quirk_list[] = { Link Here
1168
 * to device identification string and hardware/firmware revisions later.
1170
 * to device identification string and hardware/firmware revisions later.
1169
 */
1171
 */
1170
static u32
1172
static u32
1171
drm_dp_get_quirks(const struct drm_dp_dpcd_ident *ident, bool is_branch)
1173
drm_dp_get_quirks(const struct drm_dp_dpcd_ident *ident, bool is_branch, u8 *tcon_cap)
1172
{
1174
{
1173
	const struct dpcd_quirk *quirk;
1175
	const struct dpcd_quirk *quirk;
1174
	u32 quirks = 0;
1176
	u32 quirks = 0;
Lines 1188-1193 drm_dp_get_quirks(const struct drm_dp_dpcd_ident *ident, bool is_branch) Link Here
1188
		    memcmp(quirk->device_id, ident->device_id, sizeof(ident->device_id)) != 0)
1190
		    memcmp(quirk->device_id, ident->device_id, sizeof(ident->device_id)) != 0)
1189
			continue;
1191
			continue;
1190
1192
1193
		if (quirk->quirks == DP_DPCD_QUIRK_CUSTOMIZE_BRIGHTNESS_CONTROL &&
1194
		    (!(tcon_cap[1] & DP_BRIGHTNESS_CONTROL_NITS) ||
1195
		    !(tcon_cap[2] & DP_BRIGHTNESS_CONTROL_BY_AUX)))
1196
			continue;
1197
1191
		quirks |= quirk->quirks;
1198
		quirks |= quirk->quirks;
1192
	}
1199
	}
1193
1200
Lines 1214-1225 int drm_dp_read_desc(struct drm_dp_aux *aux, struct drm_dp_desc *desc, Link Here
1214
	struct drm_dp_dpcd_ident *ident = &desc->ident;
1221
	struct drm_dp_dpcd_ident *ident = &desc->ident;
1215
	unsigned int offset = is_branch ? DP_BRANCH_OUI : DP_SINK_OUI;
1222
	unsigned int offset = is_branch ? DP_BRANCH_OUI : DP_SINK_OUI;
1216
	int ret, dev_id_len;
1223
	int ret, dev_id_len;
1224
	u8 tcon_cap[4] = {0};
1217
1225
1218
	ret = drm_dp_dpcd_read(aux, offset, ident, sizeof(*ident));
1226
	ret = drm_dp_dpcd_read(aux, offset, ident, sizeof(*ident));
1219
	if (ret < 0)
1227
	if (ret < 0)
1220
		return ret;
1228
		return ret;
1221
1229
1222
	desc->quirks = drm_dp_get_quirks(ident, is_branch);
1230
	if (offset == DP_SINK_OUI) {
1231
		ret = drm_dp_dpcd_read(aux, DP_EDP_TCON_CAPABILITY_BYTE0, tcon_cap, sizeof(tcon_cap));
1232
		if (ret < 0)
1233
			return ret;
1234
	}
1235
1236
	desc->quirks = drm_dp_get_quirks(ident, is_branch, tcon_cap);
1223
1237
1224
	dev_id_len = strnlen(ident->device_id, sizeof(ident->device_id));
1238
	dev_id_len = strnlen(ident->device_id, sizeof(ident->device_id));
1225
1239
(-)a/drivers/gpu/drm/i915/display/intel_dp.c (+7 lines)
Lines 7306-7311 static bool intel_edp_init_connector(struct intel_dp *intel_dp, Link Here
7306
		goto out_vdd_off;
7306
		goto out_vdd_off;
7307
	}
7307
	}
7308
7308
7309
	if (drm_dp_has_quirk(&intel_dp->desc,
7310
		DP_DPCD_QUIRK_CUSTOMIZE_BRIGHTNESS_CONTROL)) {
7311
		i915_modparams.enable_dpcd_backlight = true;
7312
		i915_modparams.fastboot = false;
7313
		DRM_DEBUG_KMS("Using specific DPCD to control brightness\n");
7314
	}
7315
7309
	mutex_lock(&dev->mode_config.mutex);
7316
	mutex_lock(&dev->mode_config.mutex);
7310
	edid = drm_get_edid(connector, &intel_dp->aux.ddc);
7317
	edid = drm_get_edid(connector, &intel_dp->aux.ddc);
7311
	if (edid) {
7318
	if (edid) {
(-)a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c (-5 / +133 lines)
Lines 25-30 Link Here
25
#include "intel_display_types.h"
25
#include "intel_display_types.h"
26
#include "intel_dp_aux_backlight.h"
26
#include "intel_dp_aux_backlight.h"
27
27
28
#define EDP_CUSTOMIZE_MAX_BRIGHTNESS_LEVEL	(512)
29
30
static uint32_t intel_dp_aux_get_customize_backlight(struct intel_connector *connector)
31
{
32
	struct intel_dp *intel_dp = enc_to_intel_dp(&connector->encoder->base);
33
	uint8_t read_val[2] = { 0x0 };
34
35
	if (drm_dp_dpcd_read(&intel_dp->aux, DP_EDP_BRIGHTNESS_NITS,
36
			     &read_val, sizeof(read_val)) < 0) {
37
		DRM_DEBUG_KMS("Failed to read DPCD register %x\n",
38
			DP_EDP_BRIGHTNESS_NITS);
39
		return 0;
40
	}
41
42
	return (read_val[1] << 8 | read_val[0]);
43
}
44
45
static void
46
intel_dp_aux_set_customize_backlight(const struct drm_connector_state *conn_state, u32 level)
47
{
48
	struct intel_connector *connector = to_intel_connector(conn_state->connector);
49
	struct intel_dp *intel_dp = enc_to_intel_dp(&connector->encoder->base);
50
	struct intel_panel *panel = &connector->panel;
51
	uint8_t new_vals[4];
52
53
	if (level > panel->backlight.max)
54
		level = panel->backlight.max;
55
56
	new_vals[0] = level & 0xFF;
57
	new_vals[1] = (level & 0xFF00) >> 8;
58
	new_vals[2] = 0;
59
	new_vals[3] = 0;
60
61
	if (drm_dp_dpcd_write(&intel_dp->aux, DP_EDP_BRIGHTNESS_NITS, new_vals, 4) < 0)
62
		DRM_DEBUG_KMS("Failed to write aux backlight level\n");
63
}
64
65
static void intel_dp_aux_enable_customize_backlight(const struct intel_crtc_state *crtc_state,
66
					  const struct drm_connector_state *conn_state)
67
{
68
	struct intel_connector *connector = to_intel_connector(conn_state->connector);
69
	struct intel_dp *intel_dp = enc_to_intel_dp(&connector->encoder->base);
70
	uint8_t read_val[4], i;
71
	uint8_t write_val[8] = {0x00, 0x00, 0xF0, 0x01, 0x90, 0x01, 0x00, 0x00};
72
73
	if (drm_dp_dpcd_write(&intel_dp->aux, DP_EDP_PANEL_LUMINANCE_OVERRIDE, write_val, sizeof(write_val)) < 0)
74
		DRM_DEBUG_KMS("Failed to write panel luminance.\n");
75
76
	if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_EDP_BRIGHTNESS_OPTIMIZATION, 0x01) < 0)
77
		DRM_DEBUG_KMS("Failed to write %x\n",
78
			DP_EDP_BRIGHTNESS_OPTIMIZATION);
79
	/* write source OUI */
80
	write_val[0] = 0x00;
81
	write_val[1] = 0xaa;
82
	write_val[2] = 0x01;
83
	if (drm_dp_dpcd_write(&intel_dp->aux, DP_SOURCE_OUI, write_val, 3) < 0)
84
		DRM_DEBUG_KMS("Failed to write OUI\n");
85
86
	if (drm_dp_dpcd_readb(&intel_dp->aux, DP_EDP_GETSET_CTRL_PARAMS, read_val) != 1)
87
		DRM_DEBUG_KMS("Failed to read %x\n",
88
			DP_EDP_GETSET_CTRL_PARAMS);
89
90
	if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_EDP_GETSET_CTRL_PARAMS, 0) != 1)
91
		DRM_DEBUG_KMS("Failed to write %x\n",
92
			DP_EDP_GETSET_CTRL_PARAMS);
93
94
	if (drm_dp_dpcd_readb(&intel_dp->aux, DP_EDP_GETSET_CTRL_PARAMS, read_val) != 1)
95
		DRM_DEBUG_KMS("Failed to read %x\n",
96
			DP_EDP_GETSET_CTRL_PARAMS);
97
98
	if (drm_dp_dpcd_read(&intel_dp->aux, DP_EDP_CONTENT_LUMINANCE, &read_val, sizeof(read_val)) < 0)
99
		DRM_DEBUG_KMS("Failed to read %x\n",
100
			DP_EDP_CONTENT_LUMINANCE);
101
102
	memset(read_val, 0x0, 4);
103
	if (drm_dp_dpcd_write(&intel_dp->aux, DP_EDP_CONTENT_LUMINANCE, read_val, sizeof(read_val)) < 0)
104
		DRM_DEBUG_KMS("Failed to write %x\n",
105
			DP_EDP_CONTENT_LUMINANCE);
106
107
	if (drm_dp_dpcd_readb(&intel_dp->aux, DP_EDP_GETSET_CTRL_PARAMS, read_val) != 1)
108
		DRM_DEBUG_KMS("Failed to read %x\n",
109
			DP_EDP_GETSET_CTRL_PARAMS);
110
111
	if (drm_dp_dpcd_read(&intel_dp->aux, DP_SOURCE_OUI, read_val, 4) < 0)
112
		DRM_DEBUG_KMS("Failed to read OUI\n");
113
114
	DRM_DEBUG_KMS("got OUI %3ph\n", read_val);
115
116
	for (i = 0; i < 6; i++) {
117
		intel_dp_aux_set_customize_backlight(conn_state, connector->panel.backlight.level);
118
119
		msleep(60);
120
		if (intel_dp_aux_get_customize_backlight(connector))
121
			return;
122
	}
123
124
	DRM_DEBUG_KMS("Restore brightness may have problem.\n");
125
}
126
127
static void intel_dp_aux_disable_customize_backlight(const struct drm_connector_state *old_conn_state)
128
{
129
	// do nothing
130
	return;
131
}
132
28
static void set_aux_backlight_enable(struct intel_dp *intel_dp, bool enable)
133
static void set_aux_backlight_enable(struct intel_dp *intel_dp, bool enable)
29
{
134
{
30
	u8 reg_val = 0;
135
	u8 reg_val = 0;
Lines 198-203 static void intel_dp_aux_disable_backlight(const struct drm_connector_state *old Link Here
198
	set_aux_backlight_enable(enc_to_intel_dp(old_conn_state->best_encoder), false);
303
	set_aux_backlight_enable(enc_to_intel_dp(old_conn_state->best_encoder), false);
199
}
304
}
200
305
306
static int intel_dp_aux_setup_customize_backlight(struct intel_connector *connector,
307
					enum pipe pipe)
308
{
309
	struct intel_panel *panel = &connector->panel;
310
311
	panel->backlight.max = EDP_CUSTOMIZE_MAX_BRIGHTNESS_LEVEL;
312
	panel->backlight.min = 0;
313
	panel->backlight.level = panel->backlight.get(connector);
314
	panel->backlight.enabled = panel->backlight.level != 0;
315
316
	return 0;
317
}
318
201
static u32 intel_dp_aux_calc_max_backlight(struct intel_connector *connector)
319
static u32 intel_dp_aux_calc_max_backlight(struct intel_connector *connector)
202
{
320
{
203
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
321
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
Lines 310-315 int intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector) Link Here
310
{
428
{
311
	struct intel_panel *panel = &intel_connector->panel;
429
	struct intel_panel *panel = &intel_connector->panel;
312
	struct drm_i915_private *dev_priv = to_i915(intel_connector->base.dev);
430
	struct drm_i915_private *dev_priv = to_i915(intel_connector->base.dev);
431
	struct intel_dp *intel_dp = enc_to_intel_dp(&intel_connector->encoder->base);
313
432
314
	if (i915_modparams.enable_dpcd_backlight == 0 ||
433
	if (i915_modparams.enable_dpcd_backlight == 0 ||
315
	    (i915_modparams.enable_dpcd_backlight == -1 &&
434
	    (i915_modparams.enable_dpcd_backlight == -1 &&
Lines 319-329 int intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector) Link Here
319
	if (!intel_dp_aux_display_control_capable(intel_connector))
438
	if (!intel_dp_aux_display_control_capable(intel_connector))
320
		return -ENODEV;
439
		return -ENODEV;
321
440
322
	panel->backlight.setup = intel_dp_aux_setup_backlight;
441
	if (drm_dp_has_quirk(&intel_dp->desc,
323
	panel->backlight.enable = intel_dp_aux_enable_backlight;
442
	    DP_DPCD_QUIRK_CUSTOMIZE_BRIGHTNESS_CONTROL)) {
324
	panel->backlight.disable = intel_dp_aux_disable_backlight;
443
		panel->backlight.setup   = intel_dp_aux_setup_customize_backlight;
325
	panel->backlight.set = intel_dp_aux_set_backlight;
444
		panel->backlight.enable  = intel_dp_aux_enable_customize_backlight;
326
	panel->backlight.get = intel_dp_aux_get_backlight;
445
		panel->backlight.disable = intel_dp_aux_disable_customize_backlight;
446
		panel->backlight.set = intel_dp_aux_set_customize_backlight;
447
		panel->backlight.get = intel_dp_aux_get_customize_backlight;
448
	} else {
449
		panel->backlight.setup   = intel_dp_aux_setup_backlight;
450
		panel->backlight.enable  = intel_dp_aux_enable_backlight;
451
		panel->backlight.disable = intel_dp_aux_disable_backlight;
452
		panel->backlight.set = intel_dp_aux_set_backlight;
453
		panel->backlight.get = intel_dp_aux_get_backlight;
454
	}
327
455
328
	return 0;
456
	return 0;
329
}
457
}
(-)a/include/drm/drm_dp_helper.h (-1 / +20 lines)
Lines 749-754 Link Here
749
/* up to ID_SLOT_63 at 0x2ff */
749
/* up to ID_SLOT_63 at 0x2ff */
750
750
751
#define DP_SOURCE_OUI			    0x300
751
#define DP_SOURCE_OUI			    0x300
752
#define DP_EDP_TCON_CAPABILITY_BYTE0	    0x340
753
754
#define DP_EDP_TCON_CAPABILITY_BYTE1	    0x341
755
#define DP_BRIGHTNESS_CONTROL_NITS	    0x10
756
757
#define DP_EDP_TCON_CAPABILITY_BYTE2	    0x342
758
#define DP_BRIGHTNESS_CONTROL_BY_AUX	    0x01
759
760
#define DP_EDP_GETSET_CTRL_PARAMS	    0x344
761
#define DP_EDP_CONTENT_LUMINANCE	    0x346
762
#define DP_EDP_PANEL_LUMINANCE_OVERRIDE     0x34A
763
#define DP_EDP_BRIGHTNESS_NITS		    0x354
764
#define DP_EDP_BRIGHTNESS_OPTIMIZATION	    0x358
765
752
#define DP_SINK_OUI			    0x400
766
#define DP_SINK_OUI			    0x400
753
#define DP_BRANCH_OUI			    0x500
767
#define DP_BRANCH_OUI			    0x500
754
#define DP_BRANCH_ID                        0x503
768
#define DP_BRANCH_ID                        0x503
Lines 1520-1525 enum drm_dp_quirk { Link Here
1520
	 * The driver should ignore SINK_COUNT during detection.
1534
	 * The driver should ignore SINK_COUNT during detection.
1521
	 */
1535
	 */
1522
	DP_DPCD_QUIRK_NO_SINK_COUNT,
1536
	DP_DPCD_QUIRK_NO_SINK_COUNT,
1537
	/**
1538
	 * @DP_DPCD_QUIRK_NON_STANDARD_BRIGHTNESS_CONTROL:
1539
	 *
1540
	 * The device used specific DPCD register to control brightness.
1541
	 */
1542
	DP_DPCD_QUIRK_CUSTOMIZE_BRIGHTNESS_CONTROL,
1523
};
1543
};
1524
1544
1525
/**
1545
/**
1526
- 

Return to bug 205699