diff options
author | Dave Airlie <airlied@redhat.com> | 2015-03-04 18:37:19 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2015-03-04 18:37:19 -0500 |
commit | 79d6d9426ba499fdb07334720364b44909b8a06c (patch) | |
tree | 53676790819340f73360047b22d6ae55b525aeec | |
parent | 329414c4e7b7506fe3eab545b3fc9e44b7f28a10 (diff) | |
parent | 07259f8b9fbd30fcef595e872deeea5ffab934ed (diff) |
Merge branch 'drm-tda998x-devel' of git://ftp.arm.linux.org.uk/~rmk/linux-arm into drm-next
A number of TDA998x updates for the next merge window. Patches
included in this set are:
* adding support for finding the attached CRTCs from DT
* a fix function name mis-spelling in a dev_err()
* simplify the EDID reading by using the drm_do_get_edid() function
instead of coding this ourselves.
* 'drm-tda998x-devel' of git://ftp.arm.linux.org.uk/~rmk/linux-arm:
drm/i2c: tda998x: use drm_do_get_edid()
drm/i2c: tda998x: fix misspelling of current function in string
drm/i2c: tda998x: add OF support for finding attached CRTCs
-rw-r--r-- | drivers/gpu/drm/i2c/tda998x_drv.c | 101 |
1 files changed, 31 insertions, 70 deletions
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index a9041d1a8ff0..5febffdb027d 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <drm/drm_crtc_helper.h> | 25 | #include <drm/drm_crtc_helper.h> |
26 | #include <drm/drm_encoder_slave.h> | 26 | #include <drm/drm_encoder_slave.h> |
27 | #include <drm/drm_edid.h> | 27 | #include <drm/drm_edid.h> |
28 | #include <drm/drm_of.h> | ||
28 | #include <drm/i2c/tda998x.h> | 29 | #include <drm/i2c/tda998x.h> |
29 | 30 | ||
30 | #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) | 31 | #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) |
@@ -387,7 +388,7 @@ set_page(struct tda998x_priv *priv, uint16_t reg) | |||
387 | }; | 388 | }; |
388 | int ret = i2c_master_send(client, buf, sizeof(buf)); | 389 | int ret = i2c_master_send(client, buf, sizeof(buf)); |
389 | if (ret < 0) { | 390 | if (ret < 0) { |
390 | dev_err(&client->dev, "setpage %04x err %d\n", | 391 | dev_err(&client->dev, "%s %04x err %d\n", __func__, |
391 | reg, ret); | 392 | reg, ret); |
392 | return ret; | 393 | return ret; |
393 | } | 394 | } |
@@ -1035,8 +1036,9 @@ tda998x_encoder_detect(struct tda998x_priv *priv) | |||
1035 | connector_status_disconnected; | 1036 | connector_status_disconnected; |
1036 | } | 1037 | } |
1037 | 1038 | ||
1038 | static int read_edid_block(struct tda998x_priv *priv, uint8_t *buf, int blk) | 1039 | static int read_edid_block(void *data, u8 *buf, unsigned int blk, size_t length) |
1039 | { | 1040 | { |
1041 | struct tda998x_priv *priv = data; | ||
1040 | uint8_t offset, segptr; | 1042 | uint8_t offset, segptr; |
1041 | int ret, i; | 1043 | int ret, i; |
1042 | 1044 | ||
@@ -1080,8 +1082,8 @@ static int read_edid_block(struct tda998x_priv *priv, uint8_t *buf, int blk) | |||
1080 | return -ETIMEDOUT; | 1082 | return -ETIMEDOUT; |
1081 | } | 1083 | } |
1082 | 1084 | ||
1083 | ret = reg_read_range(priv, REG_EDID_DATA_0, buf, EDID_LENGTH); | 1085 | ret = reg_read_range(priv, REG_EDID_DATA_0, buf, length); |
1084 | if (ret != EDID_LENGTH) { | 1086 | if (ret != length) { |
1085 | dev_err(&priv->hdmi->dev, "failed to read edid block %d: %d\n", | 1087 | dev_err(&priv->hdmi->dev, "failed to read edid block %d: %d\n", |
1086 | blk, ret); | 1088 | blk, ret); |
1087 | return ret; | 1089 | return ret; |
@@ -1090,82 +1092,31 @@ static int read_edid_block(struct tda998x_priv *priv, uint8_t *buf, int blk) | |||
1090 | return 0; | 1092 | return 0; |
1091 | } | 1093 | } |
1092 | 1094 | ||
1093 | static uint8_t *do_get_edid(struct tda998x_priv *priv) | 1095 | static int |
1096 | tda998x_encoder_get_modes(struct tda998x_priv *priv, | ||
1097 | struct drm_connector *connector) | ||
1094 | { | 1098 | { |
1095 | int j, valid_extensions = 0; | 1099 | struct edid *edid; |
1096 | uint8_t *block, *new; | 1100 | int n; |
1097 | bool print_bad_edid = drm_debug & DRM_UT_KMS; | ||
1098 | |||
1099 | if ((block = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL) | ||
1100 | return NULL; | ||
1101 | 1101 | ||
1102 | if (priv->rev == TDA19988) | 1102 | if (priv->rev == TDA19988) |
1103 | reg_clear(priv, REG_TX4, TX4_PD_RAM); | 1103 | reg_clear(priv, REG_TX4, TX4_PD_RAM); |
1104 | 1104 | ||
1105 | /* base block fetch */ | 1105 | edid = drm_do_get_edid(connector, read_edid_block, priv); |
1106 | if (read_edid_block(priv, block, 0)) | ||
1107 | goto fail; | ||
1108 | |||
1109 | if (!drm_edid_block_valid(block, 0, print_bad_edid)) | ||
1110 | goto fail; | ||
1111 | |||
1112 | /* if there's no extensions, we're done */ | ||
1113 | if (block[0x7e] == 0) | ||
1114 | goto done; | ||
1115 | |||
1116 | new = krealloc(block, (block[0x7e] + 1) * EDID_LENGTH, GFP_KERNEL); | ||
1117 | if (!new) | ||
1118 | goto fail; | ||
1119 | block = new; | ||
1120 | |||
1121 | for (j = 1; j <= block[0x7e]; j++) { | ||
1122 | uint8_t *ext_block = block + (valid_extensions + 1) * EDID_LENGTH; | ||
1123 | if (read_edid_block(priv, ext_block, j)) | ||
1124 | goto fail; | ||
1125 | |||
1126 | if (!drm_edid_block_valid(ext_block, j, print_bad_edid)) | ||
1127 | goto fail; | ||
1128 | |||
1129 | valid_extensions++; | ||
1130 | } | ||
1131 | |||
1132 | if (valid_extensions != block[0x7e]) { | ||
1133 | block[EDID_LENGTH-1] += block[0x7e] - valid_extensions; | ||
1134 | block[0x7e] = valid_extensions; | ||
1135 | new = krealloc(block, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL); | ||
1136 | if (!new) | ||
1137 | goto fail; | ||
1138 | block = new; | ||
1139 | } | ||
1140 | 1106 | ||
1141 | done: | ||
1142 | if (priv->rev == TDA19988) | 1107 | if (priv->rev == TDA19988) |
1143 | reg_set(priv, REG_TX4, TX4_PD_RAM); | 1108 | reg_set(priv, REG_TX4, TX4_PD_RAM); |
1144 | 1109 | ||
1145 | return block; | 1110 | if (!edid) { |
1146 | 1111 | dev_warn(&priv->hdmi->dev, "failed to read EDID\n"); | |
1147 | fail: | 1112 | return 0; |
1148 | if (priv->rev == TDA19988) | ||
1149 | reg_set(priv, REG_TX4, TX4_PD_RAM); | ||
1150 | dev_warn(&priv->hdmi->dev, "failed to read EDID\n"); | ||
1151 | kfree(block); | ||
1152 | return NULL; | ||
1153 | } | ||
1154 | |||
1155 | static int | ||
1156 | tda998x_encoder_get_modes(struct tda998x_priv *priv, | ||
1157 | struct drm_connector *connector) | ||
1158 | { | ||
1159 | struct edid *edid = (struct edid *)do_get_edid(priv); | ||
1160 | int n = 0; | ||
1161 | |||
1162 | if (edid) { | ||
1163 | drm_mode_connector_update_edid_property(connector, edid); | ||
1164 | n = drm_add_edid_modes(connector, edid); | ||
1165 | priv->is_hdmi_sink = drm_detect_hdmi_monitor(edid); | ||
1166 | kfree(edid); | ||
1167 | } | 1113 | } |
1168 | 1114 | ||
1115 | drm_mode_connector_update_edid_property(connector, edid); | ||
1116 | n = drm_add_edid_modes(connector, edid); | ||
1117 | priv->is_hdmi_sink = drm_detect_hdmi_monitor(edid); | ||
1118 | kfree(edid); | ||
1119 | |||
1169 | return n; | 1120 | return n; |
1170 | } | 1121 | } |
1171 | 1122 | ||
@@ -1547,6 +1498,7 @@ static int tda998x_bind(struct device *dev, struct device *master, void *data) | |||
1547 | struct i2c_client *client = to_i2c_client(dev); | 1498 | struct i2c_client *client = to_i2c_client(dev); |
1548 | struct drm_device *drm = data; | 1499 | struct drm_device *drm = data; |
1549 | struct tda998x_priv2 *priv; | 1500 | struct tda998x_priv2 *priv; |
1501 | uint32_t crtcs = 0; | ||
1550 | int ret; | 1502 | int ret; |
1551 | 1503 | ||
1552 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | 1504 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); |
@@ -1555,9 +1507,18 @@ static int tda998x_bind(struct device *dev, struct device *master, void *data) | |||
1555 | 1507 | ||
1556 | dev_set_drvdata(dev, priv); | 1508 | dev_set_drvdata(dev, priv); |
1557 | 1509 | ||
1510 | if (dev->of_node) | ||
1511 | crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); | ||
1512 | |||
1513 | /* If no CRTCs were found, fall back to our old behaviour */ | ||
1514 | if (crtcs == 0) { | ||
1515 | dev_warn(dev, "Falling back to first CRTC\n"); | ||
1516 | crtcs = 1 << 0; | ||
1517 | } | ||
1518 | |||
1558 | priv->base.encoder = &priv->encoder; | 1519 | priv->base.encoder = &priv->encoder; |
1559 | priv->connector.interlace_allowed = 1; | 1520 | priv->connector.interlace_allowed = 1; |
1560 | priv->encoder.possible_crtcs = 1 << 0; | 1521 | priv->encoder.possible_crtcs = crtcs; |
1561 | 1522 | ||
1562 | ret = tda998x_create(client, &priv->base); | 1523 | ret = tda998x_create(client, &priv->base); |
1563 | if (ret) | 1524 | if (ret) |