.. | .. |
---|
32 | 32 | |
---|
33 | 33 | #include "analogix_dp_core.h" |
---|
34 | 34 | #include "analogix_dp_reg.h" |
---|
| 35 | +#include "../../rockchip/rockchip_drm_drv.h" |
---|
35 | 36 | |
---|
36 | 37 | #define to_dp(nm) container_of(nm, struct analogix_dp_device, nm) |
---|
37 | 38 | |
---|
.. | .. |
---|
51 | 52 | struct i2c_client *client; |
---|
52 | 53 | struct device_node *node; |
---|
53 | 54 | }; |
---|
| 55 | + |
---|
| 56 | +static void analogix_dp_bridge_mode_set(struct drm_bridge *bridge, |
---|
| 57 | + const struct drm_display_mode *adj_mode); |
---|
54 | 58 | |
---|
55 | 59 | static bool analogix_dp_bandwidth_ok(struct analogix_dp_device *dp, |
---|
56 | 60 | const struct drm_display_mode *mode, |
---|
.. | .. |
---|
1442 | 1446 | extcon_set_state_sync(dp->extcon, EXTCON_DISP_DP, false); |
---|
1443 | 1447 | } |
---|
1444 | 1448 | |
---|
| 1449 | +static int |
---|
| 1450 | +analogix_dp_atomic_connector_get_property(struct drm_connector *connector, |
---|
| 1451 | + const struct drm_connector_state *state, |
---|
| 1452 | + struct drm_property *property, |
---|
| 1453 | + uint64_t *val) |
---|
| 1454 | +{ |
---|
| 1455 | + struct rockchip_drm_private *private = connector->dev->dev_private; |
---|
| 1456 | + struct analogix_dp_device *dp = to_dp(connector); |
---|
| 1457 | + |
---|
| 1458 | + if (property == private->split_area_prop) { |
---|
| 1459 | + switch (dp->split_area) { |
---|
| 1460 | + case 1: |
---|
| 1461 | + *val = ROCKCHIP_DRM_SPLIT_LEFT_SIDE; |
---|
| 1462 | + break; |
---|
| 1463 | + case 2: |
---|
| 1464 | + *val = ROCKCHIP_DRM_SPLIT_RIGHT_SIDE; |
---|
| 1465 | + break; |
---|
| 1466 | + default: |
---|
| 1467 | + *val = ROCKCHIP_DRM_SPLIT_UNSET; |
---|
| 1468 | + break; |
---|
| 1469 | + } |
---|
| 1470 | + } |
---|
| 1471 | + |
---|
| 1472 | + return 0; |
---|
| 1473 | +} |
---|
| 1474 | + |
---|
1445 | 1475 | static const struct drm_connector_funcs analogix_dp_connector_funcs = { |
---|
1446 | 1476 | .fill_modes = drm_helper_probe_single_connector_modes, |
---|
1447 | 1477 | .detect = analogix_dp_connector_detect, |
---|
.. | .. |
---|
1450 | 1480 | .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, |
---|
1451 | 1481 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, |
---|
1452 | 1482 | .force = analogix_dp_connector_force, |
---|
| 1483 | + .atomic_get_property = analogix_dp_atomic_connector_get_property, |
---|
1453 | 1484 | }; |
---|
1454 | 1485 | |
---|
1455 | 1486 | static int analogix_dp_bridge_attach(struct drm_bridge *bridge, |
---|
.. | .. |
---|
1480 | 1511 | |
---|
1481 | 1512 | if (!dp->plat_data->skip_connector) { |
---|
1482 | 1513 | int connector_type = DRM_MODE_CONNECTOR_eDP; |
---|
| 1514 | + struct rockchip_drm_private *private; |
---|
1483 | 1515 | |
---|
1484 | 1516 | if (dp->plat_data->bridge && |
---|
1485 | 1517 | dp->plat_data->bridge->type != DRM_MODE_CONNECTOR_Unknown) |
---|
.. | .. |
---|
1498 | 1530 | DRM_ERROR("Failed to initialize connector with drm\n"); |
---|
1499 | 1531 | return ret; |
---|
1500 | 1532 | } |
---|
| 1533 | + |
---|
| 1534 | + private = connector->dev->dev_private; |
---|
| 1535 | + |
---|
| 1536 | + if (dp->split_area) |
---|
| 1537 | + drm_object_attach_property(&connector->base, |
---|
| 1538 | + private->split_area_prop, |
---|
| 1539 | + dp->split_area); |
---|
1501 | 1540 | |
---|
1502 | 1541 | drm_connector_helper_add(connector, |
---|
1503 | 1542 | &analogix_dp_connector_helper_funcs); |
---|
.. | .. |
---|
1575 | 1614 | struct drm_atomic_state *old_state = old_bridge_state->base.state; |
---|
1576 | 1615 | struct analogix_dp_device *dp = bridge->driver_private; |
---|
1577 | 1616 | struct drm_crtc *crtc; |
---|
1578 | | - struct drm_crtc_state *old_crtc_state; |
---|
| 1617 | + struct drm_crtc_state *old_crtc_state, *new_crtc_state; |
---|
1579 | 1618 | |
---|
1580 | 1619 | crtc = analogix_dp_get_new_crtc(dp, old_state); |
---|
1581 | 1620 | if (!crtc) |
---|
1582 | 1621 | return; |
---|
1583 | 1622 | |
---|
1584 | 1623 | old_crtc_state = drm_atomic_get_old_crtc_state(old_state, crtc); |
---|
| 1624 | + |
---|
| 1625 | + new_crtc_state = drm_atomic_get_new_crtc_state(old_state, crtc); |
---|
| 1626 | + analogix_dp_bridge_mode_set(bridge, &new_crtc_state->adjusted_mode); |
---|
| 1627 | + |
---|
1585 | 1628 | /* Don't touch the panel if we're coming back from PSR */ |
---|
1586 | 1629 | if (old_crtc_state && old_crtc_state->self_refresh_active) |
---|
1587 | 1630 | return; |
---|
.. | .. |
---|
1790 | 1833 | } |
---|
1791 | 1834 | |
---|
1792 | 1835 | static void analogix_dp_bridge_mode_set(struct drm_bridge *bridge, |
---|
1793 | | - const struct drm_display_mode *orig_mode, |
---|
1794 | 1836 | const struct drm_display_mode *adj_mode) |
---|
1795 | 1837 | { |
---|
1796 | 1838 | struct analogix_dp_device *dp = bridge->driver_private; |
---|
.. | .. |
---|
1910 | 1952 | |
---|
1911 | 1953 | drm_mode_copy(&m, mode); |
---|
1912 | 1954 | |
---|
1913 | | - if (dp->plat_data->split_mode) |
---|
| 1955 | + if (dp->plat_data->split_mode || dp->plat_data->dual_connector_split) |
---|
1914 | 1956 | dp->plat_data->convert_to_origin_mode(&m); |
---|
1915 | 1957 | |
---|
1916 | 1958 | max_link_rate = min_t(u32, dp->video_info.max_link_rate, |
---|
.. | .. |
---|
1934 | 1976 | .atomic_enable = analogix_dp_bridge_atomic_enable, |
---|
1935 | 1977 | .atomic_disable = analogix_dp_bridge_atomic_disable, |
---|
1936 | 1978 | .atomic_post_disable = analogix_dp_bridge_atomic_post_disable, |
---|
1937 | | - .mode_set = analogix_dp_bridge_mode_set, |
---|
1938 | 1979 | .attach = analogix_dp_bridge_attach, |
---|
1939 | 1980 | .detach = analogix_dp_bridge_detach, |
---|
1940 | 1981 | .mode_valid = analogix_dp_bridge_mode_valid, |
---|
.. | .. |
---|
2073 | 2114 | return ret; |
---|
2074 | 2115 | } |
---|
2075 | 2116 | |
---|
| 2117 | + if (device_property_read_u32(dp->dev, "split-area", &dp->split_area)) |
---|
| 2118 | + dp->split_area = 0; |
---|
| 2119 | + |
---|
2076 | 2120 | return 0; |
---|
2077 | 2121 | } |
---|
2078 | 2122 | |
---|