mdp5_plane.c revision 06c0dd96bfbba8a9368ffd7c4b12d3bfed37001d
1360a0cab50414ee30924917159066e69ee4b38d3Rob Herring/* 2360a0cab50414ee30924917159066e69ee4b38d3Rob Herring * Copyright (C) 2013 Red Hat 3ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD * Author: Rob Clark <robdclark@gmail.com> 4c84ca7ce3ae5d80622c1cc1cfe21011f9cc15be7Joachim Eastwood * 5c84ca7ce3ae5d80622c1cc1cfe21011f9cc15be7Joachim Eastwood * This program is free software; you can redistribute it and/or modify it 658dc5b53e1c1467e54bbbc47d56a4d5f8c478a31Joachim Eastwood * under the terms of the GNU General Public License version 2 as published by 7ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD * the Free Software Foundation. 8ad8a15d99cf2c8ab8ac1ab28402c49ec2548358dJean-Christophe PLAGNIOL-VILLARD * 9ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD * This program is distributed in the hope that it will be useful, but WITHOUT 10ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD * more details. 13ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD * 14ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD * You should have received a copy of the GNU General Public License along with 15ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD * this program. If not, see <http://www.gnu.org/licenses/>. 16ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD */ 17ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD 18ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD#include "mdp5_kms.h" 192515e8bbc5dca415c5a810b8d5c6aa6acec1903cDouglas Gilbert 20ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD 21ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARDstruct mdp5_plane { 22ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD struct drm_plane base; 23ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD const char *name; 24ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD 25d5c669f13759e790caf158d319641757768713beJean-Christophe PLAGNIOL-VILLARD enum mdp5_pipe pipe; 26ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD 27ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD uint32_t nformats; 28ee867d8eab1ffba8ace677eb6b62fba8c45d2e85Jean-Christophe PLAGNIOL-VILLARD uint32_t formats[32]; 29ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD 30ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD bool enabled; 31ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD}; 320d67c9e81351a2269f3ae0e8072cb1d463bf5bc6Douglas Gilbert#define to_mdp5_plane(x) container_of(x, struct mdp5_plane, base) 33ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD 34ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARDstatic struct mdp5_kms *get_kms(struct drm_plane *plane) 35ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD{ 36ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD struct msm_drm_private *priv = plane->dev->dev_private; 37ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD return to_mdp5_kms(to_mdp_kms(priv->kms)); 38655ff266998ae4b3c8e8565bf30f60ceebe39b54Ludovic Desroches} 39655ff266998ae4b3c8e8565bf30f60ceebe39b54Ludovic Desroches 40655ff266998ae4b3c8e8565bf30f60ceebe39b54Ludovic Desrochesstatic int mdp5_plane_update(struct drm_plane *plane, 41655ff266998ae4b3c8e8565bf30f60ceebe39b54Ludovic Desroches struct drm_crtc *crtc, struct drm_framebuffer *fb, 42655ff266998ae4b3c8e8565bf30f60ceebe39b54Ludovic Desroches int crtc_x, int crtc_y, 43ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD unsigned int crtc_w, unsigned int crtc_h, 4485594df2bad0dddb36aa8aa242f4d15e6f122f02Olof Johansson uint32_t src_x, uint32_t src_y, 458ac49e0485bb79223a111b366a3b1f5ec9148729Christian Daudt uint32_t src_w, uint32_t src_h) 463fcdc0555f5043eded6312efce14cd8dd66f30f8Olof Johansson{ 473fcdc0555f5043eded6312efce14cd8dd66f30f8Olof Johansson struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); 48b014487044161b83010a9cbe336dbc41d2c38a0bOlof Johansson 49b014487044161b83010a9cbe336dbc41d2c38a0bOlof Johansson mdp5_plane->enabled = true; 50b014487044161b83010a9cbe336dbc41d2c38a0bOlof Johansson 51360a0cab50414ee30924917159066e69ee4b38d3Rob Herring if (plane->fb) 52360a0cab50414ee30924917159066e69ee4b38d3Rob Herring drm_framebuffer_unreference(plane->fb); 539cd11c0c47b8690b47e7573311ce5c483cb344edLinus Torvalds 54765d012c2389cc0481f04dcccd3949f1ba0969baTomasz Figa drm_framebuffer_reference(fb); 55800974ac0420f8f81cd7ad4d33bdf179b890b282Dongjin Kim 5686666adc1e594a3e98407da21f5f2bac587ff0cfThomas Abraham return mdp5_plane_mode_set(plane, crtc, fb, 572107673e16e4a20a14fd25505fa1a81e273f9983Thomas Abraham crtc_x, crtc_y, crtc_w, crtc_h, 58e88d5ae61a00b602cdd6a6c07f9fe6fbcaad06d7Girish K S src_x, src_y, src_w, src_h); 595464ac4c259400740a212dd743f84f3f28465358Kukjin Kim} 6095e82941b73b4a8811299ad7b639157822c8c59dDoug Anderson 617e65df3899cef3193ec44a7870f9bdc1ee6af833Kukjin Kimstatic int mdp5_plane_disable(struct drm_plane *plane) 6234dcedfbf97bc1c91c20f341e4ff4f70e53a0644Chander Kashyap{ 637e65df3899cef3193ec44a7870f9bdc1ee6af833Kukjin Kim struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); 647d6ab9b8620bbca6718b36242113f4f069840641Rob Herring struct mdp5_kms *mdp5_kms = get_kms(plane); 657d6ab9b8620bbca6718b36242113f4f069840641Rob Herring enum mdp5_pipe pipe = mdp5_plane->pipe; 6617bfcd3adc2c2002c1fdf990640bc36aec6a90b3Linus Walleij int i; 6717bfcd3adc2c2002c1fdf990640bc36aec6a90b3Linus Walleij 68360a0cab50414ee30924917159066e69ee4b38d3Rob Herring DBG("%s: disable", mdp5_plane->name); 6998d4f2acb91ac4a839eab6b92f02f57986af2197Simon Guinot 700d0632f523fa040b307688ae421a1debf79af2d7Thomas Petazzoni /* update our SMP request to zero (release all our blks): */ 710d0632f523fa040b307688ae421a1debf79af2d7Thomas Petazzoni for (i = 0; i < pipe2nclients(pipe); i++) 7298d4f2acb91ac4a839eab6b92f02f57986af2197Simon Guinot mdp5_smp_request(mdp5_kms, pipe2client(pipe, i), 0); 73360a0cab50414ee30924917159066e69ee4b38d3Rob Herring 74b014487044161b83010a9cbe336dbc41d2c38a0bOlof Johansson /* TODO detaching now will cause us not to get the last 75360a0cab50414ee30924917159066e69ee4b38d3Rob Herring * vblank and mdp5_smp_commit().. so other planes will 76360a0cab50414ee30924917159066e69ee4b38d3Rob Herring * still see smp blocks previously allocated to us as 779b47a4fb7760fabfbbc33b7d7703454684f36782Willy Tarreau * in-use.. 78360a0cab50414ee30924917159066e69ee4b38d3Rob Herring */ 79360a0cab50414ee30924917159066e69ee4b38d3Rob Herring if (plane->crtc) 80b014487044161b83010a9cbe336dbc41d2c38a0bOlof Johansson mdp5_crtc_detach(plane->crtc, plane); 81ecee1e47ab42ba3907d6bde7b2981e1006382071Simon Guinot 82b014487044161b83010a9cbe336dbc41d2c38a0bOlof Johansson return 0; 83360a0cab50414ee30924917159066e69ee4b38d3Rob Herring} 84360a0cab50414ee30924917159066e69ee4b38d3Rob Herring 855492a1108bbd40e14a895c07b6a4952022e82f7cStefan Peterstatic void mdp5_plane_destroy(struct drm_plane *plane) 86f236f5aabe8ebd7824590ae82d701402ead237e7Arnaud Ebalard{ 87ecee1e47ab42ba3907d6bde7b2981e1006382071Simon Guinot struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); 88ca7d94524ab3554b08f13de91674d570cb4a09b6Simon Guinot 89ecee1e47ab42ba3907d6bde7b2981e1006382071Simon Guinot mdp5_plane_disable(plane); 907f9871d9d30f25891e0c4da4c6284d9e66e702f5Simon Guinot drm_plane_cleanup(plane); 91afcad884252b171ff6f2ac78eb43c2f5db612dd0Tero Jaasko 92ee514b381e17958fde5b99cba506f31ea6589c0bSimon Baatz kfree(mdp5_plane); 93ee514b381e17958fde5b99cba506f31ea6589c0bSimon Baatz} 94767fc1ea92f70b5a97d43b79c146c2bee3eb6e83Jason Cooper 95360a0cab50414ee30924917159066e69ee4b38d3Rob Herring/* helper to install properties which are common to planes and crtcs */ 96f17073a3aec601cb9aba6d8c1c6dbc8c6a919c07Nobuhiro Iwamatsuvoid mdp5_plane_install_properties(struct drm_plane *plane, 97f17073a3aec601cb9aba6d8c1c6dbc8c6a919c07Nobuhiro Iwamatsu struct drm_mode_object *obj) 984898de3d15d8ba34aa7a1b0f753a476d52ebdf92Barry Song{ 9985594df2bad0dddb36aa8aa242f4d15e6f122f02Olof Johansson // XXX 10085594df2bad0dddb36aa8aa242f4d15e6f122f02Olof Johansson} 101360a0cab50414ee30924917159066e69ee4b38d3Rob Herring 102e3e37bcab910a68616bc33145ed5c333825053acGregory CLEMENTint mdp5_plane_set_property(struct drm_plane *plane, 103491221451b9998cf182770f2b5f8b3a8b141dd81Florian Fainelli struct drm_property *property, uint64_t val) 104c7841473f7ecbff624809f31f36aab0df5041ef9Thomas Petazzoni{ 10519b85c086019e54c1976fdaf56e8923f7e568091Thomas Petazzoni // XXX 106568fc0a321a7f3ae1c3626a4f471d49ff005779cGregory CLEMENT return -EINVAL; 10719b85c086019e54c1976fdaf56e8923f7e568091Thomas Petazzoni} 1088ba472357a87503df2214ddc0270706ae34da4a1Shawn Guo 1098ba472357a87503df2214ddc0270706ae34da4a1Shawn Guostatic const struct drm_plane_funcs mdp5_plane_funcs = { 110860c06f6c0620307b595aacb3ead9c439e9dd785Fabio Estevam .update_plane = mdp5_plane_update, 1118ba472357a87503df2214ddc0270706ae34da4a1Shawn Guo .disable_plane = mdp5_plane_disable, 11200ba2459f6d5f9caee01cf5628df553ace50cbcdGwenhael Goavec-Merou .destroy = mdp5_plane_destroy, 1138ba472357a87503df2214ddc0270706ae34da4a1Shawn Guo .set_property = mdp5_plane_set_property, 11442a56fc6febad79f16a94391d89c617c140d6e7eAlexander Shiyan}; 115c05c1bf5739cb7adaa955503fc819d077bc46d25Alexander Shiyan 1168ba472357a87503df2214ddc0270706ae34da4a1Shawn Guovoid mdp5_plane_set_scanout(struct drm_plane *plane, 1171982d5b6c1b78363b5142eb0cb81c38d7604fc61Laurent Cans struct drm_framebuffer *fb) 118e910b45c9d6413c057fc0aaf8616683446bdda7dGwenhael Goavec-Merou{ 1199c9651cd7412032657e4949dd5cbdd8f1364befdFabio Estevam struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); 120360a0cab50414ee30924917159066e69ee4b38d3Rob Herring struct mdp5_kms *mdp5_kms = get_kms(plane); 121360a0cab50414ee30924917159066e69ee4b38d3Rob Herring enum mdp5_pipe pipe = mdp5_plane->pipe; 122051124e596869ddf3efa7a2dc2f8209401e55d09Marek Vasut uint32_t nplanes = drm_format_num_planes(fb->pixel_format); 123be3a568d77fac942bbc7fb5ed77963bc254e60ffSteffen Trumtrar uint32_t iova[4]; 124360a0cab50414ee30924917159066e69ee4b38d3Rob Herring int i; 125360a0cab50414ee30924917159066e69ee4b38d3Rob Herring 1261aa8b3e06f5fcc294b54fe2c35b2e34b09048e94Shawn Guo for (i = 0; i < nplanes; i++) { 1279a8d6d55f6989961298b995e3ef91eb90e034cf2Shawn Guo struct drm_gem_object *bo = msm_framebuffer_bo(fb, i); 12889b82915c4b5afa9e51e09636f7919bbb6f9cc1bFabio Estevam msm_gem_get_iova(bo, mdp5_kms->id, &iova[i]); 129360a0cab50414ee30924917159066e69ee4b38d3Rob Herring } 1303180f956668ee04d35d77b32a6a1be10fb251d9dChristian Hemp for (; i < 4; i++) 1315c70cb01b89895189025f8de8ee2823f516eab6aFabio Estevam iova[i] = 0; 132360a0cab50414ee30924917159066e69ee4b38d3Rob Herring 1338593a1a2e88a0b23d3bd626eee6519de9ee55938Pavel Machek mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_STRIDE_A(pipe), 134117ccd553a02a69aff41083f8b59a38927ccf002Shawn Guo MDP5_PIPE_SRC_STRIDE_A_P0(fb->pitches[0]) | 135e77b74ee6c4115a0fe1fdb673dbf25ffe1277205Jingchang Lu MDP5_PIPE_SRC_STRIDE_A_P1(fb->pitches[1])); 136e77b74ee6c4115a0fe1fdb673dbf25ffe1277205Jingchang Lu 137360a0cab50414ee30924917159066e69ee4b38d3Rob Herring mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_STRIDE_B(pipe), 138360a0cab50414ee30924917159066e69ee4b38d3Rob Herring MDP5_PIPE_SRC_STRIDE_B_P2(fb->pitches[2]) | 139360a0cab50414ee30924917159066e69ee4b38d3Rob Herring MDP5_PIPE_SRC_STRIDE_B_P3(fb->pitches[3])); 140a957fdca4feb7fbc51f9c7c6a152a86f35ca7751Julien Boibessot 141414b41536c4564db696d5fb18d8baf695491cd02Gwenhael Goavec-Merou mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC0_ADDR(pipe), iova[0]); 142360a0cab50414ee30924917159066e69ee4b38d3Rob Herring mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC1_ADDR(pipe), iova[1]); 143360a0cab50414ee30924917159066e69ee4b38d3Rob Herring mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC2_ADDR(pipe), iova[2]); 144e0f7d905242f5eedc4801ce588f7f588f4ec57cbMaxime Ripard mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC3_ADDR(pipe), iova[3]); 1455ae8d15f686f93d2ac60a7b16d8ddfbfdfc7c00fOlof Johansson 146ed138c368d95095de522db98b8b6929874bed403Brian Lilly plane->fb = fb; 147d75f3d92e86e65b3cb9725e65f7278cc303511dbBrian Lilly} 148360a0cab50414ee30924917159066e69ee4b38d3Rob Herring 149360a0cab50414ee30924917159066e69ee4b38d3Rob Herring/* NOTE: looks like if horizontal decimation is used (if we supported that) 150160d5f27605f5acac8f426d862e8f8a499eef2b5Marek Vasut * then the width used to calculate SMP block requirements is the post- 151360a0cab50414ee30924917159066e69ee4b38d3Rob Herring * decimated width. Ie. SMP buffering sits downstream of decimation (which 152f8635abd38776a413d1e84c79353693b8ecf45c9Linus Walleij * presumably happens during the dma from scanout buffer). 153d907849e0dbaeacb34e0a6a3b49ebeaf8c49355eDaniel Tang */ 154d907849e0dbaeacb34e0a6a3b49ebeaf8c49355eDaniel Tangstatic int request_smp_blocks(struct drm_plane *plane, uint32_t format, 155d907849e0dbaeacb34e0a6a3b49ebeaf8c49355eDaniel Tang uint32_t nplanes, uint32_t width) 15685594df2bad0dddb36aa8aa242f4d15e6f122f02Olof Johansson{ 157678fac41938299d33b980ad0e7b81438d3d88836Jon Hunter struct drm_device *dev = plane->dev; 1585a8095e9d02da19f3bab738e82c0520ecd62d6afJon Hunter struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); 1594bfe6341d4bfcb68c083b3109b6a4997cd287262Anil Kumar struct mdp5_kms *mdp5_kms = get_kms(plane); 16085594df2bad0dddb36aa8aa242f4d15e6f122f02Olof Johansson enum mdp5_pipe pipe = mdp5_plane->pipe; 16185594df2bad0dddb36aa8aa242f4d15e6f122f02Olof Johansson int i, hsub, nlines, nblks, ret; 16285594df2bad0dddb36aa8aa242f4d15e6f122f02Olof Johansson 163cb5e191e96953965aab8aa3bf4c0aee01faaaf79Javier Martinez Canillas hsub = drm_format_horz_chroma_subsampling(format); 1649ad1df2b15b0f1952a57c3407996450cc64bc976Javier Martinez Canillas 16585594df2bad0dddb36aa8aa242f4d15e6f122f02Olof Johansson /* different if BWC (compressed framebuffer?) enabled: */ 16630a6998ef4474b18d81d8c459f2cbd9e49ff0736Jon Hunter nlines = 2; 16700cbdce75b62a56bf3e6baca68b5ddb5474495a2Benoit Cousson 16800cbdce75b62a56bf3e6baca68b5ddb5474495a2Benoit Cousson for (i = 0, nblks = 0; i < nplanes; i++) { 16985594df2bad0dddb36aa8aa242f4d15e6f122f02Olof Johansson int n, fetch_stride, cpp; 17044b5b2d2d405c148545bef910d953e2323769a7cFlorian Vaussard 171fa63d037283a6bd0db96078d87192d1aaa073f3cSricharan R cpp = drm_format_plane_cpp(format, i); 172f0cfa981cec09e6e353295e0f8dc36bc10289996Vaibhav Hiremath fetch_stride = width * cpp / (i ? hsub : 1); 1737340dd530c5f72e63201953677b42c9e5fdb2b3dBenoit Cousson 17444b5b2d2d405c148545bef910d953e2323769a7cFlorian Vaussard n = DIV_ROUND_UP(fetch_stride * nlines, SMP_BLK_SIZE); 17544b5b2d2d405c148545bef910d953e2323769a7cFlorian Vaussard 1764730bcfb067a92bd446b4ffd149e0768572c7f19Afzal Mohammed /* for hw rev v1.00 */ 1774730bcfb067a92bd446b4ffd149e0768572c7f19Afzal Mohammed if (mdp5_kms->rev == 0) 17807f645df9ff2550749b806af626576d5ad418215Thomas Petazzoni n = roundup_pow_of_two(n); 17985594df2bad0dddb36aa8aa242f4d15e6f122f02Olof Johansson 180d3fed7bd60eb4a45afe43c6e8dfc592a30e7e33fFabio Baltieri DBG("%s[%d]: request %d SMP blocks", mdp5_plane->name, i, n); 181d3fed7bd60eb4a45afe43c6e8dfc592a30e7e33fFabio Baltieri ret = mdp5_smp_request(mdp5_kms, pipe2client(pipe, i), n); 182d3fed7bd60eb4a45afe43c6e8dfc592a30e7e33fFabio Baltieri if (ret) { 1831d8c269de0b4be9bd7ae8d719be927d759ed3647Linus Walleij dev_err(dev->dev, "Could not allocate %d SMP blocks: %d\n", 184d3fed7bd60eb4a45afe43c6e8dfc592a30e7e33fFabio Baltieri n, ret); 18535aca36450e6c3fb3b3fe9ea60a7c4689a219a87Heiko Stuebner return ret; 18685594df2bad0dddb36aa8aa242f4d15e6f122f02Olof Johansson } 18785594df2bad0dddb36aa8aa242f4d15e6f122f02Olof Johansson 18853e42c2974feaa269bc485267d0a4df0ef55e549Kuninori Morimoto nblks += n; 18976b92b4043f2303b443645b5609a8867e8a8b5d7Bastian Hecht } 19073d6a69e3b3ae168fcb8d797e427c1b5fe132a40Simon Horman 1913cc828fdb32281cc8166d3a40bee32b90ce3cad8Magnus Damm /* in success case, return total # of blocks allocated: */ 1920ce53cdc5c7e28f378e480363a0b0c2ed7e7eaf9Nobuhiro Iwamatsu return nblks; 193b8b82b2983e5b7bccca3a037c886e2aad86aaeeaSimon Horman} 19478ded16886f539830ed58d9bc043656c1785a082Magnus Damm 1950ce53cdc5c7e28f378e480363a0b0c2ed7e7eaf9Nobuhiro Iwamatsustatic void set_fifo_thresholds(struct drm_plane *plane, int nblks) 19690c294557d411100d3557bc2762a98a93f989430Dinh Nguyen{ 19790c294557d411100d3557bc2762a98a93f989430Dinh Nguyen struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); 198360a0cab50414ee30924917159066e69ee4b38d3Rob Herring struct mdp5_kms *mdp5_kms = get_kms(plane); 199360a0cab50414ee30924917159066e69ee4b38d3Rob Herring enum mdp5_pipe pipe = mdp5_plane->pipe; 200360a0cab50414ee30924917159066e69ee4b38d3Rob Herring uint32_t val; 201360a0cab50414ee30924917159066e69ee4b38d3Rob Herring 202e2eb69183ec4156eb814e67672e492bf902bbcd2Shiraz Hashim /* 1/4 of SMP pool that is being fetched */ 203e2eb69183ec4156eb814e67672e492bf902bbcd2Shiraz Hashim val = (nblks * SMP_ENTRIES_PER_BLK) / 4; 204360a0cab50414ee30924917159066e69ee4b38d3Rob Herring 205f1148dba64f3bf3a346e1eb7cdfac0e5f70660c8Srinivas Kandagatla mdp5_write(mdp5_kms, REG_MDP5_PIPE_REQPRIO_FIFO_WM_0(pipe), val * 1); 20640e3e6725370481b7b81d969dbde056f50d870aeSrinivas Kandagatla mdp5_write(mdp5_kms, REG_MDP5_PIPE_REQPRIO_FIFO_WM_1(pipe), val * 2); 20740e3e6725370481b7b81d969dbde056f50d870aeSrinivas Kandagatla mdp5_write(mdp5_kms, REG_MDP5_PIPE_REQPRIO_FIFO_WM_2(pipe), val * 3); 20840e3e6725370481b7b81d969dbde056f50d870aeSrinivas Kandagatla 209d34c671debe3d327424a9951a5c3a81065d0474dMaxime Ripard} 210d34c671debe3d327424a9951a5c3a81065d0474dMaxime Ripard 211d34c671debe3d327424a9951a5c3a81065d0474dMaxime Ripardint mdp5_plane_mode_set(struct drm_plane *plane, 212a9d281cab72cbb45fcde8be3e20b7494f573ac9dMaxime Ripard struct drm_crtc *crtc, struct drm_framebuffer *fb, 213d0f2677be5b49a1c1de59fe94faa96b7808be95fMaxime Ripard int crtc_x, int crtc_y, 21468136b105cbb798b13e9545b9952e568d04e347cMaxime Ripard unsigned int crtc_w, unsigned int crtc_h, 215360a0cab50414ee30924917159066e69ee4b38d3Rob Herring uint32_t src_x, uint32_t src_y, 216bf5fcc76d31418950b214542440d5de6e48c7998Lucas Stach uint32_t src_w, uint32_t src_h) 2175ae8d15f686f93d2ac60a7b16d8ddfbfdfc7c00fOlof Johansson{ 218360a0cab50414ee30924917159066e69ee4b38d3Rob Herring struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); 2195ae8d15f686f93d2ac60a7b16d8ddfbfdfc7c00fOlof Johansson struct mdp5_kms *mdp5_kms = get_kms(plane); 220360a0cab50414ee30924917159066e69ee4b38d3Rob Herring enum mdp5_pipe pipe = mdp5_plane->pipe; 2215ae8d15f686f93d2ac60a7b16d8ddfbfdfc7c00fOlof Johansson const struct mdp_format *format; 222360a0cab50414ee30924917159066e69ee4b38d3Rob Herring uint32_t nplanes, config = 0; 223360a0cab50414ee30924917159066e69ee4b38d3Rob Herring uint32_t phasex_step = 0, phasey_step = 0; 224360a0cab50414ee30924917159066e69ee4b38d3Rob Herring uint32_t hdecm = 0, vdecm = 0; 225d7df69fe256587c5f78961c4d69a95d4a5b12c71Bryan Wu int i, nblks; 2265ae8d15f686f93d2ac60a7b16d8ddfbfdfc7c00fOlof Johansson 227a71c03e7fd6a4027f750e2951830669244a8dad6Hiroshi Doyu nplanes = drm_format_num_planes(fb->pixel_format); 2289f19cbef99a29669a1224e3ba6ba505152247517Hiroshi Doyu 2299f19cbef99a29669a1224e3ba6ba505152247517Hiroshi Doyu /* bad formats should already be rejected: */ 230cc8e9ad88487004372cae87718ff593d0a2fdc3aRob Herring if (WARN_ON(nplanes > pipe2nclients(pipe))) 231cc8e9ad88487004372cae87718ff593d0a2fdc3aRob Herring return -EINVAL; 232978577ea21fb05c12511c25b71e493859e36892fLinus Walleij 233360a0cab50414ee30924917159066e69ee4b38d3Rob Herring /* src values are in Q16 fixed point, convert to integer: */ 234360a0cab50414ee30924917159066e69ee4b38d3Rob Herring src_x = src_x >> 16; 235360a0cab50414ee30924917159066e69ee4b38d3Rob Herring src_y = src_y >> 16; 236cc3d7f70c37641ca417f4c02ecaf12cd9772ffa6Stefano Stabellini src_w = src_w >> 16; 237cc3d7f70c37641ca417f4c02ecaf12cd9772ffa6Stefano Stabellini src_h = src_h >> 16; 238ed304be1b222398cd15954724e95787bb42e3b37Tony Prisk 239ed304be1b222398cd15954724e95787bb42e3b37Tony Prisk DBG("%s: FB[%u] %u,%u,%u,%u -> CRTC[%u] %d,%d,%u,%u", mdp5_plane->name, 240def4d6c044ea1f5f58ed6d422e6797fb0b1cfb63Tony Prisk fb->base.id, src_x, src_y, src_w, src_h, 2414606c48051db62db14756e1085fe0f8821a0e116Tony Prisk crtc->base.id, crtc_x, crtc_y, crtc_w, crtc_h); 242def4d6c044ea1f5f58ed6d422e6797fb0b1cfb63Tony Prisk 2434bda2670e4759b99f725176dd31caa612ea098b6Soren Brinkmann /* 24450dbb4cfbc264b074759e8fb5d8e0c0496a1b072Soren Brinkmann * Calculate and request required # of smp blocks: 24550dbb4cfbc264b074759e8fb5d8e0c0496a1b072Soren Brinkmann */ 246360a0cab50414ee30924917159066e69ee4b38d3Rob Herring nblks = request_smp_blocks(plane, fb->pixel_format, nplanes, src_w); 247499cd8298628eeabf0eb5eb6525d4faa0eec80d8Grant Likely if (nblks < 0) 2481ab3681271c84b7f926be9ae3be1d769b7e933e9Stephen Warren return nblks; 249360a0cab50414ee30924917159066e69ee4b38d3Rob Herring 250499cd8298628eeabf0eb5eb6525d4faa0eec80d8Grant Likely /* 251499cd8298628eeabf0eb5eb6525d4faa0eec80d8Grant Likely * Currently we update the hw for allocations/requests immediately, 252499cd8298628eeabf0eb5eb6525d4faa0eec80d8Grant Likely * but once atomic modeset/pageflip is in place, the allocation 253499cd8298628eeabf0eb5eb6525d4faa0eec80d8Grant Likely * would move into atomic->check_plane_state(), while updating the 254499cd8298628eeabf0eb5eb6525d4faa0eec80d8Grant Likely * hw would remain here: 255499cd8298628eeabf0eb5eb6525d4faa0eec80d8Grant Likely */ 256499cd8298628eeabf0eb5eb6525d4faa0eec80d8Grant Likely for (i = 0; i < pipe2nclients(pipe); i++) 257 mdp5_smp_configure(mdp5_kms, pipe2client(pipe, i)); 258 259 if (src_w != crtc_w) { 260 config |= MDP5_PIPE_SCALE_CONFIG_SCALEX_EN; 261 /* TODO calc phasex_step, hdecm */ 262 } 263 264 if (src_h != crtc_h) { 265 config |= MDP5_PIPE_SCALE_CONFIG_SCALEY_EN; 266 /* TODO calc phasey_step, vdecm */ 267 } 268 269 mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_IMG_SIZE(pipe), 270 MDP5_PIPE_SRC_IMG_SIZE_WIDTH(src_w) | 271 MDP5_PIPE_SRC_IMG_SIZE_HEIGHT(src_h)); 272 273 mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_SIZE(pipe), 274 MDP5_PIPE_SRC_SIZE_WIDTH(src_w) | 275 MDP5_PIPE_SRC_SIZE_HEIGHT(src_h)); 276 277 mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_XY(pipe), 278 MDP5_PIPE_SRC_XY_X(src_x) | 279 MDP5_PIPE_SRC_XY_Y(src_y)); 280 281 mdp5_write(mdp5_kms, REG_MDP5_PIPE_OUT_SIZE(pipe), 282 MDP5_PIPE_OUT_SIZE_WIDTH(crtc_w) | 283 MDP5_PIPE_OUT_SIZE_HEIGHT(crtc_h)); 284 285 mdp5_write(mdp5_kms, REG_MDP5_PIPE_OUT_XY(pipe), 286 MDP5_PIPE_OUT_XY_X(crtc_x) | 287 MDP5_PIPE_OUT_XY_Y(crtc_y)); 288 289 mdp5_plane_set_scanout(plane, fb); 290 291 format = to_mdp_format(msm_framebuffer_format(fb)); 292 293 mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_FORMAT(pipe), 294 MDP5_PIPE_SRC_FORMAT_A_BPC(format->bpc_a) | 295 MDP5_PIPE_SRC_FORMAT_R_BPC(format->bpc_r) | 296 MDP5_PIPE_SRC_FORMAT_G_BPC(format->bpc_g) | 297 MDP5_PIPE_SRC_FORMAT_B_BPC(format->bpc_b) | 298 COND(format->alpha_enable, MDP5_PIPE_SRC_FORMAT_ALPHA_ENABLE) | 299 MDP5_PIPE_SRC_FORMAT_CPP(format->cpp - 1) | 300 MDP5_PIPE_SRC_FORMAT_UNPACK_COUNT(format->unpack_count - 1) | 301 COND(format->unpack_tight, MDP5_PIPE_SRC_FORMAT_UNPACK_TIGHT) | 302 MDP5_PIPE_SRC_FORMAT_NUM_PLANES(nplanes - 1) | 303 MDP5_PIPE_SRC_FORMAT_CHROMA_SAMP(CHROMA_RGB)); 304 305 mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_UNPACK(pipe), 306 MDP5_PIPE_SRC_UNPACK_ELEM0(format->unpack[0]) | 307 MDP5_PIPE_SRC_UNPACK_ELEM1(format->unpack[1]) | 308 MDP5_PIPE_SRC_UNPACK_ELEM2(format->unpack[2]) | 309 MDP5_PIPE_SRC_UNPACK_ELEM3(format->unpack[3])); 310 311 mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_OP_MODE(pipe), 312 MDP5_PIPE_SRC_OP_MODE_BWC(BWC_LOSSLESS)); 313 314 /* not using secure mode: */ 315 mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_ADDR_SW_STATUS(pipe), 0); 316 317 mdp5_write(mdp5_kms, REG_MDP5_PIPE_SCALE_PHASE_STEP_X(pipe), phasex_step); 318 mdp5_write(mdp5_kms, REG_MDP5_PIPE_SCALE_PHASE_STEP_Y(pipe), phasey_step); 319 mdp5_write(mdp5_kms, REG_MDP5_PIPE_DECIMATION(pipe), 320 MDP5_PIPE_DECIMATION_VERT(vdecm) | 321 MDP5_PIPE_DECIMATION_HORZ(hdecm)); 322 mdp5_write(mdp5_kms, REG_MDP5_PIPE_SCALE_CONFIG(pipe), 323 MDP5_PIPE_SCALE_CONFIG_SCALEX_MIN_FILTER(SCALE_FILTER_NEAREST) | 324 MDP5_PIPE_SCALE_CONFIG_SCALEY_MIN_FILTER(SCALE_FILTER_NEAREST) | 325 MDP5_PIPE_SCALE_CONFIG_SCALEX_CR_FILTER(SCALE_FILTER_NEAREST) | 326 MDP5_PIPE_SCALE_CONFIG_SCALEY_CR_FILTER(SCALE_FILTER_NEAREST) | 327 MDP5_PIPE_SCALE_CONFIG_SCALEX_MAX_FILTER(SCALE_FILTER_NEAREST) | 328 MDP5_PIPE_SCALE_CONFIG_SCALEY_MAX_FILTER(SCALE_FILTER_NEAREST)); 329 330 set_fifo_thresholds(plane, nblks); 331 332 /* TODO detach from old crtc (if we had more than one) */ 333 mdp5_crtc_attach(crtc, plane); 334 335 return 0; 336} 337 338void mdp5_plane_complete_flip(struct drm_plane *plane) 339{ 340 struct mdp5_kms *mdp5_kms = get_kms(plane); 341 enum mdp5_pipe pipe = to_mdp5_plane(plane)->pipe; 342 int i; 343 344 for (i = 0; i < pipe2nclients(pipe); i++) 345 mdp5_smp_commit(mdp5_kms, pipe2client(pipe, i)); 346} 347 348enum mdp5_pipe mdp5_plane_pipe(struct drm_plane *plane) 349{ 350 struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); 351 return mdp5_plane->pipe; 352} 353 354/* initialize plane */ 355struct drm_plane *mdp5_plane_init(struct drm_device *dev, 356 enum mdp5_pipe pipe, bool private_plane) 357{ 358 struct drm_plane *plane = NULL; 359 struct mdp5_plane *mdp5_plane; 360 int ret; 361 362 mdp5_plane = kzalloc(sizeof(*mdp5_plane), GFP_KERNEL); 363 if (!mdp5_plane) { 364 ret = -ENOMEM; 365 goto fail; 366 } 367 368 plane = &mdp5_plane->base; 369 370 mdp5_plane->pipe = pipe; 371 mdp5_plane->name = pipe2name(pipe); 372 373 mdp5_plane->nformats = mdp5_get_formats(pipe, mdp5_plane->formats, 374 ARRAY_SIZE(mdp5_plane->formats)); 375 376 drm_plane_init(dev, plane, 0xff, &mdp5_plane_funcs, 377 mdp5_plane->formats, mdp5_plane->nformats, 378 private_plane); 379 380 mdp5_plane_install_properties(plane, &plane->base); 381 382 return plane; 383 384fail: 385 if (plane) 386 mdp5_plane_destroy(plane); 387 388 return ERR_PTR(ret); 389} 390