Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/tegra: sor: Do not support deep color modes

Current generations of Tegra do not support deep color modes, so force
8 bits per color even if the connected monitor or panel supports more.

Signed-off-by: Thierry Reding <treding@nvidia.com>

+89 -14
+86 -14
drivers/gpu/drm/tegra/sor.c
··· 190 190 struct regulator *hdmi_supply; 191 191 }; 192 192 193 + struct tegra_sor_state { 194 + struct drm_connector_state base; 195 + 196 + unsigned int bpc; 197 + }; 198 + 199 + static inline struct tegra_sor_state * 200 + to_sor_state(struct drm_connector_state *state) 201 + { 202 + return container_of(state, struct tegra_sor_state, base); 203 + } 204 + 193 205 struct tegra_sor_config { 194 206 u32 bits_per_pixel; 195 207 ··· 732 720 733 721 static void tegra_sor_mode_set(struct tegra_sor *sor, 734 722 const struct drm_display_mode *mode, 735 - const struct drm_display_info *info) 723 + struct tegra_sor_state *state) 736 724 { 737 725 struct tegra_dc *dc = to_tegra_dc(sor->output.encoder.crtc); 738 726 unsigned int vbe, vse, hbe, hse, vbs, hbs; ··· 758 746 if (mode->flags & DRM_MODE_FLAG_NVSYNC) 759 747 value |= SOR_STATE_ASY_VSYNCPOL; 760 748 761 - switch (info->bpc) { 749 + switch (state->bpc) { 750 + case 16: 751 + value |= SOR_STATE_ASY_PIXELDEPTH_BPP_48_444; 752 + break; 753 + 754 + case 12: 755 + value |= SOR_STATE_ASY_PIXELDEPTH_BPP_36_444; 756 + break; 757 + 758 + case 10: 759 + value |= SOR_STATE_ASY_PIXELDEPTH_BPP_30_444; 760 + break; 761 + 762 762 case 8: 763 763 value |= SOR_STATE_ASY_PIXELDEPTH_BPP_24_444; 764 764 break; ··· 780 756 break; 781 757 782 758 default: 783 - BUG(); 759 + value |= SOR_STATE_ASY_PIXELDEPTH_BPP_24_444; 784 760 break; 785 761 } 786 762 ··· 1197 1173 sor->debugfs = NULL; 1198 1174 } 1199 1175 1176 + static void tegra_sor_connector_reset(struct drm_connector *connector) 1177 + { 1178 + struct tegra_sor_state *state; 1179 + 1180 + state = kzalloc(sizeof(*state), GFP_KERNEL); 1181 + if (!state) 1182 + return; 1183 + 1184 + if (connector->state) { 1185 + __drm_atomic_helper_connector_destroy_state(connector->state); 1186 + kfree(connector->state); 1187 + } 1188 + 1189 + __drm_atomic_helper_connector_reset(connector, &state->base); 1190 + } 1191 + 1200 1192 static enum drm_connector_status 1201 1193 tegra_sor_connector_detect(struct drm_connector *connector, bool force) 1202 1194 { ··· 1225 1185 return tegra_output_connector_detect(connector, force); 1226 1186 } 1227 1187 1188 + static struct drm_connector_state * 1189 + tegra_sor_connector_duplicate_state(struct drm_connector *connector) 1190 + { 1191 + struct tegra_sor_state *state = to_sor_state(connector->state); 1192 + struct tegra_sor_state *copy; 1193 + 1194 + copy = kmemdup(state, sizeof(*state), GFP_KERNEL); 1195 + if (!copy) 1196 + return NULL; 1197 + 1198 + __drm_atomic_helper_connector_duplicate_state(connector, &copy->base); 1199 + 1200 + return &copy->base; 1201 + } 1202 + 1228 1203 static const struct drm_connector_funcs tegra_sor_connector_funcs = { 1229 1204 .dpms = drm_atomic_helper_connector_dpms, 1230 - .reset = drm_atomic_helper_connector_reset, 1205 + .reset = tegra_sor_connector_reset, 1231 1206 .detect = tegra_sor_connector_detect, 1232 1207 .fill_modes = drm_helper_probe_single_connector_modes, 1233 1208 .destroy = tegra_output_connector_destroy, 1234 - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 1209 + .atomic_duplicate_state = tegra_sor_connector_duplicate_state, 1235 1210 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 1236 1211 }; 1237 1212 ··· 1384 1329 struct tegra_dc *dc = to_tegra_dc(encoder->crtc); 1385 1330 struct tegra_sor *sor = to_sor(output); 1386 1331 struct tegra_sor_config config; 1387 - struct drm_display_info *info; 1332 + struct tegra_sor_state *state; 1388 1333 struct drm_dp_link link; 1389 1334 u8 rate, lanes; 1390 1335 unsigned int i; 1391 1336 int err = 0; 1392 1337 u32 value; 1393 1338 1394 - info = &output->connector.display_info; 1339 + state = to_sor_state(output->connector.state); 1395 1340 1396 1341 err = clk_prepare_enable(sor->clk); 1397 1342 if (err < 0) ··· 1418 1363 dev_err(sor->dev, "failed to set safe parent clock: %d\n", err); 1419 1364 1420 1365 memset(&config, 0, sizeof(config)); 1421 - config.bits_per_pixel = output->connector.display_info.bpc * 3; 1366 + config.bits_per_pixel = state->bpc * 3; 1422 1367 1423 1368 err = tegra_sor_compute_config(sor, mode, &config, &link); 1424 1369 if (err < 0) ··· 1651 1596 value |= SOR_STATE_ASY_PROTOCOL_DP_A; 1652 1597 tegra_sor_writel(sor, value, SOR_STATE1); 1653 1598 1654 - tegra_sor_mode_set(sor, mode, info); 1599 + tegra_sor_mode_set(sor, mode, state); 1655 1600 1656 1601 /* PWM setup */ 1657 1602 err = tegra_sor_setup_pwm(sor, 250); ··· 1684 1629 struct drm_connector_state *conn_state) 1685 1630 { 1686 1631 struct tegra_output *output = encoder_to_output(encoder); 1632 + struct tegra_sor_state *state = to_sor_state(conn_state); 1687 1633 struct tegra_dc *dc = to_tegra_dc(conn_state->crtc); 1688 1634 unsigned long pclk = crtc_state->mode.clock * 1000; 1689 1635 struct tegra_sor *sor = to_sor(output); 1636 + struct drm_display_info *info; 1690 1637 int err; 1638 + 1639 + info = &output->connector.display_info; 1691 1640 1692 1641 err = tegra_dc_state_setup_clock(dc, crtc_state, sor->clk_parent, 1693 1642 pclk, 0); 1694 1643 if (err < 0) { 1695 1644 dev_err(output->dev, "failed to setup CRTC state: %d\n", err); 1696 1645 return err; 1646 + } 1647 + 1648 + switch (info->bpc) { 1649 + case 8: 1650 + case 6: 1651 + state->bpc = info->bpc; 1652 + break; 1653 + 1654 + default: 1655 + DRM_DEBUG_KMS("%u bits-per-color not supported\n", info->bpc); 1656 + state->bpc = 8; 1657 + break; 1697 1658 } 1698 1659 1699 1660 return 0; ··· 1886 1815 struct tegra_dc *dc = to_tegra_dc(encoder->crtc); 1887 1816 struct tegra_sor_hdmi_settings *settings; 1888 1817 struct tegra_sor *sor = to_sor(output); 1818 + struct tegra_sor_state *state; 1889 1819 struct drm_display_mode *mode; 1890 - struct drm_display_info *info; 1891 1820 unsigned int div; 1892 1821 u32 value; 1893 1822 int err; 1894 1823 1824 + state = to_sor_state(output->connector.state); 1895 1825 mode = &encoder->crtc->state->adjusted_mode; 1896 - info = &output->connector.display_info; 1897 1826 1898 1827 err = clk_prepare_enable(sor->clk); 1899 1828 if (err < 0) ··· 2126 2055 value &= ~DITHER_CONTROL_MASK; 2127 2056 value &= ~BASE_COLOR_SIZE_MASK; 2128 2057 2129 - switch (info->bpc) { 2058 + switch (state->bpc) { 2130 2059 case 6: 2131 2060 value |= BASE_COLOR_SIZE_666; 2132 2061 break; ··· 2136 2065 break; 2137 2066 2138 2067 default: 2139 - WARN(1, "%u bits-per-color not supported\n", info->bpc); 2068 + WARN(1, "%u bits-per-color not supported\n", state->bpc); 2069 + value |= BASE_COLOR_SIZE_888; 2140 2070 break; 2141 2071 } 2142 2072 ··· 2159 2087 value |= SOR_HEAD_STATE_COLORSPACE_RGB; 2160 2088 tegra_sor_writel(sor, value, SOR_HEAD_STATE0(dc->pipe)); 2161 2089 2162 - tegra_sor_mode_set(sor, mode, info); 2090 + tegra_sor_mode_set(sor, mode, state); 2163 2091 2164 2092 tegra_sor_update(sor); 2165 2093
+3
drivers/gpu/drm/tegra/sor.h
··· 27 27 #define SOR_STATE_ASY_PIXELDEPTH_MASK (0xf << 17) 28 28 #define SOR_STATE_ASY_PIXELDEPTH_BPP_18_444 (0x2 << 17) 29 29 #define SOR_STATE_ASY_PIXELDEPTH_BPP_24_444 (0x5 << 17) 30 + #define SOR_STATE_ASY_PIXELDEPTH_BPP_30_444 (0x6 << 17) 31 + #define SOR_STATE_ASY_PIXELDEPTH_BPP_36_444 (0x8 << 17) 32 + #define SOR_STATE_ASY_PIXELDEPTH_BPP_48_444 (0x9 << 17) 30 33 #define SOR_STATE_ASY_VSYNCPOL (1 << 13) 31 34 #define SOR_STATE_ASY_HSYNCPOL (1 << 12) 32 35 #define SOR_STATE_ASY_PROTOCOL_MASK (0xf << 8)