From patchwork Fri Oct 5 09:26:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru-Cosmin Gheorghe X-Patchwork-Id: 10627695 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D70291515 for ; Fri, 5 Oct 2018 09:26:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CCA1D29236 for ; Fri, 5 Oct 2018 09:26:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C03B92923D; Fri, 5 Oct 2018 09:26:54 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 0F03D29236 for ; Fri, 5 Oct 2018 09:26:54 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id E51A26E767; Fri, 5 Oct 2018 09:26:51 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from EUR04-VI1-obe.outbound.protection.outlook.com (mail-eopbgr80077.outbound.protection.outlook.com [40.107.8.77]) by gabe.freedesktop.org (Postfix) with ESMTPS id BD3AF6E767 for ; Fri, 5 Oct 2018 09:26:50 +0000 (UTC) Received: from DB6PR0802MB2551.eurprd08.prod.outlook.com (10.172.251.149) by DB6PR0802MB2197.eurprd08.prod.outlook.com (10.172.227.19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1185.22; Fri, 5 Oct 2018 09:26:48 +0000 Received: from DB6PR0802MB2551.eurprd08.prod.outlook.com ([fe80::647d:f29a:a6d3:c8f2]) by DB6PR0802MB2551.eurprd08.prod.outlook.com ([fe80::647d:f29a:a6d3:c8f2%12]) with mapi id 15.20.1207.022; Fri, 5 Oct 2018 09:26:48 +0000 From: Alexandru-Cosmin Gheorghe To: "seanpaul@chromium.org" , "airlied@linux.ie" , "dri-devel@lists.freedesktop.org" , Liviu Dudau , Brian Starkey , "malidp@foss.arm.com" , "gustavo@padovan.org" , "maarten.lankhorst@linux.intel.com" , Ayan Halder , "daniel.vetter@ffwll.ch" , Raymond Smith , David Garbett , Lisa Wu , Matt Szczesiak , Charles Xu , "james qian wang (Arm Technology China)" Subject: [PATCH v3 1/6] drm/fourcc: Add char_per_block, block_w and block_h in drm_format_info Thread-Topic: [PATCH v3 1/6] drm/fourcc: Add char_per_block, block_w and block_h in drm_format_info Thread-Index: AQHUXI2KdyKV5KRgJ0CxlfrdSpaDkg== Date: Fri, 5 Oct 2018 09:26:47 +0000 Message-ID: <20181005092606.21100-2-alexandru-cosmin.gheorghe@arm.com> References: <20181005092606.21100-1-alexandru-cosmin.gheorghe@arm.com> In-Reply-To: <20181005092606.21100-1-alexandru-cosmin.gheorghe@arm.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: VI1P195CA0039.EURP195.PROD.OUTLOOK.COM (2603:10a6:802:5a::28) To DB6PR0802MB2551.eurprd08.prod.outlook.com (2603:10a6:4:a1::21) x-ms-exchange-messagesentrepresentingtype: 1 x-originating-ip: [217.140.106.51] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; DB6PR0802MB2197; 6:GVq7o2oqVANT3wN4WImmdYtjj6TqOzFTFIJSsbLAerXDb5TBXi+vxbOH3lN7GenKL9fYE5HNAWNZEUTMvJRQipp1Ij+Fa86REOEQrbymkmr6Efe7R4gyBVEsO1fkMA7HaweGwwiD58nbUD2cfAOrqsXTd8R4eTsXEqp5o7aELs6fKfZ+9dzhLI2P+j1P4xKnc9I7QRh0zfb67ewJ9C973AWiUEeli82KaMR9EieCfGRO5a12uvM2N3P8jee0h2u2IEicf2z3tvxh2xBOhJqK4RncLRB4R6y4zkJ8OGIUASJjyhYQKxz+oeLe8hX2QblSM/8U/aAPhwfr3JcvZI6TUasfHcOV7QqQiD+AWIWJrUaF71rR13RkIQmrDdtnaU4rKoMq+ELiLKYWGnu/qMvJTJloeSdypZ3xt7r8t0Ql9Nsh7h8LvPtTDGGKjYr2oP4nkaE2XpKLeiFcr/rqoD2m2g==; 5:rBtbnknRg1fBtQmhfmCKJw9gy/oKLIrbMAWSkmTG22Vc/uGvhAEhWxGnIW3v5cMS7IMwwl0s/Z4s7+F/aa5x+2Xq2dtyfVUGIry3QzXtiIMYRIFvdsdDMeBu/fJ6xnfRsO1XmBNby/ZV8RnDMmk0im5n9vzCRrFXtu2kfVzg3sk=; 7:IREkUYs5oNQ6p2AP7ANeXjLeGhPMLvI4ZNCZ3+fLpzLno5j3YbMyJ9FzBw8M7UaS8KPDEiOmcNpGEpyzyCS0c0eyJA5cIDKG0niKBLQkOU0gGIIvc0TyCLju5lNIynGVTV1iRQdgrPAWos/mVZxEGB7iw3xvdR9T6T+uB7r2on0WftFH9yAzC7hGt+BVli/aLk6f6Bj12Ql/PcWDXs2pQZ0zBXbDWuNFy68B7S3xZZESLA4w6Glq30xo8SZaRqTZ x-ms-office365-filtering-correlation-id: d1039d70-f612-4dad-638b-08d62aa4ac67 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600074)(711020)(4618075)(2017052603328)(7153060)(7193020); SRVR:DB6PR0802MB2197; x-ms-traffictypediagnostic: DB6PR0802MB2197: nodisclaimer: True x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(180628864354917); x-ms-exchange-senderadcheck: 1 x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(3231355)(944501410)(52105095)(3002001)(10201501046)(93006095)(93001095)(6055026)(149066)(150057)(6041310)(20161123564045)(20161123558120)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123560045)(20161123562045)(201708071742011)(7699051); SRVR:DB6PR0802MB2197; BCL:0; PCL:0; RULEID:; SRVR:DB6PR0802MB2197; x-forefront-prvs: 0816F1D86E x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(136003)(366004)(346002)(396003)(39860400002)(376002)(189003)(199004)(72206003)(68736007)(8676002)(26005)(36756003)(14454004)(256004)(186003)(11346002)(71190400001)(486006)(71200400001)(5660300001)(2616005)(6636002)(2900100001)(105586002)(106356001)(446003)(66066001)(305945005)(6506007)(7736002)(102836004)(8936002)(52116002)(76176011)(81166006)(476003)(99286004)(386003)(110136005)(316002)(54906003)(2201001)(4326008)(5250100002)(6436002)(81156014)(6486002)(2906002)(575784001)(25786009)(86362001)(1076002)(53936002)(2501003)(6116002)(3846002)(97736004)(478600001)(6512007)(921003)(1121003); DIR:OUT; SFP:1101; SCL:1; SRVR:DB6PR0802MB2197; H:DB6PR0802MB2551.eurprd08.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: arm.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: qUlEgLGu0GWr8JShOI397CHn1Qiy3ASzfE91h3pyN1PCV/BFceqvi6et3CO8jHLBOVnua3NHwn2kutYaW9vVnlMgyjUSjP/tb3bLKje9dNSv9Ra0bKd1HtvhhiEFWnOkkU7rCeWSyYCW5qe1E4jiYOEfVMGjSISN8WJc5CP4dG8YX00gbDjzO+DvlAn+d6bdfLxJRFnJ9BG6yc1z+gq/s65X+7f8awUXNAuZyr22fBcrZKnGrZcjBcZWkEr4sMFRbjjLaSPl2eh8m3F7CFDA2Us3dQMrvAVv8xZpR/kWI58Ae+C7vhSKCbYIYYFEowHJLMzAZ4bT9eKNR0NWg0wS5lpngCTNMi3zg4fHrphNcN0= spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-Network-Message-Id: d1039d70-f612-4dad-638b-08d62aa4ac67 X-MS-Exchange-CrossTenant-originalarrivaltime: 05 Oct 2018 09:26:48.0048 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB6PR0802MB2197 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: nd , Alexandru-Cosmin Gheorghe Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP For some pixel formats .cpp structure in drm_format info it's not enough to describe the peculiarities of the pixel layout, for example tiled formats or packed formats at bit level. What's implemented here is to add three new members to drm_format_info that could describe such formats: - char_per_block[3] - block_w[3] - block_h[3] char_per_block will be put in a union alongside cpp, for transparent compatibility with the existing format descriptions. Regarding, block_w and block_h they are intended to be used through their equivalent getters drm_format_info_block_width / drm_format_info_block_height, the reason of the getters is to abstract the fact that for normal formats block_w and block_h will be unset/0, but the methods will be returning 1. Using that the following drm core functions had been updated to generically handle both block and non-block formats: - drm_fb_cma_get_gem_addr: for block formats it will just return the beginning of the block. - framebuffer_check: Updated to compute the minimum pitch as DIV_ROUND_UP(width * char_per_block, drm_format_info_block_width(info, i) * drm_format_info_block_height(info, i)) - drm_gem_fb_create_with_funcs: Updated to compute the size of the last line of pixels with the same formula as for the minimum pitch. - In places where is not expecting to handle block formats, like fbdev helpers I just added some warnings in case the block width/height are greater than 1. Signed-off-by: Alexandru Gheorghe Reviewed-by: Liviu Dudau --- drivers/gpu/drm/drm_fb_cma_helper.c | 21 ++++++++-- drivers/gpu/drm/drm_fb_helper.c | 6 +++ drivers/gpu/drm/drm_fourcc.c | 40 ++++++++++++++++++++ drivers/gpu/drm/drm_framebuffer.c | 9 +++-- drivers/gpu/drm/drm_gem_framebuffer_helper.c | 4 +- include/drm/drm_fourcc.h | 29 +++++++++++++- 6 files changed, 101 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c index 47e0e2f6642d..f8293f4d96cf 100644 --- a/drivers/gpu/drm/drm_fb_cma_helper.c +++ b/drivers/gpu/drm/drm_fb_cma_helper.c @@ -72,7 +72,9 @@ struct drm_gem_cma_object *drm_fb_cma_get_gem_obj(struct drm_framebuffer *fb, EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_obj); /** - * drm_fb_cma_get_gem_addr() - Get physical address for framebuffer + * drm_fb_cma_get_gem_addr() - Get physical address for framebuffer, for pixel + * formats where values are grouped in blocks this will get you the beginning of + * the block * @fb: The framebuffer * @state: Which state of drm plane * @plane: Which plane @@ -87,6 +89,14 @@ dma_addr_t drm_fb_cma_get_gem_addr(struct drm_framebuffer *fb, struct drm_gem_cma_object *obj; dma_addr_t paddr; u8 h_div = 1, v_div = 1; + u32 block_w = drm_format_info_block_width(fb->format, plane); + u32 block_h = drm_format_info_block_height(fb->format, plane); + u32 block_size = fb->format->char_per_block[plane]; + u32 sample_x; + u32 sample_y; + u32 block_start_y; + u32 num_hblocks; + obj = drm_fb_cma_get_gem_obj(fb, plane); if (!obj) @@ -99,8 +109,13 @@ dma_addr_t drm_fb_cma_get_gem_addr(struct drm_framebuffer *fb, v_div = fb->format->vsub; } - paddr += (fb->format->cpp[plane] * (state->src_x >> 16)) / h_div; - paddr += (fb->pitches[plane] * (state->src_y >> 16)) / v_div; + sample_x = (state->src_x >> 16) / h_div; + sample_y = (state->src_y >> 16) / v_div; + block_start_y = (sample_y / block_h) * block_h; + num_hblocks = sample_x / block_w; + + paddr += fb->pitches[plane] * block_start_y; + paddr += block_size * num_hblocks; return paddr; } diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index a504a5e05676..9add0d7da744 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -1595,6 +1595,10 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var, if (var->pixclock != 0 || in_dbg_master()) return -EINVAL; + if ((drm_format_info_block_width(fb->format, 0) > 1) || + (drm_format_info_block_height(fb->format, 0) > 1)) + return -EINVAL; + /* * Changes struct fb_var_screeninfo are currently not pushed back * to KMS, hence fail if different settings are requested. @@ -1969,6 +1973,8 @@ void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helpe { struct drm_framebuffer *fb = fb_helper->fb; + WARN_ON((drm_format_info_block_width(fb->format, 0) > 1) || + (drm_format_info_block_height(fb->format, 0) > 1)); info->pseudo_palette = fb_helper->pseudo_palette; info->var.xres_virtual = fb->width; info->var.yres_virtual = fb->height; diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c index a154763257ae..0c9725ffd5e9 100644 --- a/drivers/gpu/drm/drm_fourcc.c +++ b/drivers/gpu/drm/drm_fourcc.c @@ -403,3 +403,43 @@ int drm_format_plane_height(int height, uint32_t format, int plane) return height / info->vsub; } EXPORT_SYMBOL(drm_format_plane_height); + +/** + * drm_format_info_block_width - width in pixels of block. + * @info: pixel format info + * @plane: plane index + * + * Returns: + * The width in pixels of a block, depending on the plane index. + */ +unsigned int drm_format_info_block_width(const struct drm_format_info *info, + int plane) +{ + if (!info || plane >= info->num_planes) + return 0; + + if (!info->block_w[plane]) + return 1; + return info->block_w[plane]; +} +EXPORT_SYMBOL(drm_format_info_block_width); + +/** + * drm_format_info_block_height - height in pixels of a block + * @info: pixel format info + * @plane: plane index + * + * Returns: + * The height in pixels of a block, depending on the plane index. + */ +unsigned int drm_format_info_block_height(const struct drm_format_info *info, + int plane) +{ + if (!info || plane >= info->num_planes) + return 0; + + if (!info->block_h[plane]) + return 1; + return info->block_h[plane]; +} +EXPORT_SYMBOL(drm_format_info_block_height); diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index 3bf729d0aae5..4e14013788cd 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c @@ -195,20 +195,23 @@ static int framebuffer_check(struct drm_device *dev, for (i = 0; i < info->num_planes; i++) { unsigned int width = fb_plane_width(r->width, info, i); unsigned int height = fb_plane_height(r->height, info, i); - unsigned int cpp = info->cpp[i]; + unsigned int block_size = info->char_per_block[i]; + u64 min_pitch = DIV_ROUND_UP((u64)width * block_size, + drm_format_info_block_width(info, i) * + drm_format_info_block_height(info, i)); if (!r->handles[i]) { DRM_DEBUG_KMS("no buffer object handle for plane %d\n", i); return -EINVAL; } - if ((uint64_t) width * cpp > UINT_MAX) + if (min_pitch > UINT_MAX) return -ERANGE; if ((uint64_t) height * r->pitches[i] + r->offsets[i] > UINT_MAX) return -ERANGE; - if (r->pitches[i] < width * cpp) { + if (r->pitches[i] < min_pitch) { DRM_DEBUG_KMS("bad pitch %u for plane %d\n", r->pitches[i], i); return -EINVAL; } diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c b/drivers/gpu/drm/drm_gem_framebuffer_helper.c index ded7a379ac35..e342511370e7 100644 --- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c +++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c @@ -171,7 +171,9 @@ drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file, } min_size = (height - 1) * mode_cmd->pitches[i] - + width * info->cpp[i] + + DIV_ROUND_UP((u64)width * info->char_per_block[i], + drm_format_info_block_width(info, i) * + drm_format_info_block_height(info, i)) + mode_cmd->offsets[i]; if (objs[i]->size < min_size) { diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h index 865ef60c17af..305e80847abc 100644 --- a/include/drm/drm_fourcc.h +++ b/include/drm/drm_fourcc.h @@ -58,6 +58,24 @@ struct drm_mode_fb_cmd2; * use in new code and set to 0 for new formats. * @num_planes: Number of color planes (1 to 3) * @cpp: Number of bytes per pixel (per plane) + * @char_per_block: Number of bytes per block (per plane), where blocks are + * defined as a rectangle of pixels which are stored next to each other in + * a byte aligned memory region. + * Together with block_w and block_h this could be used to properly + * describe tiles in tiled formats or to describe groups of pixels in + * packed formats for which the memory needed for a single pixel it's not + * byte aligned. + * Cpp had been kept from historical reasons because there are a lot of + * places in drivers where it's used. In drm core for generic code paths + * the preferred way is to use char_per_block, drm_format_info_block_width + * and drm_format_info_block_height which should allow handling both block + * and non-block formats in the same way. + * For formats that are intended to be used just with modifiers, cpp/ + * char_per_block must be 0. + * @block_w: Block width in pixels, this is intended to be accessed through + * drm_format_info_block_width + * @block_h: Block height in pixels, this is intended to be accessed through + * drm_format_info_block_height * @hsub: Horizontal chroma subsampling factor * @vsub: Vertical chroma subsampling factor * @has_alpha: Does the format embeds an alpha component? @@ -67,7 +85,12 @@ struct drm_format_info { u32 format; u8 depth; u8 num_planes; - u8 cpp[3]; + union { + u8 cpp[3]; + u8 char_per_block[3]; + }; + u8 block_w[3]; + u8 block_h[3]; u8 hsub; u8 vsub; bool has_alpha; @@ -96,6 +119,10 @@ int drm_format_horz_chroma_subsampling(uint32_t format); int drm_format_vert_chroma_subsampling(uint32_t format); int drm_format_plane_width(int width, uint32_t format, int plane); int drm_format_plane_height(int height, uint32_t format, int plane); +unsigned int drm_format_info_block_width(const struct drm_format_info *info, + int plane); +unsigned int drm_format_info_block_height(const struct drm_format_info *info, + int plane); const char *drm_get_format_name(uint32_t format, struct drm_format_name_buf *buf); #endif /* __DRM_FOURCC_H__ */