diff options
author | Kwanghyun Chung <khyun.chung@samsung.com> | 2021-07-26 17:53:36 +0900 |
---|---|---|
committer | Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> | 2023-04-07 06:36:00 +0000 |
commit | 1b6b6af0a87be80659f1f4cfcb03479681c48c95 (patch) | |
tree | e341676ffdfbf4f9196eec638b9b7486e238ea84 | |
parent | e65e7c4f651fd8a11c7eeba894e99bae8a3eb3a5 (diff) | |
download | display-1b6b6af0a87be80659f1f4cfcb03479681c48c95.tar.gz |
drm: samsung: support sbwc encoded writeback
The feature to support sbwc encoded writeback was added. And,
DRM_FORMAT_NV12 to writeback also was added.
Bug: 187000170
Test: ./build_cloudripper.sh
Signed-off-by: Kwanghyun Chung <khyun.chung@samsung.com>
Change-Id: Id38229165b799799fecd653e2386a4d87bdfe368
-rw-r--r-- | samsung/exynos_drm_writeback.c | 65 |
1 files changed, 60 insertions, 5 deletions
diff --git a/samsung/exynos_drm_writeback.c b/samsung/exynos_drm_writeback.c index dab5949..c2f0c71 100644 --- a/samsung/exynos_drm_writeback.c +++ b/samsung/exynos_drm_writeback.c @@ -39,6 +39,11 @@ #include "exynos_drm_format.h" #include "exynos_drm_writeback.h" +static const struct drm_display_mode exynos_drm_writeback_modes[] = { + { DRM_MODE("2400x1080", DRM_MODE_TYPE_DRIVER, 165984, 2400, 2432, 2444, 2470, 0, 1080, 1092, + 1096, 1120, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, +}; + void wb_dump(struct drm_printer *p, struct writeback_device *wb) { if (wb->state != WB_STATE_ON) { @@ -53,6 +58,7 @@ void wb_dump(struct drm_printer *p, struct writeback_device *wb) static const uint32_t writeback_formats[] = { /* TODO : add DRM_FORMAT_RGBA1010102 */ DRM_FORMAT_RGBA8888, + DRM_FORMAT_NV12, }; static const struct of_device_id wb_of_match[] = { @@ -64,12 +70,37 @@ static const struct of_device_id wb_of_match[] = { { /* sentinel */ }, }; +static int exynos_drm_add_writeback_modes(struct drm_connector *connector) +{ + int i, count, num_modes = 0; + struct drm_display_mode *mode; + struct drm_device *dev = connector->dev; + + count = ARRAY_SIZE(exynos_drm_writeback_modes); + + for (i = 0; i < count; i++) { + const struct drm_display_mode *ptr = &exynos_drm_writeback_modes[i]; + + mode = drm_mode_duplicate(dev, ptr); + if (mode) { + drm_mode_probed_add(connector, mode); + num_modes++; + } + } + + return num_modes; +} + static int writeback_get_modes(struct drm_connector *connector) { struct drm_device *dev = connector->dev; + int num_modes; + + num_modes = drm_add_modes_noedid(connector, dev->mode_config.max_width, + dev->mode_config.max_height); + num_modes += exynos_drm_add_writeback_modes(connector); - return drm_add_modes_noedid(connector, dev->mode_config.max_width, - dev->mode_config.max_height); + return num_modes; } static void wb_convert_connector_state_to_config(struct dpp_params_info *config, @@ -87,7 +118,12 @@ static void wb_convert_connector_state_to_config(struct dpp_params_info *config, config->src.f_w = fb->width; config->src.f_h = fb->height; - config->comp_type = COMP_TYPE_NONE; + if (has_all_bits(DRM_FORMAT_MOD_SAMSUNG_SBWC(0), fb->modifier)) { + config->comp_type = COMP_TYPE_SBWC; + config->blk_size = SBWC_BLOCK_SIZE_GET(fb->modifier); + } else { + config->comp_type = COMP_TYPE_NONE; + } config->format = fb->format->format; config->standard = state->standard; @@ -99,8 +135,27 @@ static void wb_convert_connector_state_to_config(struct dpp_params_info *config, config->addr[0] = exynos_drm_fb_dma_addr(fb, 0); config->addr[1] = exynos_drm_fb_dma_addr(fb, 1); - config->addr[2] = exynos_drm_fb_dma_addr(fb, 2); - config->addr[3] = exynos_drm_fb_dma_addr(fb, 3); + + if (has_all_bits(DRM_FORMAT_MOD_SAMSUNG_SBWC(0), fb->modifier)) { + const struct dpu_fmt *fmt_info = dpu_find_fmt_info(config->format); + bool is_10bpc = IS_10BPC(fmt_info); + + config->addr[0] += Y_PL_SIZE_SBWC(config->src.f_w, config->src.f_h, is_10bpc); + config->y_hd_y2_stride = HD_STRIDE_SIZE_SBWC(config->src.f_w); + + config->addr[1] = exynos_drm_fb_dma_addr(fb, 0); + config->y_pl_c2_stride = PL_STRIDE_SIZE_SBWC(config->src.f_w, is_10bpc); + + config->addr[2] = exynos_drm_fb_dma_addr(fb, 1) + + UV_PL_SIZE_SBWC(config->src.f_w, config->src.f_h, is_10bpc); + config->c_hd_stride = HD_STRIDE_SIZE_SBWC(config->src.f_w); + + config->addr[3] = exynos_drm_fb_dma_addr(fb, 1); + config->c_pl_stride = PL_STRIDE_SIZE_SBWC(config->src.f_w, is_10bpc); + } else { + config->addr[2] = exynos_drm_fb_dma_addr(fb, 2); + config->addr[3] = exynos_drm_fb_dma_addr(fb, 3); + } /* TODO: blocking mode will be implemented later */ config->is_block = false; |