Skip to content

Commit 9a5c158

Browse files
committed
Merge remote-tracking branch 'msm/msm-fixes' into HEAD
2 parents 7f7a942 + e0e86f2 commit 9a5c158

File tree

17 files changed

+120
-31
lines changed

17 files changed

+120
-31
lines changed

drivers/gpu/drm/msm/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ config DRM_MSM_HDMI
155155
Compile in support for the HDMI output MSM DRM driver. It can
156156
be a primary or a secondary display on device. Note that this is used
157157
only for the direct HDMI output. If the device outputs HDMI data
158-
throught some kind of DSI-to-HDMI bridge, this option can be disabled.
158+
through some kind of DSI-to-HDMI bridge, this option can be disabled.
159159

160160
config DRM_MSM_HDMI_HDCP
161161
bool "Enable HDMI HDCP support in MSM DRM driver"

drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ struct a6xx_state_memobj {
9191
static void *state_kcalloc(struct a6xx_gpu_state *a6xx_state, int nr, size_t objsize)
9292
{
9393
struct a6xx_state_memobj *obj =
94-
kzalloc((nr * objsize) + sizeof(*obj), GFP_KERNEL);
94+
kvzalloc((nr * objsize) + sizeof(*obj), GFP_KERNEL);
9595

9696
if (!obj)
9797
return NULL;
@@ -813,6 +813,9 @@ static struct msm_gpu_state_bo *a6xx_snapshot_gmu_bo(
813813
{
814814
struct msm_gpu_state_bo *snapshot;
815815

816+
if (!bo->size)
817+
return NULL;
818+
816819
snapshot = state_kcalloc(a6xx_state, 1, sizeof(*snapshot));
817820
if (!snapshot)
818821
return NULL;
@@ -1040,8 +1043,13 @@ static void a6xx_gpu_state_destroy(struct kref *kref)
10401043
if (a6xx_state->gmu_hfi)
10411044
kvfree(a6xx_state->gmu_hfi->data);
10421045

1043-
list_for_each_entry_safe(obj, tmp, &a6xx_state->objs, node)
1044-
kfree(obj);
1046+
if (a6xx_state->gmu_debug)
1047+
kvfree(a6xx_state->gmu_debug->data);
1048+
1049+
list_for_each_entry_safe(obj, tmp, &a6xx_state->objs, node) {
1050+
list_del(&obj->node);
1051+
kvfree(obj);
1052+
}
10451053

10461054
adreno_gpu_state_destroy(state);
10471055
kfree(a6xx_state);

drivers/gpu/drm/msm/adreno/adreno_device.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,9 @@ static int adreno_system_suspend(struct device *dev)
679679
struct msm_gpu *gpu = dev_to_gpu(dev);
680680
int remaining, ret;
681681

682+
if (!gpu)
683+
return 0;
684+
682685
suspend_scheduler(gpu);
683686

684687
remaining = wait_event_timeout(gpu->retire_event,
@@ -700,7 +703,12 @@ static int adreno_system_suspend(struct device *dev)
700703

701704
static int adreno_system_resume(struct device *dev)
702705
{
703-
resume_scheduler(dev_to_gpu(dev));
706+
struct msm_gpu *gpu = dev_to_gpu(dev);
707+
708+
if (!gpu)
709+
return 0;
710+
711+
resume_scheduler(gpu);
704712
return pm_runtime_force_resume(dev);
705713
}
706714

drivers/gpu/drm/msm/adreno/adreno_gpu.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -729,7 +729,12 @@ static char *adreno_gpu_ascii85_encode(u32 *src, size_t len)
729729
return buf;
730730
}
731731

732-
/* len is expected to be in bytes */
732+
/* len is expected to be in bytes
733+
*
734+
* WARNING: *ptr should be allocated with kvmalloc or friends. It can be free'd
735+
* with kvfree() and replaced with a newly kvmalloc'd buffer on the first call
736+
* when the unencoded raw data is encoded
737+
*/
733738
void adreno_show_object(struct drm_printer *p, void **ptr, int len,
734739
bool *encoded)
735740
{

drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,9 @@ static int mdp4_lvds_connector_get_modes(struct drm_connector *connector)
5656
return ret;
5757
}
5858

59-
static int mdp4_lvds_connector_mode_valid(struct drm_connector *connector,
60-
struct drm_display_mode *mode)
59+
static enum drm_mode_status
60+
mdp4_lvds_connector_mode_valid(struct drm_connector *connector,
61+
struct drm_display_mode *mode)
6162
{
6263
struct mdp4_lvds_connector *mdp4_lvds_connector =
6364
to_mdp4_lvds_connector(connector);

drivers/gpu/drm/msm/dp/dp_ctrl.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,8 +1243,7 @@ static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl,
12431243
{
12441244
int ret = 0;
12451245
const u8 *dpcd = ctrl->panel->dpcd;
1246-
u8 encoding = DP_SET_ANSI_8B10B;
1247-
u8 ssc;
1246+
u8 encoding[] = { 0, DP_SET_ANSI_8B10B };
12481247
u8 assr;
12491248
struct dp_link_info link_info = {0};
12501249

@@ -1256,13 +1255,11 @@ static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl,
12561255

12571256
dp_aux_link_configure(ctrl->aux, &link_info);
12581257

1259-
if (drm_dp_max_downspread(dpcd)) {
1260-
ssc = DP_SPREAD_AMP_0_5;
1261-
drm_dp_dpcd_write(ctrl->aux, DP_DOWNSPREAD_CTRL, &ssc, 1);
1262-
}
1258+
if (drm_dp_max_downspread(dpcd))
1259+
encoding[0] |= DP_SPREAD_AMP_0_5;
12631260

1264-
drm_dp_dpcd_write(ctrl->aux, DP_MAIN_LINK_CHANNEL_CODING_SET,
1265-
&encoding, 1);
1261+
/* config DOWNSPREAD_CTRL and MAIN_LINK_CHANNEL_CODING_SET */
1262+
drm_dp_dpcd_write(ctrl->aux, DP_DOWNSPREAD_CTRL, encoding, 2);
12661263

12671264
if (drm_dp_alternate_scrambler_reset_cap(dpcd)) {
12681265
assr = DP_ALTERNATE_SCRAMBLER_RESET_ENABLE;

drivers/gpu/drm/msm/dp/dp_display.c

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1249,7 +1249,7 @@ int dp_display_request_irq(struct msm_dp *dp_display)
12491249
return -EINVAL;
12501250
}
12511251

1252-
rc = devm_request_irq(&dp->pdev->dev, dp->irq,
1252+
rc = devm_request_irq(dp_display->drm_dev->dev, dp->irq,
12531253
dp_display_irq_handler,
12541254
IRQF_TRIGGER_HIGH, "dp_display_isr", dp);
12551255
if (rc < 0) {
@@ -1528,6 +1528,11 @@ void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor)
15281528
}
15291529
}
15301530

1531+
static void of_dp_aux_depopulate_bus_void(void *data)
1532+
{
1533+
of_dp_aux_depopulate_bus(data);
1534+
}
1535+
15311536
static int dp_display_get_next_bridge(struct msm_dp *dp)
15321537
{
15331538
int rc;
@@ -1552,10 +1557,16 @@ static int dp_display_get_next_bridge(struct msm_dp *dp)
15521557
* panel driver is probed asynchronously but is the best we
15531558
* can do without a bigger driver reorganization.
15541559
*/
1555-
rc = devm_of_dp_aux_populate_ep_devices(dp_priv->aux);
1560+
rc = of_dp_aux_populate_bus(dp_priv->aux, NULL);
15561561
of_node_put(aux_bus);
15571562
if (rc)
15581563
goto error;
1564+
1565+
rc = devm_add_action_or_reset(dp->drm_dev->dev,
1566+
of_dp_aux_depopulate_bus_void,
1567+
dp_priv->aux);
1568+
if (rc)
1569+
goto error;
15591570
} else if (dp->is_edp) {
15601571
DRM_ERROR("eDP aux_bus not found\n");
15611572
return -ENODEV;
@@ -1568,7 +1579,7 @@ static int dp_display_get_next_bridge(struct msm_dp *dp)
15681579
* For DisplayPort interfaces external bridges are optional, so
15691580
* silently ignore an error if one is not present (-ENODEV).
15701581
*/
1571-
rc = dp_parser_find_next_bridge(dp_priv->parser);
1582+
rc = devm_dp_parser_find_next_bridge(dp->drm_dev->dev, dp_priv->parser);
15721583
if (!dp->is_edp && rc == -ENODEV)
15731584
return 0;
15741585

@@ -1597,6 +1608,12 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
15971608
return -EINVAL;
15981609

15991610
priv = dev->dev_private;
1611+
1612+
if (priv->num_bridges == ARRAY_SIZE(priv->bridges)) {
1613+
DRM_DEV_ERROR(dev->dev, "too many bridges\n");
1614+
return -ENOSPC;
1615+
}
1616+
16001617
dp_display->drm_dev = dev;
16011618

16021619
dp_priv = container_of(dp_display, struct dp_display_private, dp_display);

drivers/gpu/drm/msm/dp/dp_drm.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,36 @@ static enum drm_connector_status dp_bridge_detect(struct drm_bridge *bridge)
3131
connector_status_disconnected;
3232
}
3333

34+
static int dp_bridge_atomic_check(struct drm_bridge *bridge,
35+
struct drm_bridge_state *bridge_state,
36+
struct drm_crtc_state *crtc_state,
37+
struct drm_connector_state *conn_state)
38+
{
39+
struct msm_dp *dp;
40+
41+
dp = to_dp_bridge(bridge)->dp_display;
42+
43+
drm_dbg_dp(dp->drm_dev, "is_connected = %s\n",
44+
(dp->is_connected) ? "true" : "false");
45+
46+
/*
47+
* There is no protection in the DRM framework to check if the display
48+
* pipeline has been already disabled before trying to disable it again.
49+
* Hence if the sink is unplugged, the pipeline gets disabled, but the
50+
* crtc->active is still true. Any attempt to set the mode or manually
51+
* disable this encoder will result in the crash.
52+
*
53+
* TODO: add support for telling the DRM subsystem that the pipeline is
54+
* disabled by the hardware and thus all access to it should be forbidden.
55+
* After that this piece of code can be removed.
56+
*/
57+
if (bridge->ops & DRM_BRIDGE_OP_HPD)
58+
return (dp->is_connected) ? 0 : -ENOTCONN;
59+
60+
return 0;
61+
}
62+
63+
3464
/**
3565
* dp_bridge_get_modes - callback to add drm modes via drm_mode_probed_add()
3666
* @bridge: Poiner to drm bridge
@@ -61,13 +91,17 @@ static int dp_bridge_get_modes(struct drm_bridge *bridge, struct drm_connector *
6191
}
6292

6393
static const struct drm_bridge_funcs dp_bridge_ops = {
94+
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
95+
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
96+
.atomic_reset = drm_atomic_helper_bridge_reset,
6497
.enable = dp_bridge_enable,
6598
.disable = dp_bridge_disable,
6699
.post_disable = dp_bridge_post_disable,
67100
.mode_set = dp_bridge_mode_set,
68101
.mode_valid = dp_bridge_mode_valid,
69102
.get_modes = dp_bridge_get_modes,
70103
.detect = dp_bridge_detect,
104+
.atomic_check = dp_bridge_atomic_check,
71105
};
72106

73107
struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev,

drivers/gpu/drm/msm/dp/dp_parser.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -240,12 +240,12 @@ static int dp_parser_clock(struct dp_parser *parser)
240240
return 0;
241241
}
242242

243-
int dp_parser_find_next_bridge(struct dp_parser *parser)
243+
int devm_dp_parser_find_next_bridge(struct device *dev, struct dp_parser *parser)
244244
{
245-
struct device *dev = &parser->pdev->dev;
245+
struct platform_device *pdev = parser->pdev;
246246
struct drm_bridge *bridge;
247247

248-
bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
248+
bridge = devm_drm_of_get_bridge(dev, pdev->dev.of_node, 1, 0);
249249
if (IS_ERR(bridge))
250250
return PTR_ERR(bridge);
251251

drivers/gpu/drm/msm/dp/dp_parser.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,15 +138,16 @@ struct dp_parser {
138138
struct dp_parser *dp_parser_get(struct platform_device *pdev);
139139

140140
/**
141-
* dp_parser_find_next_bridge() - find an additional bridge to DP
141+
* devm_dp_parser_find_next_bridge() - find an additional bridge to DP
142142
*
143+
* @dev: device to tie bridge lifetime to
143144
* @parser: dp_parser data from client
144145
*
145146
* This function is used to find any additional bridge attached to
146147
* the DP controller. The eDP interface requires a panel bridge.
147148
*
148149
* Return: 0 if able to get the bridge, otherwise negative errno for failure.
149150
*/
150-
int dp_parser_find_next_bridge(struct dp_parser *parser);
151+
int devm_dp_parser_find_next_bridge(struct device *dev, struct dp_parser *parser);
151152

152153
#endif

0 commit comments

Comments
 (0)