Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Driver for MegaChips STDP4028 with GE B850v3 firmware (LVDS-DP)
0004  * Driver for MegaChips STDP2690 with GE B850v3 firmware (DP-DP++)
0005 
0006  * Copyright (c) 2017, Collabora Ltd.
0007  * Copyright (c) 2017, General Electric Company
0008 
0009 
0010  * This driver creates a drm_bridge and a drm_connector for the LVDS to DP++
0011  * display bridge of the GE B850v3. There are two physical bridges on the video
0012  * signal pipeline: a STDP4028(LVDS to DP) and a STDP2690(DP to DP++). The
0013  * physical bridges are automatically configured by the input video signal, and
0014  * the driver has no access to the video processing pipeline. The driver is
0015  * only needed to read EDID from the STDP2690 and to handle HPD events from the
0016  * STDP4028. The driver communicates with both bridges over i2c. The video
0017  * signal pipeline is as follows:
0018  *
0019  *   Host -> LVDS|--(STDP4028)--|DP -> DP|--(STDP2690)--|DP++ -> Video output
0020  */
0021 
0022 #include <linux/i2c.h>
0023 #include <linux/module.h>
0024 #include <linux/of.h>
0025 
0026 #include <drm/drm_atomic.h>
0027 #include <drm/drm_atomic_helper.h>
0028 #include <drm/drm_bridge.h>
0029 #include <drm/drm_edid.h>
0030 #include <drm/drm_print.h>
0031 #include <drm/drm_probe_helper.h>
0032 
0033 #define EDID_EXT_BLOCK_CNT 0x7E
0034 
0035 #define STDP4028_IRQ_OUT_CONF_REG 0x02
0036 #define STDP4028_DPTX_IRQ_EN_REG 0x3C
0037 #define STDP4028_DPTX_IRQ_STS_REG 0x3D
0038 #define STDP4028_DPTX_STS_REG 0x3E
0039 
0040 #define STDP4028_DPTX_DP_IRQ_EN 0x1000
0041 
0042 #define STDP4028_DPTX_HOTPLUG_IRQ_EN 0x0400
0043 #define STDP4028_DPTX_LINK_CH_IRQ_EN 0x2000
0044 #define STDP4028_DPTX_IRQ_CONFIG \
0045         (STDP4028_DPTX_LINK_CH_IRQ_EN | STDP4028_DPTX_HOTPLUG_IRQ_EN)
0046 
0047 #define STDP4028_DPTX_HOTPLUG_STS 0x0200
0048 #define STDP4028_DPTX_LINK_STS 0x1000
0049 #define STDP4028_CON_STATE_CONNECTED \
0050         (STDP4028_DPTX_HOTPLUG_STS | STDP4028_DPTX_LINK_STS)
0051 
0052 #define STDP4028_DPTX_HOTPLUG_CH_STS 0x0400
0053 #define STDP4028_DPTX_LINK_CH_STS 0x2000
0054 #define STDP4028_DPTX_IRQ_CLEAR \
0055         (STDP4028_DPTX_LINK_CH_STS | STDP4028_DPTX_HOTPLUG_CH_STS)
0056 
0057 static DEFINE_MUTEX(ge_b850v3_lvds_dev_mutex);
0058 
0059 struct ge_b850v3_lvds {
0060     struct drm_connector connector;
0061     struct drm_bridge bridge;
0062     struct i2c_client *stdp4028_i2c;
0063     struct i2c_client *stdp2690_i2c;
0064 };
0065 
0066 static struct ge_b850v3_lvds *ge_b850v3_lvds_ptr;
0067 
0068 static u8 *stdp2690_get_edid(struct i2c_client *client)
0069 {
0070     struct i2c_adapter *adapter = client->adapter;
0071     unsigned char start = 0x00;
0072     unsigned int total_size;
0073     u8 *block = kmalloc(EDID_LENGTH, GFP_KERNEL);
0074 
0075     struct i2c_msg msgs[] = {
0076         {
0077             .addr   = client->addr,
0078             .flags  = 0,
0079             .len    = 1,
0080             .buf    = &start,
0081         }, {
0082             .addr   = client->addr,
0083             .flags  = I2C_M_RD,
0084             .len    = EDID_LENGTH,
0085             .buf    = block,
0086         }
0087     };
0088 
0089     if (!block)
0090         return NULL;
0091 
0092     if (i2c_transfer(adapter, msgs, 2) != 2) {
0093         DRM_ERROR("Unable to read EDID.\n");
0094         goto err;
0095     }
0096 
0097     if (!drm_edid_block_valid(block, 0, false, NULL)) {
0098         DRM_ERROR("Invalid EDID data\n");
0099         goto err;
0100     }
0101 
0102     total_size = (block[EDID_EXT_BLOCK_CNT] + 1) * EDID_LENGTH;
0103     if (total_size > EDID_LENGTH) {
0104         kfree(block);
0105         block = kmalloc(total_size, GFP_KERNEL);
0106         if (!block)
0107             return NULL;
0108 
0109         /* Yes, read the entire buffer, and do not skip the first
0110          * EDID_LENGTH bytes.
0111          */
0112         start = 0x00;
0113         msgs[1].len = total_size;
0114         msgs[1].buf = block;
0115 
0116         if (i2c_transfer(adapter, msgs, 2) != 2) {
0117             DRM_ERROR("Unable to read EDID extension blocks.\n");
0118             goto err;
0119         }
0120         if (!drm_edid_block_valid(block, 1, false, NULL)) {
0121             DRM_ERROR("Invalid EDID data\n");
0122             goto err;
0123         }
0124     }
0125 
0126     return block;
0127 
0128 err:
0129     kfree(block);
0130     return NULL;
0131 }
0132 
0133 static struct edid *ge_b850v3_lvds_get_edid(struct drm_bridge *bridge,
0134                         struct drm_connector *connector)
0135 {
0136     struct i2c_client *client;
0137 
0138     client = ge_b850v3_lvds_ptr->stdp2690_i2c;
0139 
0140     return (struct edid *)stdp2690_get_edid(client);
0141 }
0142 
0143 static int ge_b850v3_lvds_get_modes(struct drm_connector *connector)
0144 {
0145     struct edid *edid;
0146     int num_modes;
0147 
0148     edid = ge_b850v3_lvds_get_edid(&ge_b850v3_lvds_ptr->bridge, connector);
0149 
0150     drm_connector_update_edid_property(connector, edid);
0151     num_modes = drm_add_edid_modes(connector, edid);
0152     kfree(edid);
0153 
0154     return num_modes;
0155 }
0156 
0157 static enum drm_mode_status ge_b850v3_lvds_mode_valid(
0158         struct drm_connector *connector, struct drm_display_mode *mode)
0159 {
0160     return MODE_OK;
0161 }
0162 
0163 static const struct
0164 drm_connector_helper_funcs ge_b850v3_lvds_connector_helper_funcs = {
0165     .get_modes = ge_b850v3_lvds_get_modes,
0166     .mode_valid = ge_b850v3_lvds_mode_valid,
0167 };
0168 
0169 static enum drm_connector_status ge_b850v3_lvds_bridge_detect(struct drm_bridge *bridge)
0170 {
0171     struct i2c_client *stdp4028_i2c =
0172             ge_b850v3_lvds_ptr->stdp4028_i2c;
0173     s32 link_state;
0174 
0175     link_state = i2c_smbus_read_word_data(stdp4028_i2c,
0176                           STDP4028_DPTX_STS_REG);
0177 
0178     if (link_state == STDP4028_CON_STATE_CONNECTED)
0179         return connector_status_connected;
0180 
0181     if (link_state == 0)
0182         return connector_status_disconnected;
0183 
0184     return connector_status_unknown;
0185 }
0186 
0187 static enum drm_connector_status ge_b850v3_lvds_detect(struct drm_connector *connector,
0188                                bool force)
0189 {
0190     return ge_b850v3_lvds_bridge_detect(&ge_b850v3_lvds_ptr->bridge);
0191 }
0192 
0193 static const struct drm_connector_funcs ge_b850v3_lvds_connector_funcs = {
0194     .fill_modes = drm_helper_probe_single_connector_modes,
0195     .detect = ge_b850v3_lvds_detect,
0196     .destroy = drm_connector_cleanup,
0197     .reset = drm_atomic_helper_connector_reset,
0198     .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
0199     .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
0200 };
0201 
0202 static int ge_b850v3_lvds_create_connector(struct drm_bridge *bridge)
0203 {
0204     struct drm_connector *connector = &ge_b850v3_lvds_ptr->connector;
0205     int ret;
0206 
0207     if (!bridge->encoder) {
0208         DRM_ERROR("Parent encoder object not found");
0209         return -ENODEV;
0210     }
0211 
0212     connector->polled = DRM_CONNECTOR_POLL_HPD;
0213 
0214     drm_connector_helper_add(connector,
0215                  &ge_b850v3_lvds_connector_helper_funcs);
0216 
0217     ret = drm_connector_init(bridge->dev, connector,
0218                  &ge_b850v3_lvds_connector_funcs,
0219                  DRM_MODE_CONNECTOR_DisplayPort);
0220     if (ret) {
0221         DRM_ERROR("Failed to initialize connector with drm\n");
0222         return ret;
0223     }
0224 
0225     return drm_connector_attach_encoder(connector, bridge->encoder);
0226 }
0227 
0228 static irqreturn_t ge_b850v3_lvds_irq_handler(int irq, void *dev_id)
0229 {
0230     struct i2c_client *stdp4028_i2c
0231             = ge_b850v3_lvds_ptr->stdp4028_i2c;
0232 
0233     i2c_smbus_write_word_data(stdp4028_i2c,
0234                   STDP4028_DPTX_IRQ_STS_REG,
0235                   STDP4028_DPTX_IRQ_CLEAR);
0236 
0237     if (ge_b850v3_lvds_ptr->bridge.dev)
0238         drm_kms_helper_hotplug_event(ge_b850v3_lvds_ptr->bridge.dev);
0239 
0240     return IRQ_HANDLED;
0241 }
0242 
0243 static int ge_b850v3_lvds_attach(struct drm_bridge *bridge,
0244                  enum drm_bridge_attach_flags flags)
0245 {
0246     struct i2c_client *stdp4028_i2c
0247             = ge_b850v3_lvds_ptr->stdp4028_i2c;
0248 
0249     /* Configures the bridge to re-enable interrupts after each ack. */
0250     i2c_smbus_write_word_data(stdp4028_i2c,
0251                   STDP4028_IRQ_OUT_CONF_REG,
0252                   STDP4028_DPTX_DP_IRQ_EN);
0253 
0254     /* Enable interrupts */
0255     i2c_smbus_write_word_data(stdp4028_i2c,
0256                   STDP4028_DPTX_IRQ_EN_REG,
0257                   STDP4028_DPTX_IRQ_CONFIG);
0258 
0259     if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
0260         return 0;
0261 
0262     return ge_b850v3_lvds_create_connector(bridge);
0263 }
0264 
0265 static const struct drm_bridge_funcs ge_b850v3_lvds_funcs = {
0266     .attach = ge_b850v3_lvds_attach,
0267     .detect = ge_b850v3_lvds_bridge_detect,
0268     .get_edid = ge_b850v3_lvds_get_edid,
0269 };
0270 
0271 static int ge_b850v3_lvds_init(struct device *dev)
0272 {
0273     mutex_lock(&ge_b850v3_lvds_dev_mutex);
0274 
0275     if (ge_b850v3_lvds_ptr)
0276         goto success;
0277 
0278     ge_b850v3_lvds_ptr = devm_kzalloc(dev,
0279                       sizeof(*ge_b850v3_lvds_ptr),
0280                       GFP_KERNEL);
0281 
0282     if (!ge_b850v3_lvds_ptr) {
0283         mutex_unlock(&ge_b850v3_lvds_dev_mutex);
0284         return -ENOMEM;
0285     }
0286 
0287 success:
0288     mutex_unlock(&ge_b850v3_lvds_dev_mutex);
0289     return 0;
0290 }
0291 
0292 static void ge_b850v3_lvds_remove(void)
0293 {
0294     mutex_lock(&ge_b850v3_lvds_dev_mutex);
0295     /*
0296      * This check is to avoid both the drivers
0297      * removing the bridge in their remove() function
0298      */
0299     if (!ge_b850v3_lvds_ptr)
0300         goto out;
0301 
0302     drm_bridge_remove(&ge_b850v3_lvds_ptr->bridge);
0303 
0304     ge_b850v3_lvds_ptr = NULL;
0305 out:
0306     mutex_unlock(&ge_b850v3_lvds_dev_mutex);
0307 }
0308 
0309 static int ge_b850v3_register(void)
0310 {
0311     struct i2c_client *stdp4028_i2c = ge_b850v3_lvds_ptr->stdp4028_i2c;
0312     struct device *dev = &stdp4028_i2c->dev;
0313 
0314     /* drm bridge initialization */
0315     ge_b850v3_lvds_ptr->bridge.funcs = &ge_b850v3_lvds_funcs;
0316     ge_b850v3_lvds_ptr->bridge.ops = DRM_BRIDGE_OP_DETECT |
0317                      DRM_BRIDGE_OP_EDID;
0318     ge_b850v3_lvds_ptr->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
0319     ge_b850v3_lvds_ptr->bridge.of_node = dev->of_node;
0320     drm_bridge_add(&ge_b850v3_lvds_ptr->bridge);
0321 
0322     /* Clear pending interrupts since power up. */
0323     i2c_smbus_write_word_data(stdp4028_i2c,
0324                   STDP4028_DPTX_IRQ_STS_REG,
0325                   STDP4028_DPTX_IRQ_CLEAR);
0326 
0327     if (!stdp4028_i2c->irq)
0328         return 0;
0329 
0330     return devm_request_threaded_irq(&stdp4028_i2c->dev,
0331             stdp4028_i2c->irq, NULL,
0332             ge_b850v3_lvds_irq_handler,
0333             IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
0334             "ge-b850v3-lvds-dp", ge_b850v3_lvds_ptr);
0335 }
0336 
0337 static int stdp4028_ge_b850v3_fw_probe(struct i2c_client *stdp4028_i2c,
0338                        const struct i2c_device_id *id)
0339 {
0340     struct device *dev = &stdp4028_i2c->dev;
0341     int ret;
0342 
0343     ret = ge_b850v3_lvds_init(dev);
0344 
0345     if (ret)
0346         return ret;
0347 
0348     ge_b850v3_lvds_ptr->stdp4028_i2c = stdp4028_i2c;
0349     i2c_set_clientdata(stdp4028_i2c, ge_b850v3_lvds_ptr);
0350 
0351     /* Only register after both bridges are probed */
0352     if (!ge_b850v3_lvds_ptr->stdp2690_i2c)
0353         return 0;
0354 
0355     return ge_b850v3_register();
0356 }
0357 
0358 static int stdp4028_ge_b850v3_fw_remove(struct i2c_client *stdp4028_i2c)
0359 {
0360     ge_b850v3_lvds_remove();
0361 
0362     return 0;
0363 }
0364 
0365 static const struct i2c_device_id stdp4028_ge_b850v3_fw_i2c_table[] = {
0366     {"stdp4028_ge_fw", 0},
0367     {},
0368 };
0369 MODULE_DEVICE_TABLE(i2c, stdp4028_ge_b850v3_fw_i2c_table);
0370 
0371 static const struct of_device_id stdp4028_ge_b850v3_fw_match[] = {
0372     { .compatible = "megachips,stdp4028-ge-b850v3-fw" },
0373     {},
0374 };
0375 MODULE_DEVICE_TABLE(of, stdp4028_ge_b850v3_fw_match);
0376 
0377 static struct i2c_driver stdp4028_ge_b850v3_fw_driver = {
0378     .id_table   = stdp4028_ge_b850v3_fw_i2c_table,
0379     .probe      = stdp4028_ge_b850v3_fw_probe,
0380     .remove     = stdp4028_ge_b850v3_fw_remove,
0381     .driver     = {
0382         .name       = "stdp4028-ge-b850v3-fw",
0383         .of_match_table = stdp4028_ge_b850v3_fw_match,
0384     },
0385 };
0386 
0387 static int stdp2690_ge_b850v3_fw_probe(struct i2c_client *stdp2690_i2c,
0388                        const struct i2c_device_id *id)
0389 {
0390     struct device *dev = &stdp2690_i2c->dev;
0391     int ret;
0392 
0393     ret = ge_b850v3_lvds_init(dev);
0394 
0395     if (ret)
0396         return ret;
0397 
0398     ge_b850v3_lvds_ptr->stdp2690_i2c = stdp2690_i2c;
0399     i2c_set_clientdata(stdp2690_i2c, ge_b850v3_lvds_ptr);
0400 
0401     /* Only register after both bridges are probed */
0402     if (!ge_b850v3_lvds_ptr->stdp4028_i2c)
0403         return 0;
0404 
0405     return ge_b850v3_register();
0406 }
0407 
0408 static int stdp2690_ge_b850v3_fw_remove(struct i2c_client *stdp2690_i2c)
0409 {
0410     ge_b850v3_lvds_remove();
0411 
0412     return 0;
0413 }
0414 
0415 static const struct i2c_device_id stdp2690_ge_b850v3_fw_i2c_table[] = {
0416     {"stdp2690_ge_fw", 0},
0417     {},
0418 };
0419 MODULE_DEVICE_TABLE(i2c, stdp2690_ge_b850v3_fw_i2c_table);
0420 
0421 static const struct of_device_id stdp2690_ge_b850v3_fw_match[] = {
0422     { .compatible = "megachips,stdp2690-ge-b850v3-fw" },
0423     {},
0424 };
0425 MODULE_DEVICE_TABLE(of, stdp2690_ge_b850v3_fw_match);
0426 
0427 static struct i2c_driver stdp2690_ge_b850v3_fw_driver = {
0428     .id_table   = stdp2690_ge_b850v3_fw_i2c_table,
0429     .probe      = stdp2690_ge_b850v3_fw_probe,
0430     .remove     = stdp2690_ge_b850v3_fw_remove,
0431     .driver     = {
0432         .name       = "stdp2690-ge-b850v3-fw",
0433         .of_match_table = stdp2690_ge_b850v3_fw_match,
0434     },
0435 };
0436 
0437 static int __init stdpxxxx_ge_b850v3_init(void)
0438 {
0439     int ret;
0440 
0441     ret = i2c_add_driver(&stdp4028_ge_b850v3_fw_driver);
0442     if (ret)
0443         return ret;
0444 
0445     return i2c_add_driver(&stdp2690_ge_b850v3_fw_driver);
0446 }
0447 module_init(stdpxxxx_ge_b850v3_init);
0448 
0449 static void __exit stdpxxxx_ge_b850v3_exit(void)
0450 {
0451     i2c_del_driver(&stdp2690_ge_b850v3_fw_driver);
0452     i2c_del_driver(&stdp4028_ge_b850v3_fw_driver);
0453 }
0454 module_exit(stdpxxxx_ge_b850v3_exit);
0455 
0456 MODULE_AUTHOR("Peter Senna Tschudin <peter.senna@collabora.com>");
0457 MODULE_AUTHOR("Martyn Welch <martyn.welch@collabora.co.uk>");
0458 MODULE_DESCRIPTION("GE LVDS to DP++ display bridge)");
0459 MODULE_LICENSE("GPL v2");