summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKwanghyun Chung <khyun.chung@samsung.com>2021-07-26 17:53:36 +0900
committerTreehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com>2023-04-07 06:36:00 +0000
commit1b6b6af0a87be80659f1f4cfcb03479681c48c95 (patch)
treee341676ffdfbf4f9196eec638b9b7486e238ea84
parente65e7c4f651fd8a11c7eeba894e99bae8a3eb3a5 (diff)
downloaddisplay-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.c65
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;