[PATCH] drm/amd/powerplay: fix memdup.cocci warnings
From: kbuild test robot Simplify the code a bit by using kmemdup instead of kzalloc and memcpy. Generated by: scripts/coccinelle/api/memdup.cocci Fixes: 76760fe3c00d ("drm/amd/powerplay: add function to store overdrive information for smu11") CC: Likun Gao Signed-off-by: kbuild test robot Signed-off-by: Julia Lawall --- tree: git://people.freedesktop.org/~agd5f/linux.git drm-next-5.2-wip head: 25752e1fc83e9f983b11d680fc7bfc129b4eaae6 commit: 76760fe3c00d04f25cc1a6115294310d4effeb77 [161/226] drm/amd/powerplay: add function to store overdrive information for smu11 :: branch date: 6 hours ago :: commit date: 6 hours ago vega20_ppt.c | 24 +--- 1 file changed, 9 insertions(+), 15 deletions(-) --- a/drivers/gpu/drm/amd/amdgpu/../powerplay/vega20_ppt.c +++ b/drivers/gpu/drm/amd/amdgpu/../powerplay/vega20_ppt.c @@ -173,14 +173,12 @@ static int vega20_setup_od8_information( if (table_context->od_feature_capabilities) return -EINVAL; - table_context->od_feature_capabilities = kzalloc(od_feature_array_size, GFP_KERNEL); + table_context->od_feature_capabilities = kmemdup(&powerplay_table->OverDrive8Table.ODFeatureCapabilities, + od_feature_array_size, +GFP_KERNEL); if (!table_context->od_feature_capabilities) return -ENOMEM; - memcpy(table_context->od_feature_capabilities, - &powerplay_table->OverDrive8Table.ODFeatureCapabilities, - od_feature_array_size); - /* Setup correct ODSettingCount, and store ODSettingArray from * powerplay table to od_settings_max and od_setting_min */ od_setting_count = @@ -194,7 +192,9 @@ static int vega20_setup_od8_information( if (table_context->od_settings_max) return -EINVAL; - table_context->od_settings_max = kzalloc(od_setting_array_size, GFP_KERNEL); + table_context->od_settings_max = kmemdup(&powerplay_table->OverDrive8Table.ODSettingsMax, +od_setting_array_size, +GFP_KERNEL); if (!table_context->od_settings_max) { kfree(table_context->od_feature_capabilities); @@ -202,14 +202,12 @@ static int vega20_setup_od8_information( return -ENOMEM; } - memcpy(table_context->od_settings_max, - &powerplay_table->OverDrive8Table.ODSettingsMax, - od_setting_array_size); - if (table_context->od_settings_min) return -EINVAL; - table_context->od_settings_min = kzalloc(od_setting_array_size, GFP_KERNEL); + table_context->od_settings_min = kmemdup(&powerplay_table->OverDrive8Table.ODSettingsMin, +od_setting_array_size, +GFP_KERNEL); if (!table_context->od_settings_min) { kfree(table_context->od_feature_capabilities); @@ -218,10 +216,6 @@ static int vega20_setup_od8_information( table_context->od_settings_max = NULL; return -ENOMEM; } - - memcpy(table_context->od_settings_min, - &powerplay_table->OverDrive8Table.ODSettingsMin, - od_setting_array_size); } return 0; ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[radeon-alex:drm-next-5.2-wip 214/226] drivers/gpu/drm/amd/amdgpu/../powerplay/vega20_ppt.c:1204:3-9: preceding lock on line 1065 (fwd)
Hello, It looks like line 1204 needs a break rather than a return, like in the aborts from the other cases. julia -- Forwarded message -- Date: Sat, 2 Mar 2019 14:36:31 +0800 From: kbuild test robot To: kbu...@01.org Cc: Julia Lawall Subject: [radeon-alex:drm-next-5.2-wip 214/226] drivers/gpu/drm/amd/amdgpu/../powerplay/vega20_ppt.c:1204:3-9: preceding lock on line 1065 CC: kbuild-...@01.org CC: dri-devel@lists.freedesktop.org TO: Likun Gao CC: Alex Deucher CC: Gui Chengming tree: git://people.freedesktop.org/~agd5f/linux.git drm-next-5.2-wip head: 25752e1fc83e9f983b11d680fc7bfc129b4eaae6 commit: e85bae378020046f53f18a61ac6bd5cdb798a079 [214/226] drm/amd/powerplay: support sysfs to set/get pcie :: branch date: 7 hours ago :: commit date: 7 hours ago >> drivers/gpu/drm/amd/amdgpu/../powerplay/vega20_ppt.c:1204:3-9: preceding >> lock on line 1065 git remote add radeon-alex git://people.freedesktop.org/~agd5f/linux.git git remote update radeon-alex git checkout e85bae378020046f53f18a61ac6bd5cdb798a079 vim +1204 drivers/gpu/drm/amd/amdgpu/../powerplay/vega20_ppt.c 1d5da59b Likun Gao 2019-01-07 1050 7b0f60df Likun Gao 2019-01-07 1051 static int vega20_force_clk_levels(struct smu_context *smu, 7b0f60df Likun Gao 2019-01-07 1052 enum pp_clock_type type, uint32_t mask) 7b0f60df Likun Gao 2019-01-07 1053 { 7b0f60df Likun Gao 2019-01-07 1054 struct vega20_dpm_table *dpm_table; 7b0f60df Likun Gao 2019-01-07 1055 struct vega20_single_dpm_table *single_dpm_table; db129665 Likun Gao 2019-02-20 1056 uint32_t soft_min_level, soft_max_level, hard_min_level; 72ee8378 Likun Gao 2019-01-23 1057 struct smu_dpm_context *smu_dpm = &smu->smu_dpm; 72ee8378 Likun Gao 2019-01-23 1058 int ret = 0; 72ee8378 Likun Gao 2019-01-23 1059 72ee8378 Likun Gao 2019-01-23 1060 if (smu_dpm->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) { 72ee8378 Likun Gao 2019-01-23 1061 pr_info("force clock level is for dpm manual mode only.\n"); 72ee8378 Likun Gao 2019-01-23 1062 return -EINVAL; 72ee8378 Likun Gao 2019-01-23 1063 } 72ee8378 Likun Gao 2019-01-23 1064 72ee8378 Likun Gao 2019-01-23 @1065 mutex_lock(&(smu->mutex)); 7b0f60df Likun Gao 2019-01-07 1066 7b0f60df Likun Gao 2019-01-07 1067 soft_min_level = mask ? (ffs(mask) - 1) : 0; 7b0f60df Likun Gao 2019-01-07 1068 soft_max_level = mask ? (fls(mask) - 1) : 0; 7b0f60df Likun Gao 2019-01-07 1069 7b0f60df Likun Gao 2019-01-07 1070 dpm_table = smu->smu_dpm.dpm_context; 7b0f60df Likun Gao 2019-01-07 1071 7b0f60df Likun Gao 2019-01-07 1072 switch (type) { 7b0f60df Likun Gao 2019-01-07 1073 case PP_SCLK: 7b0f60df Likun Gao 2019-01-07 1074 single_dpm_table = &(dpm_table->gfx_table); 7b0f60df Likun Gao 2019-01-07 1075 7b0f60df Likun Gao 2019-01-07 1076 if (soft_max_level >= single_dpm_table->count) { 7b0f60df Likun Gao 2019-01-07 1077 pr_err("Clock level specified %d is over max allowed %d\n", 7b0f60df Likun Gao 2019-01-07 1078 soft_max_level, single_dpm_table->count - 1); 72ee8378 Likun Gao 2019-01-23 1079 ret = -EINVAL; 72ee8378 Likun Gao 2019-01-23 1080 break; 7b0f60df Likun Gao 2019-01-07 1081 } 7b0f60df Likun Gao 2019-01-07 1082 7b0f60df Likun Gao 2019-01-07 1083 single_dpm_table->dpm_state.soft_min_level = 7b0f60df Likun Gao 2019-01-07 1084 single_dpm_table->dpm_levels[soft_min_level].value; 7b0f60df Likun Gao 2019-01-07 1085 single_dpm_table->dpm_state.soft_max_level = 7b0f60df Likun Gao 2019-01-07 1086 single_dpm_table->dpm_levels[soft_max_level].value; 7b0f60df Likun Gao 2019-01-07 1087 db129665 Likun Gao 2019-02-20 1088 ret = vega20_upload_dpm_level(smu, false, FEATURE_DPM_GFXCLK_MASK); 7b0f60df Likun Gao 2019-01-07 1089 if (ret) { 7b0f60df Likun Gao 2019-01-07 1090 pr_err("Failed to upload boot level to lowest!\n"); 72ee8378 Likun Gao 2019-01-23 1091 break; 7b0f60df Likun Gao 2019-01-07 1092 } 7b0f60df Likun Gao 2019-01-07 1093 db129665 Likun Gao 2019-02-20 1094 ret = vega20_upload_dpm_level(smu, true, FEATURE_DPM_GFXCLK_MASK); 72ee8378 Likun Gao 2019-01-23 1095 if (ret) 7b0f60df Likun Gao 2019-01-07 1096 pr_err("Failed to upload dpm max level to highest!\n"); 7b0f60df Likun Gao 2019-01-07 1097 7b0f60df Likun Gao 2019-01-07 1098 break; 7b0f60df Likun Gao 2019-01-07 1099 7b0f60df Likun Gao 2019-01-07 1100 case PP_MCLK: 7b0f60df Likun Gao 2019-01-07 1101 single_dpm_table = &(dpm_table->mem_table); 7b0f60df Likun Gao 2019-01-07 1102 7b0f60df Likun Gao 2019-01-07 1103 if (soft_max_level >= single_dpm_table->count) { 7b0f60df Likun Gao
Re: [PATCH v3 2/2] drm/lima: driver for ARM Mali4xx GPUs
> > +static struct lima_fence *lima_fence_create(struct lima_sched_pipe *pipe) > > +{ > > + struct lima_fence *fence; > > + > > + fence = kmem_cache_zalloc(lima_fence_slab, GFP_KERNEL); > > Out of curiosity, what is the benefit of using a separate slab here? > If this is beneficial, then other drivers should do this too and it > should be common. Otherwise, it adds some complexity. fence is pretty frequently alloc free struct, so make it a slab. And it's used in get/put pattern, so may live longer than embedded struct. This is referenced from amdgpu driver. > > And maybe the slab should be initialzed in probe rather than module_init. > Either way is OK. But live in module init is easier not to init twice for two devices. > > +int lima_vm_bo_add(struct lima_vm *vm, struct lima_bo *bo, bool create) > > +{ > > + struct lima_bo_va *bo_va; > > + int err; > > + > > + mutex_lock(&bo->lock); > > + > > + bo_va = lima_vm_bo_find(vm, bo); > > + if (bo_va) { > > + bo_va->ref_count++; > > + mutex_unlock(&bo->lock); > > + return 0; > > + } > > + > > + /* should not create new bo_va if not asked by caller */ > > + if (!create) { > > + mutex_unlock(&bo->lock); > > + return -ENOENT; > > + } > > + > > + bo_va = kzalloc(sizeof(*bo_va), GFP_KERNEL); > > + if (!bo_va) { > > + err = -ENOMEM; > > + goto err_out0; > > + } > > + > > + bo_va->vm = vm; > > + bo_va->ref_count = 1; > > + > > + mutex_lock(&vm->lock); > > + > > + err = drm_mm_insert_node(&vm->mm, &bo_va->node, bo->gem.size); > > + if (err) > > + goto err_out1; > > + > > + err = lima_vm_map_page_table(vm, bo->pages_dma_addr, > > bo_va->node.start, > > +bo_va->node.start + bo_va->node.size - > > 1); > > + if (err) > > + goto err_out2; > > + > > + mutex_unlock(&vm->lock); > > + > > + list_add_tail(&bo_va->list, &bo->va); > > So you can have 1 BO at multiple VAs? Is that really needed? > Actually 1 BO can't have multi VA in single VM, but one VA in each VM. When a BO is exported/imported between two process, i.e. xserver and client, two processes have different VM, so can't make sure it can be mapped at the same place. Regards, Qiang ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: 2019 X.Org Board of Directors Elections Nomination period is NOW
The nomination period is now closed. We'll announce nominees March 7. Note also that the membership deadline is March 7. If you haven't signed-up to be a member and would like to do so there's only 6 more days left. Harry On 2019-02-14 5:27 p.m., Wentland, Harry wrote: > Since we haven't seen an onslaught of nominations we've decided to extend the > nomination period for another two weeks. Please consider nominating yourself > or anyone else you think would be a suitable candidate. This is your chance > to help steer the future of X.Org and serve the community. > > Updated election schedule (if no further delays): > Jan 31 - nomination period begins > Feb 28 - extended nomination period ends > Mar 7 - publish candidates, membership deadline > Mar 14 - election period begins > Mar 28 - election period ends > > Harry > > On 2019-02-11 10:38 a.m., Wentland, Harry wrote: >> So far we've received a couple of nominations for four open spots. The >> official nomination period ends this Thursday. Please let us know if you'd >> like to nominate someone including yourself. >> >> Harry >> >> On 2019-01-31 5:08 p.m., Wentland, Harry wrote: >>> We are seeking nominations for candidates for election to the X.Org >>> Foundation Board of Directors. All X.Org Foundation members are eligible >>> for election to the board. >>> >>> Nominations for the 2019 election are now open and will remain open until >>> 23:59 UTC on 14 February 2019. >>> >>> The Board consists of directors elected from the membership. Each year, an >>> election is held to bring the total number of directors to eight. The four >>> members receiving the highest vote totals will serve as directors for two >>> year terms. >>> >>> The directors who received two year terms starting in 2018 were Keith >>> Packard, Bryce Harrington, Eric Anholt, and Harry Wentland. They will >>> continue to serve until their term ends in 2020. Current directors whose >>> term expires in 2019 are Rob Clark, Martin Peres, Taylor Campbell and >>> Daniel Vetter. >>> >>> A director is expected to participate in the fortnightly IRC meeting to >>> discuss current business and to attend the annual meeting of the X.Org >>> Foundation, which will be held at a location determined in advance by the >>> Board of Directors. >>> >>> A member may nominate themselves or any other member they feel is >>> qualified. Nominations should be sent to the Election Committee at >>> elections at x.org. >>> >>> Nominees shall be required to be current members of the X.Org Foundation, >>> and submit a personal statement of up to 200 words that will be provided to >>> prospective voters. The collected statements, along with the statement of >>> contribution to the X.Org Foundation in the member's account page on >>> http://members.x.org, will be made available to all voters to help them >>> make their voting decisions. >>> >>> Nominations, membership applications or renewals and completed personal >>> statements must be received no later than 23:59 UTC on 14 February 2019. >>> >>> The slate of candidates will be published 21 February 2019 and candidate >>> Q&A will begin then. The deadline for Xorg membership applications and >>> renewals is 21 February 2019. >>> >>> Cheers, Harry Wentland, on behalf of the X.Org BoD >>> >>> >>> >>> >>> ___ >>> memb...@foundation.x.org: X.Org Foundation Members >>> Archives: https://foundation.x.org/cgi-bin/mailman/private/members >>> Info: https://foundation.x.org/cgi-bin/mailman/listinfo/members >>> >> ___ >> memb...@foundation.x.org: X.Org Foundation Members >> Archives: https://foundation.x.org/cgi-bin/mailman/private/members >> Info: https://foundation.x.org/cgi-bin/mailman/listinfo/members >> > ___ > memb...@foundation.x.org: X.Org Foundation Members > Archives: https://foundation.x.org/cgi-bin/mailman/private/members > Info: https://foundation.x.org/cgi-bin/mailman/listinfo/members > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [git pull] drm fixes for 5.0 final
The pull request you sent on Fri, 1 Mar 2019 15:40:01 +1000: > git://anongit.freedesktop.org/drm/drm tags/drm-fixes-2019-03-01 has been merged into torvalds/linux.git: https://git.kernel.org/torvalds/c/6357c8127bea35c52085a0ae0f97e73de2419825 Thank you! -- Deet-doot-dot, I am a bot. https://korg.wiki.kernel.org/userdoc/prtracker ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/amdgpu/powerplay: Fix missing break in switch statement
On 3/1/19 5:54 PM, Alex Deucher wrote: > On Fri, Mar 1, 2019 at 4:51 PM Gustavo A. R. Silva > wrote: >> >> Add missing break statement in order to prevent the code from falling >> through to case SMU_Discrete_DpmTable. >> >> This bug was found thanks to the ongoing efforts to enable >> -Wimplicit-fallthrough. >> >> Fixes: 34a564eaf528 ("drm/amd/powerplay: implement fw image related smum >> interface for Polaris.") >> Cc: sta...@vger.kernel.org >> Signed-off-by: Gustavo A. R. Silva > > Already fixed: > https://cgit.freedesktop.org/~agd5f/linux/commit/?h=drm-next-5.2-wip&id=6feaa4194c18578623565017f95d1b2f6b243567 > Awesome. :) I was looking for that link, but I didn't find it. That's why I sent this patch. Happy to see it is fixed now. Thanks, Alex. -- Gustavo ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/amdgpu/powerplay: Fix missing break in switch statement
On Fri, Mar 1, 2019 at 4:51 PM Gustavo A. R. Silva wrote: > > Add missing break statement in order to prevent the code from falling > through to case SMU_Discrete_DpmTable. > > This bug was found thanks to the ongoing efforts to enable > -Wimplicit-fallthrough. > > Fixes: 34a564eaf528 ("drm/amd/powerplay: implement fw image related smum > interface for Polaris.") > Cc: sta...@vger.kernel.org > Signed-off-by: Gustavo A. R. Silva Already fixed: https://cgit.freedesktop.org/~agd5f/linux/commit/?h=drm-next-5.2-wip&id=6feaa4194c18578623565017f95d1b2f6b243567 Alex > --- > drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c > b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c > index 52abca065764..222fb79d319e 100644 > --- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c > +++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c > @@ -2330,6 +2330,7 @@ static uint32_t polaris10_get_offsetof(uint32_t type, > uint32_t member) > case DRAM_LOG_BUFF_SIZE: > return offsetof(SMU74_SoftRegisters, > DRAM_LOG_BUFF_SIZE); > } > + break; > case SMU_Discrete_DpmTable: > switch (member) { > case UvdBootLevel: > -- > 2.21.0 > > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/amdgpu/gfx_v8_0: Mark expected switch fall-through
On Fri, Mar 1, 2019 at 3:58 PM Gustavo A. R. Silva wrote: > > In preparation to enabling -Wimplicit-fallthrough, mark switch > cases where we are expecting to fall through. > > This patch fixes the following warning: > > drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c: In function > ‘gfx_v8_0_tiling_mode_table_init’: > ./include/linux/device.h:1487:2: warning: this statement may fall through > [-Wimplicit-fallthrough=] > _dev_warn(dev, dev_fmt(fmt), ##__VA_ARGS__) > ^~~ > drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c:3236:3: note: in expansion of macro > ‘dev_warn’ >dev_warn(adev->dev, >^~~~ > drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c:3240:2: note: here > case CHIP_CARRIZO: > ^~~~ > > Warning level 3 was used: -Wimplicit-fallthrough=3 > > This patch is part of the ongoing efforts to enable > -Wimplicit-fallthrough. > > Signed-off-by: Gustavo A. R. Silva Applied. thanks! Alex > --- > drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c > b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c > index b8e50a34bdb3..02955e6e9dd9 100644 > --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c > @@ -3236,6 +3236,7 @@ static void gfx_v8_0_tiling_mode_table_init(struct > amdgpu_device *adev) > dev_warn(adev->dev, > "Unknown chip type (%d) in function > gfx_v8_0_tiling_mode_table_init() falling through to CHIP_CARRIZO\n", > adev->asic_type); > + /* fall through */ > > case CHIP_CARRIZO: > modearray[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | > -- > 2.21.0 > > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/ttm: Fix spelling of "KiB"
On Fri, Mar 1, 2019 at 3:31 AM Jakub Wilk wrote: > > The symbol for binary prefix kibi is "Ki", with uppercase K. > (In contrast, the symbol for decimal kilo is lowercase "k".) > > Signed-off-by: Jakub Wilk Applied. thanks! Alex > --- > drivers/gpu/drm/ttm/ttm_memory.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/ttm/ttm_memory.c > b/drivers/gpu/drm/ttm/ttm_memory.c > index f1567c353b54..53130cd9e935 100644 > --- a/drivers/gpu/drm/ttm/ttm_memory.c > +++ b/drivers/gpu/drm/ttm/ttm_memory.c > @@ -81,7 +81,7 @@ static void ttm_mem_zone_kobj_release(struct kobject *kobj) > struct ttm_mem_zone *zone = > container_of(kobj, struct ttm_mem_zone, kobj); > > - pr_info("Zone %7s: Used memory at exit: %llu kiB\n", > + pr_info("Zone %7s: Used memory at exit: %llu KiB\n", > zone->name, (unsigned long long)zone->used_mem >> 10); > kfree(zone); > } > @@ -448,7 +448,7 @@ int ttm_mem_global_init(struct ttm_mem_global *glob) > #endif > for (i = 0; i < glob->num_zones; ++i) { > zone = glob->zones[i]; > - pr_info("Zone %7s: Available graphics memory: %llu kiB\n", > + pr_info("Zone %7s: Available graphics memory: %llu KiB\n", > zone->name, (unsigned long long)zone->max_mem >> 10); > } > ttm_page_alloc_init(glob, glob->zone_kernel->max_mem/(2*PAGE_SIZE)); > -- > 2.20.1 > > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [EARLY RFC][PATCH] dma-buf: Add dma-buf heaps framework
On Thu, Feb 28, 2019 at 9:21 AM Andrew F. Davis wrote: > > On 2/27/19 3:55 PM, John Stultz wrote: > > On Wed, Feb 27, 2019 at 8:38 AM Andrew F. Davis wrote: > >> > >> We can always add back the free op, the alternative is to have the heap > >> export the fd. > >> > >> I'm not sure either is needed though, when we > >> dma_buf_put(buffer->dmabuf) on the error path it should trigger the > >> release op, and that can cleanup the allocations in the heap. > > > > Good point, but I worry that's a bit subtle. > > > > Also doing the stuff with the helpers where we have to register a free > > callback is kind of ugly, and I personally like the symmetry of having > > free hooks if we have allocation hooks (even if the dmabuf release > > hook initiates the free call). > > > > I do like the symmetry of a free op, just not sure how or what should be > done in it that couldn't be taken care of in the dmabuf.release op.. I came around on this. I've reworked the top core allocate function to basically just return the result of heap->allocate(), which now returns the dmabuf fd. Any error handling/freeing is then kept to the heap allocate function and we don't need a heap free op. I still have to have a free callback for the helper functions, but I may do some more cleanup there. thanks -john ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/amd/powerplay: fix semicolon code style issue
On Thu, Feb 28, 2019 at 8:12 PM Yang Wei wrote: > > From: Yang Wei > > Delete superfluous semicolons. > > Signed-off-by: Yang Wei Applied. thanks! Alex > --- > drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 8 > drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c | 2 +- > 2 files changed, 5 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c > b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c > index 9bc27f4..b12c828 100644 > --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c > +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c > @@ -1304,7 +1304,7 @@ static int pp_notify_smu_enable_pwe(void *handle) > > if (hwmgr->hwmgr_func->smus_notify_pwe == NULL) { > pr_info_ratelimited("%s was not implemented.\n", __func__); > - return -EINVAL;; > + return -EINVAL; > } > > mutex_lock(&hwmgr->smu_lock); > @@ -1341,7 +1341,7 @@ static int pp_set_min_deep_sleep_dcefclk(void *handle, > uint32_t clock) > > if (hwmgr->hwmgr_func->set_min_deep_sleep_dcefclk == NULL) { > pr_debug("%s was not implemented.\n", __func__); > - return -EINVAL;; > + return -EINVAL; > } > > mutex_lock(&hwmgr->smu_lock); > @@ -1360,7 +1360,7 @@ static int pp_set_hard_min_dcefclk_by_freq(void > *handle, uint32_t clock) > > if (hwmgr->hwmgr_func->set_hard_min_dcefclk_by_freq == NULL) { > pr_debug("%s was not implemented.\n", __func__); > - return -EINVAL;; > + return -EINVAL; > } > > mutex_lock(&hwmgr->smu_lock); > @@ -1379,7 +1379,7 @@ static int pp_set_hard_min_fclk_by_freq(void *handle, > uint32_t clock) > > if (hwmgr->hwmgr_func->set_hard_min_fclk_by_freq == NULL) { > pr_debug("%s was not implemented.\n", __func__); > - return -EINVAL;; > + return -EINVAL; > } > > mutex_lock(&hwmgr->smu_lock); > diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c > b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c > index 1f92a9f..ffa7d46 100644 > --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c > +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c > @@ -76,7 +76,7 @@ int phm_set_power_state(struct pp_hwmgr *hwmgr, > int phm_enable_dynamic_state_management(struct pp_hwmgr *hwmgr) > { > struct amdgpu_device *adev = NULL; > - int ret = -EINVAL;; > + int ret = -EINVAL; > PHM_FUNC_CHECK(hwmgr); > adev = hwmgr->adev; > > -- > 2.7.4 > > > ___ > amd-gfx mailing list > amd-...@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/amd-gfx ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: big conflict in drm-tip (amdgpu)
On Thu, Feb 28, 2019 at 12:43 PM Chris Wilson wrote: > > Quoting Alex Deucher (2019-02-28 17:25:41) > > On Thu, Feb 28, 2019 at 4:54 AM Chris Wilson > > wrote: > > > > > > Quoting Daniel Vetter (2019-02-28 09:49:51) > > > > On Thu, Feb 28, 2019 at 5:30 AM Dave Airlie wrote: > > > > > > > > > > I merged some fixes into drm-fixes, pushed it out, then saw tip > > > > > breaking, but I'm needed elsewhere, so if anyone can fix tip up or > > > > > tell me why I got a super messy commit, I'll owe you. > > > > > > > > Chris already patched it up it seems, I guess someone should > > > > double-check it's reasonable. For the future might be good if amd > > > > trees push into drm-tip and/or linux-next beforehand, for early > > > > warning and testing of the merge resolution. Ideally both I'd say. > > > > It's the biggest driver we have after all :-) > > > > > > I took a conservative approach, and just verified that the code still > > > compiled. I expect the vrr fakery was reverted in the process, but also > > > expect that new code will be flowing from amdgpu in their next update > > > anyway. > > > > Can you point me to the conflict? I'll take a look. Sorry for the > > noise. The VRR fix for 5.0 was a backport since the code changed > > slightly between 5.0 and 5.1. We have the same fix against 5.1 as > > well if that is what the problem was. > > https://cgit.freedesktop.org/drm/drm-tip/commit/?h=rerere-cache&id=660b640f5938ce08c95d75bd7a20182a92e1467f > see amdgpu_dm_commit_planes() > > Presentation in rerere-cache is very weird, there's probably a better > way to review the merge choice&resolution d63716658ac1 ("drm/amd/display: Use vrr friendly pageflip throttling in DC.") should be dropped and this should be applied instead for drm-next: https://cgit.freedesktop.org/~agd5f/linux/commit/?h=drm-next-5.2-wip&id=5d5f43c235d02e4d8e9d50d012f3b21f380486eb Alex > -Chris ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: linux-next: manual merge of the drm tree with the drm-fixes tree
On Thu, Feb 28, 2019 at 9:24 PM Stephen Rothwell wrote: > > Hi all, > > Today's linux-next merge of the drm tree got a conflict in: > > drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > > between commit: > > d63716658ac1 ("drm/amd/display: Use vrr friendly pageflip throttling in > DC.") > > from the drm-fixes tree and commits: > > 8a48b44cd00f ("drm/amd/display: Call into DC once per multiplane flip") > bc7f670ee04c ("drm/amd/display: Perform plane updates only when needed") > > from the drm tree. > > I had no idea how to resolve this, so I just effectively reverted the > drm-fixes commit. > > I fixed it up (see above) and can carry the fix as necessary. This > is now fixed as far as linux-next is concerned, but any non trivial > conflicts should be mentioned to your upstream maintainer when your tree > is submitted for merging. You may also want to consider cooperating > with the maintainer of the conflicting tree to minimise any particularly > complex conflicts. d63716658ac1 ("drm/amd/display: Use vrr friendly pageflip throttling in DC.") should be reverted and this should be applied instead for drm-next: https://cgit.freedesktop.org/~agd5f/linux/commit/?h=drm-next-5.2-wip&id=5d5f43c235d02e4d8e9d50d012f3b21f380486eb Alex > > > > -- > Cheers, > Stephen Rothwell > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 15/17] drm/vc4: Convert to using __drm_atomic_helper_crtc_reset() for reset.
Maarten Lankhorst writes: > Convert vc4 to using __drm_atomic_helper_crtc_reset(), instead of > writing its own version. Instead of open coding destroy_state(), > call it directly for freeing the old state. > > Signed-off-by: Maarten Lankhorst > Cc: Eric Anholt > --- > drivers/gpu/drm/vc4/vc4_crtc.c | 9 + > 1 file changed, 5 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c > index e7c04a9eb219..fdf21594b050 100644 > --- a/drivers/gpu/drm/vc4/vc4_crtc.c > +++ b/drivers/gpu/drm/vc4/vc4_crtc.c > @@ -1041,12 +1041,13 @@ static void vc4_crtc_destroy_state(struct drm_crtc > *crtc, > static void > vc4_crtc_reset(struct drm_crtc *crtc) > { > - if (crtc->state) > - vc4_crtc_destroy_state(crtc->state); > + struct vc4_crtc_state *crtc_state = > + kzalloc(sizeof(*crtc_state), GFP_KERNEL); > > - crtc->state = kzalloc(sizeof(struct vc4_crtc_state), GFP_KERNEL); > if (crtc->state) > - crtc->state->crtc = crtc; > + vc4_crtc_destroy_state(crtc, crtc->state); > + > + __drm_atomic_helper_crtc_reset(crtc, &crtc_state->base); Wouldn't it be much easier if __drm_atomic_helper_crtc_reset took in a new state and destroyed the old state for you? It seems like hardly a helper as is. signature.asc Description: PGP signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 01/17] drm/vc4: Fix memory leak during gpu reset.
Maarten Lankhorst writes: > __drm_atomic_helper_crtc_destroy_state does not free memory, it only > cleans it up. Fix this by calling the functions own destroy function. Reviewed-by: Eric Anholt signature.asc Description: PGP signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH libdrm] tests/modetest: add QCOM_COMPRESSED to supported modifiers list
Signed-off-by: Fritz Koenig --- tests/modetest/modetest.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c index 975dcbcd..9c85c07b 100644 --- a/tests/modetest/modetest.c +++ b/tests/modetest/modetest.c @@ -293,6 +293,8 @@ static const char *modifier_to_string(uint64_t modifier) return "NVIDIA_16BX2_BLOCK(5)"; case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED: return "MOD_BROADCOM_VC4_T_TILED"; + case DRM_FORMAT_MOD_QCOM_COMPRESSED: + return "QCOM_COMPRESSED"; default: return "(UNKNOWN MODIFIER)"; } -- 2.21.0.352.gf09ad66450-goog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 3/3] drm/panel: Add Rocktech jh057n00900 panel driver
Hi Guido. Thanks for addressing review comments in first round. Just a few nits in this follow-up. With these nits addressed: Reviewed-by: Sam Ravnborg On Fri, Mar 01, 2019 at 02:02:04PM +0100, Guido Günther wrote: > +#include This include file is, as far as I could tell, no longer used and can be dropped. > + > +static int jh057n_get_modes(struct drm_panel *panel) > +{ > + struct drm_display_mode *mode; > + > + mode = drm_mode_duplicate(panel->drm, &default_mode); > + if (!mode) { > + DRM_ERROR("Failed to add mode %ux%u@%u", > + default_mode.hdisplay, default_mode.vdisplay, > + default_mode.vrefresh); > + return -ENOMEM; Use DRM_DEV_ERROR() You can find dev via: panel->base.drm-dev > + > +static int jh057n_probe(struct mipi_dsi_device *dsi) > +{ > + struct device *dev = &dsi->dev; > + struct jh057n *ctx; > + int ret; > + > + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); > + if (!ctx) > + return -ENOMEM; > + > + ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); > + if (IS_ERR(ctx->reset_gpio)) { > + DRM_DEV_ERROR(dev, "cannot get reset gpio"); > + return PTR_ERR(ctx->reset_gpio); > + } > + > + mipi_dsi_set_drvdata(dsi, ctx); > + > + ctx->dev = dev; > + > + dsi->lanes = 4; > + dsi->format = MIPI_DSI_FMT_RGB888; > + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | > + MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_VIDEO_SYNC_PULSE; > + > + ctx->backlight = devm_of_find_backlight(dev); > + if (IS_ERR(ctx->backlight)) > + return PTR_ERR(ctx->backlight); > + > + drm_panel_init(&ctx->panel); > + ctx->panel.dev = dev; > + ctx->panel.funcs = &jh057n_drm_funcs; > + > + drm_panel_add(&ctx->panel); > + > + ret = mipi_dsi_attach(dsi); > + if (ret < 0) { > + DRM_DEV_ERROR(dev, "mipi_dsi_attach failed. Is host ready?"); > + drm_panel_remove(&ctx->panel); > + return ret; > + } > + > + DRM_INFO(DRV_NAME "_panel %ux%u@%u %ubpp dsi %udl - ready", > + default_mode.hdisplay, default_mode.vdisplay, > + default_mode.vrefresh, > + mipi_dsi_pixel_format_to_bpp(dsi->format), dsi->lanes); You already have dev, so use DRM_DEV_INFO() and drop DRV_NAME > + > +static const struct of_device_id jh057n_of_match[] = { > + { .compatible = "rocktech,jh057n00900" }, > + { /* Sentinel */ } Lower case 's' (sorry, likely my bad) > + .probe = jh057n_probe, > + .remove = jh057n_remove, > + .shutdown = jh057n_shutdown, > + .driver = { > + .name = DRV_NAME "_panel", Drop "_panel" postfix. Other drivers do not use it. Sam ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 1/2] drm/panel: simple: Add Sharp LS020B1DD01D panel support
Hi Paul. On Thu, Feb 28, 2019 at 03:58:52PM -0300, Paul Cercueil wrote: > The Sharp LS020B1DD01D is a simple 2.0" 240x160 16-bit TFT panel. > > Signed-off-by: Paul Cercueil > Tested-by: Artur Rojek > --- > drivers/gpu/drm/panel/panel-simple.c | 28 > 1 file changed, 28 insertions(+) > > diff --git a/drivers/gpu/drm/panel/panel-simple.c > b/drivers/gpu/drm/panel/panel-simple.c > index 9e8218f6a3f2..3ab604f5477e 100644 > --- a/drivers/gpu/drm/panel/panel-simple.c > +++ b/drivers/gpu/drm/panel/panel-simple.c > @@ -2278,6 +2278,31 @@ static const struct panel_desc sharp_lq150x1lg11 = { > .bus_format = MEDIA_BUS_FMT_RGB565_1X16, > }; > > +static const struct display_timing sharp_ls020b1dd01d_timing = { > + .pixelclock = { 200, 420, 500 }, > + .hactive = { 240, 240, 240 }, > + .hfront_porch = { 66, 66, 66 }, > + .hback_porch = { 1, 1, 1 }, > + .hsync_len = { 1, 1, 1 }, > + .vactive = { 160, 160, 160 }, > + .vfront_porch = { 52, 52, 52 }, > + .vback_porch = { 6, 6, 6 }, > + .vsync_len = { 10, 10, 10 }, > + .flags = DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW, > +}; > + > +static const struct panel_desc sharp_ls020b1dd01d = { > + .timings = &sharp_ls020b1dd01d_timing, > + .num_timings = 1, > + .bpc = 6, > + .size = { > + .width = 42, > + .height = 28, > + }, > + .bus_format = MEDIA_BUS_FMT_RGB565_1X16, > + .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_NEGEDGE, > +}; > + > static const struct drm_display_mode shelly_sca07010_bfn_lnn_mode = { > .clock = 33300, > .hdisplay = 800, > @@ -2767,6 +2792,9 @@ static const struct of_device_id platform_of_match[] = { > .compatible = "sharp,lq150x1lg11", > .data = &sharp_lq150x1lg11, > }, { > + .compatible = "sharp,ls020b1dd01d", > + .data = &sharp_ls020b1dd01d, > + }, { For all three patches I am missing dt-bindings documentation. also for all three patches you get a "+1" for adding all of .flags, .bus_format, .bus_flags. Sam ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm/amdgpu/powerplay: Fix missing break in switch statement
Add missing break statement in order to prevent the code from falling through to case SMU_Discrete_DpmTable. This bug was found thanks to the ongoing efforts to enable -Wimplicit-fallthrough. Fixes: 34a564eaf528 ("drm/amd/powerplay: implement fw image related smum interface for Polaris.") Cc: sta...@vger.kernel.org Signed-off-by: Gustavo A. R. Silva --- drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c index 52abca065764..222fb79d319e 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c @@ -2330,6 +2330,7 @@ static uint32_t polaris10_get_offsetof(uint32_t type, uint32_t member) case DRAM_LOG_BUFF_SIZE: return offsetof(SMU74_SoftRegisters, DRAM_LOG_BUFF_SIZE); } + break; case SMU_Discrete_DpmTable: switch (member) { case UvdBootLevel: -- 2.21.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 109808] ROCm OpenCL segfaults on drm-next-5.1-wip
https://bugs.freedesktop.org/show_bug.cgi?id=109808 Bug ID: 109808 Summary: ROCm OpenCL segfaults on drm-next-5.1-wip Product: DRI Version: XOrg git Hardware: Other OS: All Status: NEW Severity: normal Priority: medium Component: DRM/AMDgpu Assignee: dri-devel@lists.freedesktop.org Reporter: bmil...@gmail.com rocm clinfo segfaults with this on dmesg: mar 01 15:27:36 mjb kernel: kfd2kgd: init_user_pages: Failed to register MMU notifier: -19 Reverting: drm/amdgpu: use HMM callback to replace mmu notifier drm/amdgpu: replace get_user_pages with HMM mirror helpers drm/amdkfd: avoid HMM change cause circular lock drm/amdgpu: use HMM callback to replace mmu notifier makes it work again, something might be wrong with those related commits. -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 3/3] DRM: Add KMS driver for the Ingenic JZ47xx SoCs
Hi Paul. Driver looks good and is a very nice piece of work. In the following a number of minor issues. One area that jumped at me was framedesc and the use of dma_alloc_coherent() I hope someone that knows the memory handling better can give some advice here. To me it looks like something drm should be able to help you with. Sam > --- a/drivers/gpu/drm/Makefile > +++ b/drivers/gpu/drm/Makefile > @@ -94,6 +94,7 @@ obj-$(CONFIG_DRM_TEGRA) += tegra/ > obj-$(CONFIG_DRM_STM) += stm/ > obj-$(CONFIG_DRM_STI) += sti/ > obj-$(CONFIG_DRM_IMX) += imx/ > +obj-y+= ingenic/ To avoid visiting ingenic/ dir for every build use: obj-$(CONFIG_DRM_INGENIC) += ingennic/ And accept that you need to do this also in ingenic/Makefile > obj-$(CONFIG_DRM_MEDIATEK) += mediatek/ > obj-$(CONFIG_DRM_MESON) += meson/ > obj-y+= i2c/ > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +#include "../drm_internal.h" No other drivers needs drm_internal.h - what makes this driver special? Or do we have something in drm_internal that should be moved to include/drm/ ? > +struct ingenic_framedesc { > + uint32_t next; > + uint32_t addr; > + uint32_t id; > + uint32_t cmd; > +} __packed; For internel types u32 is the typical use. uint32_t is usually used in uapi. Consider to use dma_addr_t for addresses - we see this in other drivers. If there are alignemnt constraints then add these. > + > +struct jz_soc_info { > + bool needs_dev_clk; > +}; > + > +struct ingenic_drm { > + struct device *dev; > + void __iomem *base; > + struct regmap *map; > + struct clk *lcd_clk, *pix_clk; > + > + u32 lcd_mode; > + > + struct ingenic_framedesc *framedesc; > + dma_addr_t framedesc_phys; > + > + struct drm_device *drm; > + struct drm_plane primary; > + struct drm_crtc crtc; > + struct drm_connector connector; > + struct drm_encoder encoder; > + struct drm_panel *panel; > + > + struct device_node *panel_node; panel_node is not used outside ingenic_drm_probe() so no need to have it here. > + > + unsigned short ps_start, ps_end, cls_start, > +cls_end, spl_start, spl_end, rev_start; I do not see these used, they can all be dropped. > +}; > + > + > +static const struct regmap_config ingenic_drm_regmap_config = { > + .reg_bits = 32, > + .val_bits = 32, > + .reg_stride = 4, > + > + .max_register = JZ_REG_LCD_CMD1, > + .writeable_reg = ingenic_drm_writeable_reg, > +}; +1 for using regmap. > + > +static inline bool ingenic_drm_lcd_is_special_mode(u32 mode) > +{ > + switch (mode) { > + case JZ_DRM_LCD_SPECIAL_TFT_1: > + case JZ_DRM_LCD_SPECIAL_TFT_2: > + case JZ_DRM_LCD_SPECIAL_TFT_3: > + return true; > + default: > + return false; > + } > +} Does it make sense to support these modes today? If it is not used in practice then no need to carry it in the driver. > + > +static inline bool ingenic_drm_lcd_is_stn_mode(u32 mode) > +{ > + switch (mode) { > + case JZ_DRM_LCD_SINGLE_COLOR_STN: > + case JZ_DRM_LCD_SINGLE_MONOCHROME_STN: > + case JZ_DRM_LCD_DUAL_COLOR_STN: > + case JZ_DRM_LCD_DUAL_MONOCHROME_STN: > + return true; > + default: > + return false; > + } > +} This function is not used and can be deleted. stn display are not really worth it these days anyway. > +static void ingenic_drm_crtc_atomic_flush(struct drm_crtc *crtc, > + struct drm_crtc_state *oldstate) > +{ > + struct ingenic_drm *priv = drm_crtc_get_priv(crtc); > + struct drm_crtc_state *state = crtc->state; > + struct drm_pending_vblank_event *event = state->event; > + struct drm_framebuffer *drm_fb = crtc->primary->state->fb; > + const struct drm_format_info *finfo; > + unsigned int width, height; > + > + if (drm_atomic_crtc_needs_modeset(state)) { > + finfo = drm_format_info(drm_fb->format->format); > + width = state->adjusted_mode.hdisplay; > + height = state->adjusted_mode.vdisplay; width and height are unused and can be dropped. > + > + ingenic_drm_crtc_update_timings(priv, &state->mode); > + > + ingenic_drm_crtc_update_ctrl(priv, finfo->depth); > + ingenic_drm_crtc_update_cfg(priv, &state->adjusted_mode); > + > + clk_set_rate(priv->pix_clk, state->adjusted_mode.clock * 1000); > + > + regmap_write(priv->map, JZ_REG_LCD_DA0, priv->framedesc->next); > + } > + > + if (event) { > + state->event = NULL; > + > + spin_lock_irq(&crtc->dev->event_lock); > + if (drm_crtc_vblank_get(crtc) == 0) > + drm_crtc_arm_vblank_event(crtc, event); > + else > + drm_
[PATCH] drm/amdgpu/gfx_v8_0: Mark expected switch fall-through
In preparation to enabling -Wimplicit-fallthrough, mark switch cases where we are expecting to fall through. This patch fixes the following warning: drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c: In function ‘gfx_v8_0_tiling_mode_table_init’: ./include/linux/device.h:1487:2: warning: this statement may fall through [-Wimplicit-fallthrough=] _dev_warn(dev, dev_fmt(fmt), ##__VA_ARGS__) ^~~ drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c:3236:3: note: in expansion of macro ‘dev_warn’ dev_warn(adev->dev, ^~~~ drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c:3240:2: note: here case CHIP_CARRIZO: ^~~~ Warning level 3 was used: -Wimplicit-fallthrough=3 This patch is part of the ongoing efforts to enable -Wimplicit-fallthrough. Signed-off-by: Gustavo A. R. Silva --- drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index b8e50a34bdb3..02955e6e9dd9 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -3236,6 +3236,7 @@ static void gfx_v8_0_tiling_mode_table_init(struct amdgpu_device *adev) dev_warn(adev->dev, "Unknown chip type (%d) in function gfx_v8_0_tiling_mode_table_init() falling through to CHIP_CARRIZO\n", adev->asic_type); + /* fall through */ case CHIP_CARRIZO: modearray[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | -- 2.21.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC PATCH v1 15/15] drm/msm/a5xx: Support per-instance pagetables
On Fri, Mar 1, 2019 at 2:39 PM Jordan Crouse wrote: > > Add support for per-instance pagetables for 5XX targets. Create a support > buffer for preemption to hold the SMMU pagetable information for a > preempted ring, enable TTBR1 to support split pagetables and add the > necessary PM4 commands to trigger a pagetable switch at the beginning > of a user command. > > Signed-off-by: Jordan Crouse > --- > > drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 120 > +- > drivers/gpu/drm/msm/adreno/a5xx_gpu.h | 19 + > drivers/gpu/drm/msm/adreno/a5xx_preempt.c | 70 + > 3 files changed, 192 insertions(+), 17 deletions(-) > > diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > index 3d6f414..9294fd5 100644 > --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > @@ -202,6 +202,59 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, > struct msm_gem_submit *submit > msm_gpu_retire(gpu); > } > > +static void a5xx_set_pagetable(struct msm_gpu *gpu, struct msm_ringbuffer > *ring, > + struct msm_file_private *ctx) > +{ > + u64 ttbr; > + u32 asid; > + > + if (!msm_iommu_get_ptinfo(ctx->aspace->mmu, &ttbr, &asid)) > + return; > + > + ttbr = ttbr | ((u64) asid) << 48; > + > + /* Turn off protected mode */ > + OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1); > + OUT_RING(ring, 0); > + > + /* Turn on APIV mode to access critical regions */ > + OUT_PKT4(ring, REG_A5XX_CP_CNTL, 1); > + OUT_RING(ring, 1); > + > + /* Make sure the ME is synchronized before staring the update */ > + OUT_PKT7(ring, CP_WAIT_FOR_ME, 0); > + > + /* Execute the table update */ > + OUT_PKT7(ring, CP_SMMU_TABLE_UPDATE, 3); > + OUT_RING(ring, lower_32_bits(ttbr)); > + OUT_RING(ring, upper_32_bits(ttbr)); > + OUT_RING(ring, 0); > + > + /* > +* Write the new TTBR0 to the preemption records - this will be used > to > +* reload the pagetable if the current ring gets preempted out. > +*/ > + OUT_PKT7(ring, CP_MEM_WRITE, 4); > + OUT_RING(ring, lower_32_bits(rbmemptr(ring, ttbr0))); > + OUT_RING(ring, upper_32_bits(rbmemptr(ring, ttbr0))); > + OUT_RING(ring, lower_32_bits(ttbr)); > + OUT_RING(ring, upper_32_bits(ttbr)); > + > + /* Invalidate the draw state so we start off fresh */ > + OUT_PKT7(ring, CP_SET_DRAW_STATE, 3); > + OUT_RING(ring, 0x4); CP_SET_DRAW_STATE__0_DISABLE_ALL_GROUPS? > + OUT_RING(ring, 1); was that really meant to be 1, not 0, for the low 32b of the state object address? BR, -R > + OUT_RING(ring, 0); > + > + /* Turn off APRIV */ > + OUT_PKT4(ring, REG_A5XX_CP_CNTL, 1); > + OUT_RING(ring, 0); > + > + /* Turn off protected mode */ > + OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1); > + OUT_RING(ring, 1); > +} > + > static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, > struct msm_file_private *ctx) > { > @@ -217,6 +270,8 @@ static void a5xx_submit(struct msm_gpu *gpu, struct > msm_gem_submit *submit, > return; > } > > + a5xx_set_pagetable(gpu, ring, ctx); > + > OUT_PKT7(ring, CP_PREEMPT_ENABLE_GLOBAL, 1); > OUT_RING(ring, 0x02); > > @@ -1456,21 +1511,77 @@ static unsigned long a5xx_gpu_busy(struct msm_gpu > *gpu) > return (unsigned long)busy_time; > } > > +static struct msm_gem_address_space *a5xx_new_address_space(struct msm_gpu > *gpu) > +{ > + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); > + struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu); > + struct msm_gem_address_space *aspace; > + int ret; > + > + /* Return the default pagetable if per instance tables don't work */ > + if (!a5xx_gpu->per_instance_tables) > + return gpu->aspace; > + > + aspace = msm_gem_address_space_create_instance(&gpu->pdev->dev, > + "gpu", 0x1ULL, 0x1ULL); > + if (IS_ERR(aspace)) > + return aspace; > + > + ret = aspace->mmu->funcs->attach(aspace->mmu, NULL, 0); > + if (ret) { > + /* -ENODEV means that aux domains aren't supported */ > + if (ret == -ENODEV) > + return gpu->aspace; > + > + return ERR_PTR(ret); > + } > + > + return aspace; > +} > + > static struct msm_gem_address_space * > a5xx_create_address_space(struct msm_gpu *gpu) > { > + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); > + struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu); > + struct device *dev = &gpu->pdev->dev; > struct msm_gem_address_space *aspace; > struct iommu_domain *iommu; > - int ret; > + int ret, val = 1; > + > + a5xx_gpu->per_instance_tables = false; > >
Re: [PATCH 1/3] dt-bindings: Add doc for the ingenic-drm driver
Hi Paul. Good to see work migrating fbdev => drm. Following comments is based on experience while working on migrating another driver from fbdev => drm. On Thu, Feb 28, 2019 at 07:07:54PM -0300, Paul Cercueil wrote: > Add documentation for the devicetree bindings of the DRM driver for the > JZ47xx family of SoCs from Ingenic. > > Signed-off-by: Paul Cercueil > Tested-by: Artur Rojek > --- > .../devicetree/bindings/display/ingenic,drm.txt| 30 > ++ > 1 file changed, 30 insertions(+) > create mode 100644 Documentation/devicetree/bindings/display/ingenic,drm.txt > > diff --git a/Documentation/devicetree/bindings/display/ingenic,drm.txt > b/Documentation/devicetree/bindings/display/ingenic,drm.txt > new file mode 100644 > index ..52a368ec35cd > --- /dev/null > +++ b/Documentation/devicetree/bindings/display/ingenic,drm.txt > @@ -0,0 +1,30 @@ > +Ingenic JZ47xx DRM driver > + > +Required properties: > +- compatible: one of: > + * ingenic,jz4740-drm > + * ingenic,jz4725b-drm > +- reg: LCD registers location and length The fbdev way of doing this was to hardcode register setttings. In the drm world we read the configuration of the panel and let this decide the actual configuration. Note that no drm drivers supports stn displays and that there is really no use for this these days. So you can skip the STN parts. Also the modern way to specify a panel in the DT is using OF graph bindings. You can find many examples how to do this. I was there with the atmel LCDC driver (not in the kernel yet), and had some challenges with this. Sam ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH v1 12/15] drm/msm: Add support to create target specific address spaces
Add support to create a GPU target specific address space for a context. For those targets that support per-instance pagetables they will return a new address space set up for the instance if possible otherwise just use the global device pagetable. Signed-off-by: Jordan Crouse --- drivers/gpu/drm/msm/msm_drv.c | 25 ++--- drivers/gpu/drm/msm/msm_gpu.h | 1 + 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index cac2293..5b83093 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -605,6 +605,14 @@ static void load_gpu(struct drm_device *dev) mutex_unlock(&init_lock); } +static struct msm_gem_address_space *context_address_space(struct msm_gpu *gpu) +{ + if (!gpu->funcs->new_address_space) + return gpu->aspace; + + return gpu->funcs->new_address_space(gpu); +} + static int context_init(struct drm_device *dev, struct drm_file *file) { struct msm_drm_private *priv = dev->dev_private; @@ -614,9 +622,16 @@ static int context_init(struct drm_device *dev, struct drm_file *file) if (!ctx) return -ENOMEM; + ctx->aspace = context_address_space(priv->gpu); + if (IS_ERR(ctx->aspace)) { + int ret = PTR_ERR(ctx->aspace); + + kfree(ctx); + return ret; + } + msm_submitqueue_init(dev, ctx); - ctx->aspace = priv->gpu->aspace; file->driver_priv = ctx; return 0; @@ -632,8 +647,12 @@ static int msm_open(struct drm_device *dev, struct drm_file *file) return context_init(dev, file); } -static void context_close(struct msm_file_private *ctx) +static void context_close(struct msm_drm_private *priv, + struct msm_file_private *ctx) { + if (ctx->aspace != priv->gpu->aspace) + msm_gem_address_space_put(ctx->aspace); + msm_submitqueue_close(ctx); kfree(ctx); } @@ -648,7 +667,7 @@ static void msm_postclose(struct drm_device *dev, struct drm_file *file) priv->lastctx = NULL; mutex_unlock(&dev->struct_mutex); - context_close(ctx); + context_close(priv, ctx); } static irqreturn_t msm_irq(int irq, void *arg) diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index 81b9861..35b0faf 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -76,6 +76,7 @@ struct msm_gpu_funcs { void (*gpu_set_freq)(struct msm_gpu *gpu, unsigned long freq); struct msm_gem_address_space *(*create_address_space) (struct msm_gpu *gpu); + struct msm_gem_address_space *(*new_address_space)(struct msm_gpu *gpu); }; struct msm_gpu { -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH v1 13/15] drm/msm/gpu: Add ttbr0 to the memptrs
Targets that support per-instance pagetable switching will have to keep track of which pagetable belongs to each instance to be able to recover for preemption. Signed-off-by: Jordan Crouse --- drivers/gpu/drm/msm/msm_ringbuffer.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.h b/drivers/gpu/drm/msm/msm_ringbuffer.h index 6434ebb..493fa89 100644 --- a/drivers/gpu/drm/msm/msm_ringbuffer.h +++ b/drivers/gpu/drm/msm/msm_ringbuffer.h @@ -40,6 +40,7 @@ struct msm_gpu_submit_stats { struct msm_rbmemptrs { volatile uint32_t rptr; volatile uint32_t fence; + volatile uint64_t ttbr0; volatile struct msm_gpu_submit_stats stats[MSM_GPU_SUBMIT_STATS_COUNT]; }; -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH v1 14/15] drm/msm/a6xx: Support per-instance pagetables
Add support for per-instance pagetables for a6xx targets. Add support to handle split pagetables and create a new instance if the needed IOMMU support exists and insert the necessary PM4 commands to trigger a pagetable switch at the beginning of a user command. Signed-off-by: Jordan Crouse --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 124 -- drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 1 + 2 files changed, 121 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index f2e0800..57d1909 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -10,6 +10,63 @@ #include +static void a6xx_set_pagetable(struct msm_gpu *gpu, struct msm_ringbuffer *ring, + struct msm_file_private *ctx) +{ + u64 ttbr; + u32 asid; + + if (!msm_iommu_get_ptinfo(ctx->aspace->mmu, &ttbr, &asid)) + return; + + ttbr = ttbr | ((u64) asid) << 48; + + /* Turn off protected mode */ + OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1); + OUT_RING(ring, 0); + + /* Turn on APIV mode to access critical regions */ + OUT_PKT4(ring, REG_A6XX_CP_MISC_CNTL, 1); + OUT_RING(ring, 1); + + /* Make sure the ME is synchronized before staring the update */ + OUT_PKT7(ring, CP_WAIT_FOR_ME, 0); + + /* Execute the table update */ + OUT_PKT7(ring, CP_SMMU_TABLE_UPDATE, 4); + OUT_RING(ring, lower_32_bits(ttbr)); + OUT_RING(ring, upper_32_bits(ttbr)); + /* CONTEXTIDR is currently unused */ + OUT_RING(ring, 0); + /* CONTEXTBANK is currently unused */ + OUT_RING(ring, 0); + + /* +* Write the new TTBR0 to the preemption records - this will be used to +* reload the pagetable if the current ring gets preempted out. +*/ + OUT_PKT7(ring, CP_MEM_WRITE, 4); + OUT_RING(ring, lower_32_bits(rbmemptr(ring, ttbr0))); + OUT_RING(ring, upper_32_bits(rbmemptr(ring, ttbr0))); + OUT_RING(ring, lower_32_bits(ttbr)); + OUT_RING(ring, upper_32_bits(ttbr)); + + /* Invalidate the draw state so we start off fresh */ + OUT_PKT7(ring, CP_SET_DRAW_STATE, 3); + OUT_RING(ring, 0x4); + OUT_RING(ring, 1); + OUT_RING(ring, 0); + + /* Turn off APRIV */ + OUT_PKT4(ring, REG_A6XX_CP_MISC_CNTL, 1); + OUT_RING(ring, 0); + + /* Turn off protected mode */ + OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1); + OUT_RING(ring, 1); +} + + static inline bool _a6xx_check_idle(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); @@ -87,6 +144,8 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, struct msm_ringbuffer *ring = submit->ring; unsigned int i; + a6xx_set_pagetable(gpu, ring, ctx); + get_stats_counter(ring, REG_A6XX_RBBM_PERFCTR_CP_0_LO, rbmemptr_stats(ring, index, cpcycles_start)); @@ -783,21 +842,77 @@ static unsigned long a6xx_gpu_busy(struct msm_gpu *gpu) return (unsigned long)busy_time; } +static struct msm_gem_address_space *a6xx_new_address_space(struct msm_gpu *gpu) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); + struct msm_gem_address_space *aspace; + int ret; + + /* Return the default pagetable if per instance tables don't work */ + if (!a6xx_gpu->per_instance_tables) + return gpu->aspace; + + aspace = msm_gem_address_space_create_instance(&gpu->pdev->dev, "gpu", + 0x1ULL, 0x1ULL); + if (IS_ERR(aspace)) + return aspace; + + ret = aspace->mmu->funcs->attach(aspace->mmu, NULL, 0); + if (ret) { + /* -ENODEV means that aux domains aren't supported */ + if (ret == -ENODEV) + return gpu->aspace; + + return ERR_PTR(ret); + } + + return aspace; +} + static struct msm_gem_address_space * a6xx_create_address_space(struct msm_gpu *gpu) { + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); + struct device *dev = &gpu->pdev->dev; struct msm_gem_address_space *aspace; struct iommu_domain *iommu; - int ret; + int ret, val = 1; + + a6xx_gpu->per_instance_tables = false; iommu = iommu_domain_alloc(&platform_bus_type); if (!iommu) return NULL; - iommu->geometry.aperture_start = 0x1ULL; - iommu->geometry.aperture_end = 0x1ULL; + /* Try to enable split pagetables */ + if (iommu_domain_set_attr(iommu, DOMAIN_ATTR_SPLIT_TABLES, &val)) { + /* +* If split pagetables aren't available we won't be able to do +* per-ins
[RFC PATCH v1 11/15] drm/msm: Add a helper function for a per-instance address space
Add a helper function to create a GEM address space attached to an iommu auxiliary domain for a per-instance pagetable. Signed-off-by: Jordan Crouse --- drivers/gpu/drm/msm/msm_drv.h | 4 +++ drivers/gpu/drm/msm/msm_gem_vma.c | 53 +++ 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 3140e8f..4423be0 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -258,6 +258,10 @@ struct msm_gem_address_space * msm_gem_address_space_create_a2xx(struct device *dev, struct msm_gpu *gpu, const char *name, uint64_t va_start, uint64_t va_end); +struct msm_gem_address_space * +msm_gem_address_space_create_instance(struct device *dev, const char *name, + u64 va_start, u64 va_end); + int msm_register_mmu(struct drm_device *dev, struct msm_mmu *mmu); void msm_unregister_mmu(struct drm_device *dev, struct msm_mmu *mmu); diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c b/drivers/gpu/drm/msm/msm_gem_vma.c index 49c0482..4364bf8 100644 --- a/drivers/gpu/drm/msm/msm_gem_vma.c +++ b/drivers/gpu/drm/msm/msm_gem_vma.c @@ -136,14 +136,12 @@ int msm_gem_init_vma(struct msm_gem_address_space *aspace, return 0; } - -struct msm_gem_address_space * -msm_gem_address_space_create(struct device *dev, struct iommu_domain *domain, - const char *name) +static struct msm_gem_address_space * +msm_gem_address_space_new(struct msm_mmu *mmu, const char *name, + u64 va_start, u64 va_end) { struct msm_gem_address_space *aspace; - u64 size = domain->geometry.aperture_end - - domain->geometry.aperture_start; + u64 size = va_end - va_start; aspace = kzalloc(sizeof(*aspace), GFP_KERNEL); if (!aspace) @@ -151,10 +149,9 @@ msm_gem_address_space_create(struct device *dev, struct iommu_domain *domain, spin_lock_init(&aspace->lock); aspace->name = name; - aspace->mmu = msm_iommu_new(dev, domain); + aspace->mmu = mmu; - drm_mm_init(&aspace->mm, (domain->geometry.aperture_start >> PAGE_SHIFT), - size >> PAGE_SHIFT); + drm_mm_init(&aspace->mm, (va_start >> PAGE_SHIFT), size >> PAGE_SHIFT); kref_init(&aspace->kref); @@ -162,24 +159,38 @@ msm_gem_address_space_create(struct device *dev, struct iommu_domain *domain, } struct msm_gem_address_space * +msm_gem_address_space_create(struct device *dev, struct iommu_domain *domain, + const char *name) +{ + struct msm_mmu *mmu = msm_iommu_new(dev, domain); + + if (IS_ERR(mmu)) + return ERR_CAST(mmu); + + return msm_gem_address_space_new(mmu, name, + domain->geometry.aperture_start, domain->geometry.aperture_end); +} + +struct msm_gem_address_space * msm_gem_address_space_create_a2xx(struct device *dev, struct msm_gpu *gpu, const char *name, uint64_t va_start, uint64_t va_end) { - struct msm_gem_address_space *aspace; - u64 size = va_end - va_start; + struct msm_mmu *mmu = msm_gpummu_new(dev, gpu); - aspace = kzalloc(sizeof(*aspace), GFP_KERNEL); - if (!aspace) - return ERR_PTR(-ENOMEM); + if (IS_ERR(mmu)) + return ERR_CAST(mmu); - spin_lock_init(&aspace->lock); - aspace->name = name; - aspace->mmu = msm_gpummu_new(dev, gpu); + return msm_gem_address_space_new(mmu, name, va_start, va_end); +} - drm_mm_init(&aspace->mm, (va_start >> PAGE_SHIFT), - size >> PAGE_SHIFT); +struct msm_gem_address_space * +msm_gem_address_space_create_instance(struct device *dev, const char *name, + u64 va_start, u64 va_end) +{ + struct msm_mmu *mmu = msm_iommu_new_instance(dev); - kref_init(&aspace->kref); + if (IS_ERR(mmu)) + return ERR_CAST(mmu); - return aspace; + return msm_gem_address_space_new(mmu, name, va_start, va_end); } -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH v1 15/15] drm/msm/a5xx: Support per-instance pagetables
Add support for per-instance pagetables for 5XX targets. Create a support buffer for preemption to hold the SMMU pagetable information for a preempted ring, enable TTBR1 to support split pagetables and add the necessary PM4 commands to trigger a pagetable switch at the beginning of a user command. Signed-off-by: Jordan Crouse --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 120 +- drivers/gpu/drm/msm/adreno/a5xx_gpu.h | 19 + drivers/gpu/drm/msm/adreno/a5xx_preempt.c | 70 + 3 files changed, 192 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 3d6f414..9294fd5 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -202,6 +202,59 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit *submit msm_gpu_retire(gpu); } +static void a5xx_set_pagetable(struct msm_gpu *gpu, struct msm_ringbuffer *ring, + struct msm_file_private *ctx) +{ + u64 ttbr; + u32 asid; + + if (!msm_iommu_get_ptinfo(ctx->aspace->mmu, &ttbr, &asid)) + return; + + ttbr = ttbr | ((u64) asid) << 48; + + /* Turn off protected mode */ + OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1); + OUT_RING(ring, 0); + + /* Turn on APIV mode to access critical regions */ + OUT_PKT4(ring, REG_A5XX_CP_CNTL, 1); + OUT_RING(ring, 1); + + /* Make sure the ME is synchronized before staring the update */ + OUT_PKT7(ring, CP_WAIT_FOR_ME, 0); + + /* Execute the table update */ + OUT_PKT7(ring, CP_SMMU_TABLE_UPDATE, 3); + OUT_RING(ring, lower_32_bits(ttbr)); + OUT_RING(ring, upper_32_bits(ttbr)); + OUT_RING(ring, 0); + + /* +* Write the new TTBR0 to the preemption records - this will be used to +* reload the pagetable if the current ring gets preempted out. +*/ + OUT_PKT7(ring, CP_MEM_WRITE, 4); + OUT_RING(ring, lower_32_bits(rbmemptr(ring, ttbr0))); + OUT_RING(ring, upper_32_bits(rbmemptr(ring, ttbr0))); + OUT_RING(ring, lower_32_bits(ttbr)); + OUT_RING(ring, upper_32_bits(ttbr)); + + /* Invalidate the draw state so we start off fresh */ + OUT_PKT7(ring, CP_SET_DRAW_STATE, 3); + OUT_RING(ring, 0x4); + OUT_RING(ring, 1); + OUT_RING(ring, 0); + + /* Turn off APRIV */ + OUT_PKT4(ring, REG_A5XX_CP_CNTL, 1); + OUT_RING(ring, 0); + + /* Turn off protected mode */ + OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1); + OUT_RING(ring, 1); +} + static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, struct msm_file_private *ctx) { @@ -217,6 +270,8 @@ static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, return; } + a5xx_set_pagetable(gpu, ring, ctx); + OUT_PKT7(ring, CP_PREEMPT_ENABLE_GLOBAL, 1); OUT_RING(ring, 0x02); @@ -1456,21 +1511,77 @@ static unsigned long a5xx_gpu_busy(struct msm_gpu *gpu) return (unsigned long)busy_time; } +static struct msm_gem_address_space *a5xx_new_address_space(struct msm_gpu *gpu) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu); + struct msm_gem_address_space *aspace; + int ret; + + /* Return the default pagetable if per instance tables don't work */ + if (!a5xx_gpu->per_instance_tables) + return gpu->aspace; + + aspace = msm_gem_address_space_create_instance(&gpu->pdev->dev, + "gpu", 0x1ULL, 0x1ULL); + if (IS_ERR(aspace)) + return aspace; + + ret = aspace->mmu->funcs->attach(aspace->mmu, NULL, 0); + if (ret) { + /* -ENODEV means that aux domains aren't supported */ + if (ret == -ENODEV) + return gpu->aspace; + + return ERR_PTR(ret); + } + + return aspace; +} + static struct msm_gem_address_space * a5xx_create_address_space(struct msm_gpu *gpu) { + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu); + struct device *dev = &gpu->pdev->dev; struct msm_gem_address_space *aspace; struct iommu_domain *iommu; - int ret; + int ret, val = 1; + + a5xx_gpu->per_instance_tables = false; iommu = iommu_domain_alloc(&platform_bus_type); if (!iommu) return NULL; - iommu->geometry.aperture_start = 0x1ULL; - iommu->geometry.aperture_end = 0x1ULL; + /* Try to enable split pagetables */ + if (iommu_domain_set_attr(iommu, DOMAIN_ATTR_SPLIT_TABLES, &val)) { + /* +* If split pagetables aren't available we won't be able to do +* per-i
[RFC PATCH v1 09/15] drm/msm/gpu: Move address space setup to the GPU targets
Move the address space steup code out of the generic msm GPU code to to the individual GPU targets. This allows us to do target specific setup such as gpummu for a2xx or split pagetables and per-instance pagetables for newer a5xx and a6xx targets. All this is at the expense of duplicated code in some of the target files but I think it pays for itself in improved code flow and flexibility. Signed-off-by: Jordan Crouse --- drivers/gpu/drm/msm/adreno/a2xx_gpu.c | 37 -- drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 50 ++ drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 51 +++ drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 37 +++--- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 37 +++--- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 7 - drivers/gpu/drm/msm/msm_gem.h | 1 + drivers/gpu/drm/msm/msm_gpu.c | 54 ++--- drivers/gpu/drm/msm/msm_gpu.h | 2 ++ 9 files changed, 173 insertions(+), 103 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c index 1f83bc1..49241d0 100644 --- a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c @@ -401,6 +401,30 @@ static struct msm_gpu_state *a2xx_gpu_state_get(struct msm_gpu *gpu) return state; } +static struct msm_gem_address_space * +a2xx_create_address_space(struct msm_gpu *gpu) +{ + struct msm_gem_address_space *aspace; + int ret; + + aspace = msm_gem_address_space_create_a2xx(&gpu->pdev->dev, gpu, + "gpu", SZ_16M, SZ_16M + 0xff * SZ_64K); + if (IS_ERR(aspace)) { + DRM_DEV_ERROR(gpu->dev->dev, + "No memory protection without MMU\n"); + return ERR_PTR(-ENXIO); + } + + ret = aspace->mmu->funcs->attach(aspace->mmu, NULL, 0); + if (ret) { + msm_gem_address_space_put(aspace); + return ERR_PTR(ret); + } + + return aspace; +} + + /* Register offset defines for A2XX - copy of A3XX */ static const unsigned int a2xx_register_offsets[REG_ADRENO_REGISTER_MAX] = { REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_BASE, REG_AXXX_CP_RB_BASE), @@ -429,6 +453,7 @@ static const struct adreno_gpu_funcs funcs = { #endif .gpu_state_get = a2xx_gpu_state_get, .gpu_state_put = adreno_gpu_state_put, + .create_address_space = a2xx_create_address_space, }, }; @@ -473,16 +498,8 @@ struct msm_gpu *a2xx_gpu_init(struct drm_device *dev) adreno_gpu->reg_offsets = a2xx_register_offsets; ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1); - if (ret) - goto fail; - - if (!gpu->aspace) { - dev_err(dev->dev, "No memory protection without MMU\n"); - ret = -ENXIO; - goto fail; - } - - return gpu; + if (!ret) + return gpu; fail: if (a2xx_gpu) diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c index c3b4bc6..33ab5e8 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c @@ -21,6 +21,7 @@ # include #endif +#include "msm_gem.h" #include "a3xx_gpu.h" #define A3XX_INT0_MASK \ @@ -433,6 +434,41 @@ static struct msm_gpu_state *a3xx_gpu_state_get(struct msm_gpu *gpu) return state; } +static struct msm_gem_address_space * +a3xx_create_address_space(struct msm_gpu *gpu) +{ + struct msm_gem_address_space *aspace; + struct iommu_domain *iommu; + int ret; + + iommu = iommu_domain_alloc(&platform_bus_type); + if (!iommu) { + DRM_DEV_ERROR(gpu->dev->dev, + "No memory protection without IOMMU\n"); + return ERR_PTR(-ENXIO); + } + + iommu->geometry.aperture_start = SZ_16M; + iommu->geometry.aperture_end = 0x; + + aspace = msm_gem_address_space_create(&gpu->pdev->dev, iommu, "gpu"); + if (IS_ERR(aspace)) { + iommu_domain_free(iommu); + DRM_DEV_ERROR(gpu->dev->dev, "failed to init mmu: %ld\n", + PTR_ERR(aspace)); + return aspace; + } + + ret = aspace->mmu->funcs->attach(aspace->mmu, NULL, 0); + if (ret) { + msm_gem_address_space_put(aspace); + return ERR_PTR(ret); + } + + return aspace; +} + + /* Register offset defines for A3XX */ static const unsigned int a3xx_register_offsets[REG_ADRENO_REGISTER_MAX] = { REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_BASE, REG_AXXX_CP_RB_BASE), @@ -461,6 +497,7 @@ static const struct adreno_gpu_funcs funcs = { #endif .gpu_state_get = a3xx_gpu_state_get, .gpu_state_put = adreno_gpu_state_put, + .create_address_space = a3xx_create_addres
[RFC PATCH v1 07/15] drm/msm: Print all 64 bits of the faulting IOMMU address
When we move to 64 bit addressing for a5xx and a6xx targets we will start seeing pagefaults at larger addresses so format them appropriately in the log message for easier debugging. Signed-off-by: Jordan Crouse --- drivers/gpu/drm/msm/msm_iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c index 12bb54c..1926329 100644 --- a/drivers/gpu/drm/msm/msm_iommu.c +++ b/drivers/gpu/drm/msm/msm_iommu.c @@ -30,7 +30,7 @@ static int msm_fault_handler(struct iommu_domain *domain, struct device *dev, struct msm_iommu *iommu = arg; if (iommu->base.handler) return iommu->base.handler(iommu->base.arg, iova, flags); - pr_warn_ratelimited("*** fault: iova=%08lx, flags=%d\n", iova, flags); + pr_warn_ratelimited("*** fault: iova=%16lx, flags=%d\n", iova, flags); return 0; } -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH v1 10/15] drm/msm: Add support for IOMMU auxiliary domains
Add support for creating a auxiliary domain from the IOMMU device to implement per-instance pagetables. Also add a helper function to return the pagetable base address (ttbr) and asid to the caller so that the GPU target code can set up the pagetable switch. Signed-off-by: Jordan Crouse --- drivers/gpu/drm/msm/msm_iommu.c | 97 + drivers/gpu/drm/msm/msm_mmu.h | 4 ++ 2 files changed, 101 insertions(+) diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c index 1926329..adf9f18 100644 --- a/drivers/gpu/drm/msm/msm_iommu.c +++ b/drivers/gpu/drm/msm/msm_iommu.c @@ -21,9 +21,21 @@ struct msm_iommu { struct msm_mmu base; struct iommu_domain *domain; + u64 ttbr; + u32 asid; }; #define to_msm_iommu(x) container_of(x, struct msm_iommu, base) +/* + * The asid is currently unused for arm-smmu-v2 since all the pagetable + * switching does a TLBIALL but still assign a somewhat unique number per + * instance to leave open the possibility of being smarter about it + * + * Accepted range is 32 to 255 (starting at 32 gives a cushion for the asids + * assigned to the real context banks in the arm-smmu driver. + */ +static int msm_iommu_asid = 32; + static int msm_fault_handler(struct iommu_domain *domain, struct device *dev, unsigned long iova, int flags, void *arg) { @@ -34,6 +46,47 @@ static int msm_fault_handler(struct iommu_domain *domain, struct device *dev, return 0; } +static int msm_iommu_aux_attach(struct msm_mmu *mmu, const char * const *names, + int cnt) +{ + struct msm_iommu *iommu = to_msm_iommu(mmu); + int ret; + + /* Attach the aux device */ + ret = iommu_aux_attach_device(iommu->domain, mmu->dev); + if (ret) + return ret; + + /* Get the base address of the pagetable */ + ret = iommu_domain_get_attr(iommu->domain, DOMAIN_ATTR_PTBASE, + &iommu->ttbr); + if (ret) + return ret; + + /* +* Assign an asid for the instance even though the code doesn't +* currently support per-asid TLB invalidation. There isn't any +* protection on this so two instances could in theory end up with the +* same ASID but that would have very minor performance implications if +* per-ASID TLB invalidation were to be enabled in the future +*/ + iommu->asid = msm_iommu_asid++; + + if (msm_iommu_asid > 0xff) + msm_iommu_asid = 32; + + return 0; +} + +static void msm_iommu_aux_detach(struct msm_mmu *mmu, const char * const *names, +int cnt) +{ + struct msm_iommu *iommu = to_msm_iommu(mmu); + + iommu->ttbr = 0; + iommu->asid = 0; +} + static int msm_iommu_attach(struct msm_mmu *mmu, const char * const *names, int cnt) { @@ -86,6 +139,50 @@ static const struct msm_mmu_funcs funcs = { .destroy = msm_iommu_destroy, }; +static const struct msm_mmu_funcs aux_funcs = { + .attach = msm_iommu_aux_attach, + .detach = msm_iommu_aux_detach, + .map = msm_iommu_map, + .unmap = msm_iommu_unmap, + .destroy = msm_iommu_destroy, +}; + +bool msm_iommu_get_ptinfo(struct msm_mmu *mmu, u64 *ttbr, u32 *asid) +{ + struct msm_iommu *iommu = to_msm_iommu(mmu); + + if (!iommu->ttbr) + return false; + + if (ttbr) + *ttbr = iommu->ttbr; + if (asid) + *asid = iommu->asid; + + return true; +} + + +struct msm_mmu *msm_iommu_new_instance(struct device *dev) +{ + struct msm_iommu *iommu; + + iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); + if (!iommu) + return ERR_PTR(-ENOMEM); + + /* Create a new domain that will be attached as an aux domain */ + iommu->domain = iommu_domain_alloc(&platform_bus_type); + if (!iommu->domain) { + kfree(iommu); + return ERR_PTR(-ENOMEM); + } + + msm_mmu_init(&iommu->base, dev, &aux_funcs); + + return &iommu->base; +} + struct msm_mmu *msm_iommu_new(struct device *dev, struct iommu_domain *domain) { struct msm_iommu *iommu; diff --git a/drivers/gpu/drm/msm/msm_mmu.h b/drivers/gpu/drm/msm/msm_mmu.h index d21b266..f430903 100644 --- a/drivers/gpu/drm/msm/msm_mmu.h +++ b/drivers/gpu/drm/msm/msm_mmu.h @@ -46,6 +46,10 @@ static inline void msm_mmu_init(struct msm_mmu *mmu, struct device *dev, struct msm_mmu *msm_iommu_new(struct device *dev, struct iommu_domain *domain); struct msm_mmu *msm_gpummu_new(struct device *dev, struct msm_gpu *gpu); +struct msm_mmu *msm_iommu_new_instance(struct device *dev); + +bool msm_iommu_get_ptinfo(struct msm_mmu *mmu, u64 *ttbr, u32 *asid); + static inline void msm_mmu_set_fault_handler(struct msm_mmu *mmu, void *arg, int (*hand
[RFC PATCH v1 08/15] drm/msm: Pass the MMU domain index in struct msm_file_private
Pass the index of the MMU domain in struct msm_file_private instead of assuming gpu->id throughout the submit path. This clears the way to change ctx->aspace to a per-instance pagetable. Signed-off-by: Jordan Crouse --- drivers/gpu/drm/msm/msm_drv.c| 2 ++ drivers/gpu/drm/msm/msm_drv.h| 1 + drivers/gpu/drm/msm/msm_gem.h| 1 + drivers/gpu/drm/msm/msm_gem_submit.c | 13 - drivers/gpu/drm/msm/msm_gpu.c| 5 ++--- 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 906b2bb..cac2293 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -607,6 +607,7 @@ static void load_gpu(struct drm_device *dev) static int context_init(struct drm_device *dev, struct drm_file *file) { + struct msm_drm_private *priv = dev->dev_private; struct msm_file_private *ctx; ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); @@ -615,6 +616,7 @@ static int context_init(struct drm_device *dev, struct drm_file *file) msm_submitqueue_init(dev, ctx); + ctx->aspace = priv->gpu->aspace; file->driver_priv = ctx; return 0; diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index cb642fe..3140e8f 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -68,6 +68,7 @@ struct msm_file_private { rwlock_t queuelock; struct list_head submitqueues; int queueid; + struct msm_gem_address_space *aspace; }; enum msm_mdp_plane_property { diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h index 2064fac..5e21d01 100644 --- a/drivers/gpu/drm/msm/msm_gem.h +++ b/drivers/gpu/drm/msm/msm_gem.h @@ -142,6 +142,7 @@ void msm_gem_vunmap(struct drm_gem_object *obj, enum msm_gem_lock subclass); struct msm_gem_submit { struct drm_device *dev; struct msm_gpu *gpu; + struct msm_gem_address_space *aspace; struct list_head node; /* node in ring submit list */ struct list_head bo_list; struct ww_acquire_ctx ticket; diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 12b983f..79d95b2 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -32,8 +32,9 @@ #define BO_PINNED 0x2000 static struct msm_gem_submit *submit_create(struct drm_device *dev, - struct msm_gpu *gpu, struct msm_gpu_submitqueue *queue, - uint32_t nr_bos, uint32_t nr_cmds) + struct msm_gpu *gpu, struct msm_gem_address_space *aspace, + struct msm_gpu_submitqueue *queue, uint32_t nr_bos, + uint32_t nr_cmds) { struct msm_gem_submit *submit; uint64_t sz = sizeof(*submit) + ((u64)nr_bos * sizeof(submit->bos[0])) + @@ -47,6 +48,7 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev, return NULL; submit->dev = dev; + submit->aspace = aspace; submit->gpu = gpu; submit->fence = NULL; submit->cmd = (void *)&submit->bos[nr_bos]; @@ -170,7 +172,7 @@ static void submit_unlock_unpin_bo(struct msm_gem_submit *submit, struct msm_gem_object *msm_obj = submit->bos[i].obj; if (submit->bos[i].flags & BO_PINNED) - msm_gem_unpin_iova(&msm_obj->base, submit->gpu->aspace); + msm_gem_unpin_iova(&msm_obj->base, submit->aspace); if (submit->bos[i].flags & BO_LOCKED) ww_mutex_unlock(&msm_obj->resv->lock); @@ -274,7 +276,7 @@ static int submit_pin_objects(struct msm_gem_submit *submit) /* if locking succeeded, pin bo: */ ret = msm_gem_get_and_pin_iova(&msm_obj->base, - submit->gpu->aspace, &iova); + submit->aspace, &iova); if (ret) break; @@ -487,7 +489,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, } } - submit = submit_create(dev, gpu, queue, args->nr_bos, args->nr_cmds); + submit = submit_create(dev, gpu, ctx->aspace, queue, args->nr_bos, + args->nr_cmds); if (!submit) { ret = -ENOMEM; goto out_unlock; diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 10babd1..79b71b1 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -693,7 +693,7 @@ static void retire_submit(struct msm_gpu *gpu, struct msm_ringbuffer *ring, struct msm_gem_object *msm_obj = submit->bos[i].obj; /* move to inactive: */ msm_gem_move_to_inactive(&msm_obj->base); - msm_gem_unpin_iova(&msm_obj->base, gpu->aspace); + msm_gem_unpin_iova(&msm_obj->base, submit->aspace); drm_gem_object_put(&msm_obj->base
[RFC PATCH v1 06/15] drm/msm/adreno: Enable 64 bit mode by default on a5xx and a6xx targets
A5XX and newer GPUs can be run in either 32 or 64 bit mode. The GPU registers and the microcode use 64 bit virtual addressing in either case but the upper 32 bits are ignored if the GPU is in 32 bit mode. There is no performance disadvantage to remaining in 64 bit mode even if we are only generating 32 bit addresses so switch over now to prepare for using addresses above 4G for targets that support them. Signed-off-by: Jordan Crouse --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 14 ++ drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 14 ++ 2 files changed, 28 insertions(+) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index d5f5e56..45662d3 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -749,6 +749,20 @@ static int a5xx_hw_init(struct msm_gpu *gpu) REG_A5XX_RBBM_SECVID_TSB_TRUSTED_BASE_HI, 0x); gpu_write(gpu, REG_A5XX_RBBM_SECVID_TSB_TRUSTED_SIZE, 0x); + /* Put the GPU into 64 bit by default */ + gpu_write(gpu, REG_A5XX_CP_ADDR_MODE_CNTL, 0x1); + gpu_write(gpu, REG_A5XX_VSC_ADDR_MODE_CNTL, 0x1); + gpu_write(gpu, REG_A5XX_GRAS_ADDR_MODE_CNTL, 0x1); + gpu_write(gpu, REG_A5XX_RB_ADDR_MODE_CNTL, 0x1); + gpu_write(gpu, REG_A5XX_PC_ADDR_MODE_CNTL, 0x1); + gpu_write(gpu, REG_A5XX_HLSQ_ADDR_MODE_CNTL, 0x1); + gpu_write(gpu, REG_A5XX_VFD_ADDR_MODE_CNTL, 0x1); + gpu_write(gpu, REG_A5XX_VPC_ADDR_MODE_CNTL, 0x1); + gpu_write(gpu, REG_A5XX_UCHE_ADDR_MODE_CNTL, 0x1); + gpu_write(gpu, REG_A5XX_SP_ADDR_MODE_CNTL, 0x1); + gpu_write(gpu, REG_A5XX_TPL1_ADDR_MODE_CNTL, 0x1); + gpu_write(gpu, REG_A5XX_RBBM_SECVID_TSB_ADDR_MODE_CNTL, 0x1); + ret = adreno_hw_init(gpu); if (ret) return ret; diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index fefe773..1c20d59 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -375,6 +375,20 @@ static int a6xx_hw_init(struct msm_gpu *gpu) REG_A6XX_RBBM_SECVID_TSB_TRUSTED_BASE_HI, 0x); gpu_write(gpu, REG_A6XX_RBBM_SECVID_TSB_TRUSTED_SIZE, 0x); + /* Turn on 64 bit addressing for all blocks */ + gpu_write(gpu, REG_A6XX_CP_ADDR_MODE_CNTL, 0x1); + gpu_write(gpu, REG_A6XX_VSC_ADDR_MODE_CNTL, 0x1); + gpu_write(gpu, REG_A6XX_GRAS_ADDR_MODE_CNTL, 0x1); + gpu_write(gpu, REG_A6XX_RB_ADDR_MODE_CNTL, 0x1); + gpu_write(gpu, REG_A6XX_PC_ADDR_MODE_CNTL, 0x1); + gpu_write(gpu, REG_A6XX_HLSQ_ADDR_MODE_CNTL, 0x1); + gpu_write(gpu, REG_A6XX_VFD_ADDR_MODE_CNTL, 0x1); + gpu_write(gpu, REG_A6XX_VPC_ADDR_MODE_CNTL, 0x1); + gpu_write(gpu, REG_A6XX_UCHE_ADDR_MODE_CNTL, 0x1); + gpu_write(gpu, REG_A6XX_SP_ADDR_MODE_CNTL, 0x1); + gpu_write(gpu, REG_A6XX_TPL1_ADDR_MODE_CNTL, 0x1); + gpu_write(gpu, REG_A6XX_RBBM_SECVID_TSB_ADDR_MODE_CNTL, 0x1); + /* enable hardware clockgating */ a6xx_set_hwcg(gpu, true); -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC PATCH v1 00/15] drm/msm: Per-instance pagetable support
This is the latest incarnation of per-instance pagetable support for the MSM GPU driver. Some of these have been seen before, most recently [1]. Per-instance pagetables allow the target GPU driver to create and manage an individual pagetable for each file descriptor instance and switch between them asynchronously using the GPU to reprogram the pagetable registers on the fly. This is accomplished in this series by taking advantage of the multiple IOMMU domain API from Lu Baolu [2] and all these patches are based on that patch. This series is split into three parts: Part one adds support for split pagetables. These are the same patches from the previous attempts [1]. Split pagetables allow the hardware to switch out the lower pagetable (TTBR0) without affecting the global allocations in the upper one (TTBR1). Part 2 adds aux domain support for arm-smmu-v2. New aux domains create a new pagetable but do not touch the underlying hardware. The target driver uses the new aux domain to map and unmap memory through the usual mechanisms. The final part is the support in the GPU driver to enable 64 bit addressing for a5xx and a6xx, set up the support for split pagetables, create new per-instance pagetables for a new instance and submit the GPU command to switch the pagetable at the appropriate time. This is compile tested but I haven't done much target testing as of yet. I wanted to get this out in the world for debate while we work on fixing up the minor issues. In particular, I want to make sure that this fits with the current thinking about how aux domains should look and feel. [1] https://patchwork.freedesktop.org/series/43447/ [2] https://patchwork.kernel.org/patch/10825061/ Jordan Crouse (15): iommu: Add DOMAIN_ATTR_SPLIT_TABLES iommu/arm-smmu: Add split pagetable support for arm-smmu-v2 iommu/io-pgtable: Allow TLB operations to be optional iommu: Add DOMAIN_ATTR_PTBASE iommu/arm-smmu: Add auxiliary domain support for arm-smmuv2 drm/msm/adreno: Enable 64 bit mode by default on a5xx and a6xx targets drm/msm: Print all 64 bits of the faulting IOMMU address drm/msm: Pass the MMU domain index in struct msm_file_private drm/msm/gpu: Move address space setup to the GPU targets drm/msm: Add support for IOMMU auxiliary domains drm/msm: Add a helper function for a per-instance address space drm/msm: Add support to create target specific address spaces drm/msm/gpu: Add ttbr0 to the memptrs drm/msm/a6xx: Support per-instance pagetables drm/msm/a5xx: Support per-instance pagetables drivers/gpu/drm/msm/adreno/a2xx_gpu.c | 37 ++-- drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 50 -- drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 51 -- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 163 +- drivers/gpu/drm/msm/adreno/a5xx_gpu.h | 19 ++ drivers/gpu/drm/msm/adreno/a5xx_preempt.c | 70 ++-- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 167 +- drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 1 + drivers/gpu/drm/msm/adreno/adreno_gpu.c | 7 - drivers/gpu/drm/msm/msm_drv.c | 25 ++- drivers/gpu/drm/msm/msm_drv.h | 5 + drivers/gpu/drm/msm/msm_gem.h | 2 + drivers/gpu/drm/msm/msm_gem_submit.c | 13 +- drivers/gpu/drm/msm/msm_gem_vma.c | 53 +++--- drivers/gpu/drm/msm/msm_gpu.c | 59 +-- drivers/gpu/drm/msm/msm_gpu.h | 3 + drivers/gpu/drm/msm/msm_iommu.c | 99 ++- drivers/gpu/drm/msm/msm_mmu.h | 4 + drivers/gpu/drm/msm/msm_ringbuffer.h | 1 + drivers/iommu/arm-smmu-regs.h | 18 ++ drivers/iommu/arm-smmu.c | 278 ++ drivers/iommu/io-pgtable-arm.c| 3 +- drivers/iommu/io-pgtable.h| 10 +- include/linux/iommu.h | 2 + 24 files changed, 952 insertions(+), 188 deletions(-) -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/vkms: Solve bug on kms_crc_cursor tests
On Fri, Mar 01, 2019 at 03:35:35PM -0300, Shayenne Moura wrote: > Em sex, 1 de mar de 2019 às 12:26, Ville Syrjälä > escreveu: > > > > On Fri, Mar 01, 2019 at 11:55:11AM -0300, Shayenne Moura wrote: > > > Em qui, 28 de fev de 2019 às 11:03, Ville Syrjälä > > > escreveu: > > > > > > > > On Thu, Feb 28, 2019 at 11:11:07AM +0100, Daniel Vetter wrote: > > > > > On Mon, Feb 25, 2019 at 11:26:06AM -0300, Shayenne Moura wrote: > > > > > > vkms_crc_work_handle needs the value of the actual frame to > > > > > > schedule the workqueue that calls periodically the vblank > > > > > > handler and the destroy state functions. However, the frame > > > > > > value returned from vkms_vblank_simulate is updated and > > > > > > diminished in vblank_get_timestamp because it is not in a > > > > > > vblank interrupt, and return an inaccurate value. > > > > > > > > > > > > Solve this getting the actual vblank frame directly from the > > > > > > vblank->count inside the `struct drm_crtc`, instead of using > > > > > > the `drm_accurate_vblank_count` function. > > > > > > > > > > > > Signed-off-by: Shayenne Moura > > > > > > > > > > Sorry for the delay, I'm a bit swamped right now :-/ > > > > > > > > > > Debug work you're doing here is really impressive! But I have no idea > > > > > what's going on. It doesn't look like it's just papering over a bug > > > > > (like > > > > > the in_vblank_irq check we've discussed on irc), but I also have no > > > > > idea > > > > > why it works. > > > > > > > > > > I'll pull in Ville, he understands this better than me. > > > > > > > > It's not entirely clear what we're trying to fix. From what I can see > > > > the crc work seems to be in no way synchronized with page flips, so > > > > I'm not sure how all this is really supposed to work. > > > > > > > > > > Hi, Ville! > > > > > > Thank you for the review! :) > > > > > > I do not understand well what crc code is doing, but the issue that I > > > found > > > is related to the vblank timestamp and frame count. > > > > > > When vkms handles the crc_cursor it uses the start frame and end frame > > > values to verify if it needs to call the function > > > 'drm_crtc_add_crc_entry()' > > > for each frame. > > > > > > However, when getting the frame count, the code is calling the function > > > drm_update_vblank_count(dev, pipe, false) and, because of the 'false', > > > subtracting the actual vblank timestamp (consequently, the frame count > > > value), causing conflicts. > > > > The in_vblank_irq behavour looks sane to me. What are these conflicts? > > > > The entire history was: > - I sent the patch with bugfix for vblank extra frame. The patch changed >our function vkms_get_vblank_timestamp() to look like this: > > bool vkms_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, >int *max_error, ktime_t *vblank_time, >bool in_vblank_irq) > { > struct vkms_device *vkmsdev = drm_device_to_vkms_device(dev); > struct vkms_output *output = &vkmsdev->output; > > *vblank_time = output->vblank_hrtimer.node.expires; > > + if (!in_vblank_irq) > +*vblank_time -= output->period_ns; > > return true; > } > > - This patch solve the issue that I was looking for (extra vblank > frames on kms_flip). > > - However, kms_cursor_crc tests, which passed before my patch, started to > fail. > > - Debugging them, I found that the problem was inside of function > `vkms_vblank_simulate()` > when it was handling the crc_enabled (inside if (state && > output->crc_enabled)) > and inside the function vkms_crc_work_handle() too. > > - Following the steps: > 1. Inside vkms_vblank_simulate() we call drm_crtc_accurate_vblank_count() > 2. In its turn, drm_crtc_accurate_vblank_count() calls the function >drm_update_vblank_count(dev, pipe, false). /* This false is default */ > 3. Finally, the “false” used in drm_update_vblank_count(), will be > passed to vkms_get_vblank_timestamp() and the condition “if > (!in_vblank_irq)” will be executed multiple times (we don’t want it). > > - Inside vkms_crc, the issue is that the returned frame value change for > every call of drm_crtc_accurate_vblank_count() because > in_vblank_irq == false. OK. So why is it changing? AFAICS it should not change unless the timer was moved forward in between the calls. > > - To solve this, I used the value already calculated on vblank->count, > instead of using the helper function that updates the value. > > Shayenne > > > > > > > Does it make sense? I am not sure about this crc code behavior. > > > > > > Shayenne > > > > > > > > -Daniel > > > > > > > > > > > --- > > > > > > drivers/gpu/drm/vkms/vkms_crc.c | 4 +++- > > > > > > drivers/gpu/drm/vkms/vkms_crtc.c | 4 +++- > > > > > > 2 files changed, 6 insertions(+), 2 deletions(-) > > > > > > > > > > > > diff --git a/drivers/gpu/drm/vkms/vkms_crc.c > > > > > > b/drivers/gpu/drm/vkms/vkms_crc.c > > > > > > index d7b409a3c0f8..09a8b00ef1f1 100644 > >
Re: [PATCH] drm/vkms: Solve bug on kms_crc_cursor tests
Em sex, 1 de mar de 2019 às 12:26, Ville Syrjälä escreveu: > > On Fri, Mar 01, 2019 at 11:55:11AM -0300, Shayenne Moura wrote: > > Em qui, 28 de fev de 2019 às 11:03, Ville Syrjälä > > escreveu: > > > > > > On Thu, Feb 28, 2019 at 11:11:07AM +0100, Daniel Vetter wrote: > > > > On Mon, Feb 25, 2019 at 11:26:06AM -0300, Shayenne Moura wrote: > > > > > vkms_crc_work_handle needs the value of the actual frame to > > > > > schedule the workqueue that calls periodically the vblank > > > > > handler and the destroy state functions. However, the frame > > > > > value returned from vkms_vblank_simulate is updated and > > > > > diminished in vblank_get_timestamp because it is not in a > > > > > vblank interrupt, and return an inaccurate value. > > > > > > > > > > Solve this getting the actual vblank frame directly from the > > > > > vblank->count inside the `struct drm_crtc`, instead of using > > > > > the `drm_accurate_vblank_count` function. > > > > > > > > > > Signed-off-by: Shayenne Moura > > > > > > > > Sorry for the delay, I'm a bit swamped right now :-/ > > > > > > > > Debug work you're doing here is really impressive! But I have no idea > > > > what's going on. It doesn't look like it's just papering over a bug > > > > (like > > > > the in_vblank_irq check we've discussed on irc), but I also have no idea > > > > why it works. > > > > > > > > I'll pull in Ville, he understands this better than me. > > > > > > It's not entirely clear what we're trying to fix. From what I can see > > > the crc work seems to be in no way synchronized with page flips, so > > > I'm not sure how all this is really supposed to work. > > > > > > > Hi, Ville! > > > > Thank you for the review! :) > > > > I do not understand well what crc code is doing, but the issue that I found > > is related to the vblank timestamp and frame count. > > > > When vkms handles the crc_cursor it uses the start frame and end frame > > values to verify if it needs to call the function 'drm_crtc_add_crc_entry()' > > for each frame. > > > > However, when getting the frame count, the code is calling the function > > drm_update_vblank_count(dev, pipe, false) and, because of the 'false', > > subtracting the actual vblank timestamp (consequently, the frame count > > value), causing conflicts. > > The in_vblank_irq behavour looks sane to me. What are these conflicts? > The entire history was: - I sent the patch with bugfix for vblank extra frame. The patch changed our function vkms_get_vblank_timestamp() to look like this: bool vkms_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, int *max_error, ktime_t *vblank_time, bool in_vblank_irq) { struct vkms_device *vkmsdev = drm_device_to_vkms_device(dev); struct vkms_output *output = &vkmsdev->output; *vblank_time = output->vblank_hrtimer.node.expires; + if (!in_vblank_irq) +*vblank_time -= output->period_ns; return true; } - This patch solve the issue that I was looking for (extra vblank frames on kms_flip). - However, kms_cursor_crc tests, which passed before my patch, started to fail. - Debugging them, I found that the problem was inside of function `vkms_vblank_simulate()` when it was handling the crc_enabled (inside if (state && output->crc_enabled)) and inside the function vkms_crc_work_handle() too. - Following the steps: 1. Inside vkms_vblank_simulate() we call drm_crtc_accurate_vblank_count() 2. In its turn, drm_crtc_accurate_vblank_count() calls the function drm_update_vblank_count(dev, pipe, false). /* This false is default */ 3. Finally, the “false” used in drm_update_vblank_count(), will be passed to vkms_get_vblank_timestamp() and the condition “if (!in_vblank_irq)” will be executed multiple times (we don’t want it). - Inside vkms_crc, the issue is that the returned frame value change for every call of drm_crtc_accurate_vblank_count() because in_vblank_irq == false. - To solve this, I used the value already calculated on vblank->count, instead of using the helper function that updates the value. Shayenne > > > > Does it make sense? I am not sure about this crc code behavior. > > > > Shayenne > > > > > > -Daniel > > > > > > > > > --- > > > > > drivers/gpu/drm/vkms/vkms_crc.c | 4 +++- > > > > > drivers/gpu/drm/vkms/vkms_crtc.c | 4 +++- > > > > > 2 files changed, 6 insertions(+), 2 deletions(-) > > > > > > > > > > diff --git a/drivers/gpu/drm/vkms/vkms_crc.c > > > > > b/drivers/gpu/drm/vkms/vkms_crc.c > > > > > index d7b409a3c0f8..09a8b00ef1f1 100644 > > > > > --- a/drivers/gpu/drm/vkms/vkms_crc.c > > > > > +++ b/drivers/gpu/drm/vkms/vkms_crc.c > > > > > @@ -161,6 +161,8 @@ void vkms_crc_work_handle(struct work_struct > > > > > *work) > > > > > struct vkms_output *out = drm_crtc_to_vkms_output(crtc); > > > > > struct vkms_device *vdev = container_of(out, struct vkms_device, > > > > > output); > > > > > + unsigned int pipe = drm_crtc_in
Re: [PATCH v2 05/10] drm/arm/malidp:- Define a common list of AFBC format modifiers supported for DP500, DP550 and DP650
On Tue, Feb 26, 2019 at 04:20:56PM +, Ayan Halder wrote: > From: Ayan Kumar Halder > > We need to define a common list of format modifiers supported by each of > the Mali display processors. > > The following are the constraints with AFBC:- > > 1. AFBC is not supported for the formats defined in > malidp_hw_format_is_linear_only() > > 2. Some of the formats are supported only with AFBC modifiers. Thus we have > introduced a new function 'malidp_hw_format_is_afbc_only()' which verifies > the same. > > 3. AFBC_FORMAT_MOD_YTR needs to be provided for any RGB format. > > 4. Formats <= 16bpp cannot support AFBC_FORMAT_MOD_SPLIT. > > 5. CBR should not be set for non-subsampled formats. > > 6. SMART layer does not support framebuffer with AFBC modifiers. > Return -EINVAL for such a scenario. > > 7. AFBC_FORMAT_MOD_YTR is not supported for any YUV formats. > > 8. Formats which are subsampled cannot support AFBC_FORMAT_MOD_SPLIT. > However in DP550, YUV_420_10BIT is supported with AFBC_FORMAT_MOD_SPLIT. > This feature has been identified with > MALIDP_DEVICE_AFBC_YUV_420_10_SUPPORT_SPLIT. > > 9. In DP550 and DP650, for YUYV, the hardware supports different > format-ids to be used with and without AFBC modifier. We have used the > feature 'MALIDP_DEVICE_AFBC_YUYV_USE_422_P2' to identify this > characteristic. > > 10. DP500 does not support split mode (ie AFBC_FORMAT_MOD_SPLIT). We have > used the feature 'MALIDP_DEVICE_AFBC_SUPPORT_SPLIT' to identify the DPs > which support SPLIT mode. > > 11. DP550 supports YUV420 with split mode. We have defined the feature > 'AFBC_SUPPORT_SPLIT_WITH_YUV_420_10' to identify this characteristic. > > Changes since v1:- > - Merged https://patchwork.freedesktop.org/patch/265215/ into this patch > - As Liviu pointed out in the last patch, we can pull the checks outside > of the 'while (*modifiers != DRM_FORMAT_MOD_INVALID)' loop > - Rebased > > Signed-off-by: Ayan Kumar halder Reviewed-by: Liviu Dudau Best regards, Liviu > --- > drivers/gpu/drm/arm/malidp_drv.c| 32 ++--- > drivers/gpu/drm/arm/malidp_drv.h| 6 ++ > drivers/gpu/drm/arm/malidp_hw.c | 96 +-- > drivers/gpu/drm/arm/malidp_hw.h | 24 +-- > drivers/gpu/drm/arm/malidp_mw.c | 2 +- > drivers/gpu/drm/arm/malidp_planes.c | 126 > +++- > 6 files changed, 246 insertions(+), 40 deletions(-) > > diff --git a/drivers/gpu/drm/arm/malidp_drv.c > b/drivers/gpu/drm/arm/malidp_drv.c > index ab50ad0..c697664 100644 > --- a/drivers/gpu/drm/arm/malidp_drv.c > +++ b/drivers/gpu/drm/arm/malidp_drv.c > @@ -264,37 +264,17 @@ static bool > malidp_verify_afbc_framebuffer_caps(struct drm_device *dev, > const struct drm_mode_fb_cmd2 *mode_cmd) > { > - const struct drm_format_info *info; > - > - if ((mode_cmd->modifier[0] >> 56) != DRM_FORMAT_MOD_VENDOR_ARM) { > - DRM_DEBUG_KMS("Unknown modifier (not Arm)\n"); > + if (malidp_format_mod_supported(dev, mode_cmd->pixel_format, > + mode_cmd->modifier[0]) == false) > return false; > - } > - > - if (mode_cmd->modifier[0] & > - ~DRM_FORMAT_MOD_ARM_AFBC(AFBC_MOD_VALID_BITS)) { > - DRM_DEBUG_KMS("Unsupported modifiers\n"); > - return false; > - } > - > - info = drm_get_format_info(dev, mode_cmd); > - if (!info) { > - DRM_DEBUG_KMS("Unable to get the format information\n"); > - return false; > - } > - > - if (info->num_planes != 1) { > - DRM_DEBUG_KMS("AFBC buffers expect one plane\n"); > - return false; > - } > > if (mode_cmd->offsets[0] != 0) { > DRM_DEBUG_KMS("AFBC buffers' plane offset should be 0\n"); > return false; > } > > - switch (mode_cmd->modifier[0] & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) { > - case AFBC_FORMAT_MOD_BLOCK_SIZE_16x16: > + switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) { > + case AFBC_SIZE_16X16: > if ((mode_cmd->width % 16) || (mode_cmd->height % 16)) { > DRM_DEBUG_KMS("AFBC buffers must be aligned to 16 > pixels\n"); > return false; > @@ -319,8 +299,8 @@ malidp_verify_afbc_framebuffer_size(struct drm_device > *dev, > u32 afbc_superblock_size = 0, afbc_superblock_height = 0; > u32 afbc_superblock_width = 0, afbc_size = 0; > > - switch (mode_cmd->modifier[0] & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) { > - case AFBC_FORMAT_MOD_BLOCK_SIZE_16x16: > + switch (mode_cmd->modifier[0] & AFBC_SIZE_MASK) { > + case AFBC_SIZE_16X16: > afbc_superblock_height = 16; > afbc_superblock_width = 16; > break; > diff --git a/drivers/gpu/drm/arm/malidp_drv.h > b/drivers/gpu/drm/arm/malidp_drv.h > index b76c86f..019a682 100644 > --- a/drivers/gpu/drm/arm/malidp_drv.h > +++ b/drivers/gpu/drm/a
Re: [PATCH] drm/vmwgfx: remove redundant unlikely annotation
Hi Chengguang, Thanks for doing this. Will include this for vmwgfx-next Reviewed-by: Deepak Rawat On Thu, 2019-02-21 at 10:09 +0800, Chengguang Xu wrote: > unlikely has already included in IS_ERR(), so just > remove redundant unlikely annotation. > > Signed-off-by: Chengguang Xu > --- > drivers/gpu/drm/vmwgfx/vmwgfx_context.c | 2 +- > drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 4 ++-- > 2 files changed, 3 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c > b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c > index 14bd760a62fd..694fabafaeee 100644 > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c > @@ -210,7 +210,7 @@ static int vmw_gb_context_init(struct vmw_private > *dev_priv, > for (i = 0; i < SVGA_COTABLE_DX10_MAX; ++i) { > uctx->cotables[i] = vmw_cotable_alloc(dev_priv, > &uctx- > >res, i); > - if (unlikely(IS_ERR(uctx->cotables[i]))) { > + if (IS_ERR(uctx->cotables[i])) { > ret = PTR_ERR(uctx->cotables[i]); > goto out_cotables; > } > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c > b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c > index 88b8178d4687..1cde07cf3067 100644 > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c > @@ -638,7 +638,7 @@ vmw_cmd_res_check(struct vmw_private *dev_priv, > > res = vmw_user_resource_noref_lookup_handle > (dev_priv, sw_context->fp->tfile, *id_loc, > converter); > - if (unlikely(IS_ERR(res))) { > + if (IS_ERR(res)) { > DRM_ERROR("Could not find or use resource > 0x%08x.\n", > (unsigned int) *id_loc); > return PTR_ERR(res); > @@ -3799,7 +3799,7 @@ static int vmw_execbuf_tie_context(struct > vmw_private *dev_priv, > res = vmw_user_resource_noref_lookup_handle > (dev_priv, sw_context->fp->tfile, handle, >user_context_converter); > - if (unlikely(IS_ERR(res))) { > + if (IS_ERR(res)) { > DRM_ERROR("Could not find or user DX context > 0x%08x.\n", > (unsigned) handle); > return PTR_ERR(res); ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v4 03/10] drm/arm/malidp: Set the AFBC register bits if the framebuffer has AFBC modifier
On Tue, Feb 26, 2019 at 04:20:54PM +, Ayan Halder wrote: > From: Ayan Kumar Halder > > Added the AFBC decoder registers for DP500 , DP550 and DP650. > These registers control the processing of AFBC buffers. It controls various > features like AFBC decoder enable, lossless transformation and block split > as well as setting of the left, right, top and bottom cropping of AFBC > buffers (in number of pixels). > All the layers (except DE_SMART) support framebuffers with AFBC modifiers. > One needs to set the pixel values of the top, left, bottom and right > cropping for the AFBC framebuffer. > Cropping an AFBC framebuffer is controlled by the AFBC crop registers. > In that case, the layer input size registers should be configured with > framebuffer's dimensions and not with drm_plane_state source width/height > values (which is used for non AFBC framebuffer to denote cropping). > > Changes from v1: > - Removed the "if (fb->modifier)" check from malidp_de_plane_update() > and added it in malidp_de_set_plane_afbc(). This will consolidate all the > AFBC specific register configurations in a single function ie > malidp_de_set_plane_afbc(). > > Changes from v2: > - For AFBC framebuffer, layer input size register should be set to > framebuffer's width and height. > > Changes from v3: > - Rebased on top of latest drm-misc-next > - Some cleanups/sanity changes based on Liviu's comments > > Signed-off-by: Ayan Kumar Halder Reviewed-by: Liviu Dudau Best regards, Liviu > --- > drivers/gpu/drm/arm/malidp_hw.c | 30 ++ > drivers/gpu/drm/arm/malidp_hw.h | 2 + > drivers/gpu/drm/arm/malidp_planes.c | 107 > > drivers/gpu/drm/arm/malidp_regs.h | 20 +++ > 4 files changed, 136 insertions(+), 23 deletions(-) > > diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c > index b9bed11..64c2ca3 100644 > --- a/drivers/gpu/drm/arm/malidp_hw.c > +++ b/drivers/gpu/drm/arm/malidp_hw.c > @@ -94,11 +94,14 @@ static const struct malidp_layer malidp500_layers[] = { >* yuv2rgb matrix offset, mmu control register offset, > rotation_features >*/ > { DE_VIDEO1, MALIDP500_DE_LV_BASE, MALIDP500_DE_LV_PTR_BASE, > - MALIDP_DE_LV_STRIDE0, MALIDP500_LV_YUV2RGB, 0, ROTATE_ANY }, > + MALIDP_DE_LV_STRIDE0, MALIDP500_LV_YUV2RGB, 0, ROTATE_ANY, > + MALIDP500_DE_LV_AD_CTRL }, > { DE_GRAPHICS1, MALIDP500_DE_LG1_BASE, MALIDP500_DE_LG1_PTR_BASE, > - MALIDP_DE_LG_STRIDE, 0, 0, ROTATE_ANY }, > + MALIDP_DE_LG_STRIDE, 0, 0, ROTATE_ANY, > + MALIDP500_DE_LG1_AD_CTRL }, > { DE_GRAPHICS2, MALIDP500_DE_LG2_BASE, MALIDP500_DE_LG2_PTR_BASE, > - MALIDP_DE_LG_STRIDE, 0, 0, ROTATE_ANY }, > + MALIDP_DE_LG_STRIDE, 0, 0, ROTATE_ANY, > + MALIDP500_DE_LG2_AD_CTRL }, > }; > > static const struct malidp_layer malidp550_layers[] = { > @@ -106,13 +109,16 @@ static const struct malidp_layer malidp550_layers[] = { >* yuv2rgb matrix offset, mmu control register offset, > rotation_features >*/ > { DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE, > - MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB, 0, ROTATE_ANY }, > + MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB, 0, ROTATE_ANY, > + MALIDP550_DE_LV1_AD_CTRL }, > { DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE, > - MALIDP_DE_LG_STRIDE, 0, 0, ROTATE_ANY }, > + MALIDP_DE_LG_STRIDE, 0, 0, ROTATE_ANY, > + MALIDP550_DE_LG_AD_CTRL }, > { DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE, > - MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB, 0, ROTATE_ANY }, > + MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB, 0, ROTATE_ANY, > + MALIDP550_DE_LV2_AD_CTRL }, > { DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE, > - MALIDP550_DE_LS_R1_STRIDE, 0, 0, ROTATE_NONE }, > + MALIDP550_DE_LS_R1_STRIDE, 0, 0, ROTATE_NONE, 0 }, > }; > > static const struct malidp_layer malidp650_layers[] = { > @@ -122,16 +128,18 @@ static const struct malidp_layer malidp650_layers[] = { >*/ > { DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE, > MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB, > - MALIDP650_DE_LV_MMU_CTRL, ROTATE_ANY }, > + MALIDP650_DE_LV_MMU_CTRL, ROTATE_ANY, > + MALIDP550_DE_LV1_AD_CTRL }, > { DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE, > MALIDP_DE_LG_STRIDE, 0, MALIDP650_DE_LG_MMU_CTRL, > - ROTATE_COMPRESSED }, > + ROTATE_COMPRESSED, MALIDP550_DE_LG_AD_CTRL }, > { DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE, > MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB, > - MALIDP650_DE_LV_MMU_CTRL, ROTATE_ANY }, > + MALIDP
[Bug 109329] Luxmark freezes the system
https://bugs.freedesktop.org/show_bug.cgi?id=109329 --- Comment #2 from Fabian Maurer --- The default scene, I guess. Sorry, I don't know what exactly you mean - I just run the program without any parameters, and then it freezes. I'd test more, but currently luxmark doesn't build on my system. -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 109693] Hang of the graphics driver and assertion on si_upload_vertex_buffer_descriptors
https://bugs.freedesktop.org/show_bug.cgi?id=109693 --- Comment #1 from Tim Müller --- Would be great if someone could take a look at this, as it might affect more users once the next GStreamer stable release is out. -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 202445] amdgpu/dc: framerate dropping below adaptive sync range causes screen flickering
https://bugzilla.kernel.org/show_bug.cgi?id=202445 --- Comment #22 from Clément Guérin (li...@protonmail.com) --- Great news. Can you confirm that https://bugzilla.kernel.org/show_bug.cgi?id=202445#c16 is not related to this issue? -- You are receiving this mail because: You are watching the assignee of the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 202445] amdgpu/dc: framerate dropping below adaptive sync range causes screen flickering
https://bugzilla.kernel.org/show_bug.cgi?id=202445 --- Comment #21 from Nicholas Kazlauskas (nicholas.kazlaus...@amd.com) --- I'll let you know when it's up so you can try it. It should resolve the issue, but if it doesn't it will at least help narrow down the cause. -- You are receiving this mail because: You are watching the assignee of the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 202445] amdgpu/dc: framerate dropping below adaptive sync range causes screen flickering
https://bugzilla.kernel.org/show_bug.cgi?id=202445 --- Comment #20 from Nicholas Kazlauskas (nicholas.kazlaus...@amd.com) --- That patch certainly helps for the case where the pageflip was submitted during vblank (the frontporch will no longer timeout, causing flickering). The video you recorded helped identify what I think is the specific issue in this case though - I believe that the implementation is frequently changing the BTR target instead or prioritizing the last used target rate. There should be a fix for this coming soon, it should also apply to 5.0 once it's done. Thanks for the report! -- You are receiving this mail because: You are watching the assignee of the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 201763] amdgpu: [powerplay] VBIOS did not find boot engine clock value in dependency table. Using Memory DPM level 0!
https://bugzilla.kernel.org/show_bug.cgi?id=201763 --- Comment #7 from Michel Dänzer (mic...@daenzer.net) --- (In reply to Rogério Brito from comment #5) > First of all, sorry for the late reply. I had really a really bad start of > the year (death in family, complications caused by that, health problems, > fire at home and also recovering from that hard hit etc.) Nothing to apologize for, I hope things are (getting) better for you now! > (In reply to Michel Dänzer from comment #2) > > From the dmesg output, it looks like the AMD GPU is powered off most of the > > time. Do the freezes happen when you explicitly use it for something, e.g. > > for a game via DRI_PRIME=1? > > I never play games (really, the only game that I played in the last few > years was 2048 on a browser), but I guess that other applications may use > the discrete AMD GPU that this notebook has. The AMD GPU should only be used if you explicitly choose to, by setting DRI_PRIME=1 or maybe using a corresponding setting of your desktop environment. Maybe the AMD GPU is only getting powered up accidentally, and the freezes happen due to something going wrong while powering it up/down. Please attach the corresponding Xorg log file, preferably captured after dmesg has at least two instances of [drm] PCIE GART of 256M enabled (table at 0x00F4). You could also try modprobe.blacklist=amdgpu on the kernel command line, to see if the freezes happen even if the amdgpu driver never initializes the AMD GPU. -- You are receiving this mail because: You are watching the assignee of the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 1/5] drm: Add helpers to kick off PSR enable/disable
On Fri, Mar 01, 2019 at 09:18:13AM +0100, Daniel Vetter wrote: > On Thu, Feb 28, 2019 at 04:09:30PM -0500, Sean Paul wrote: > > From: Sean Paul > > > > This patch adds a new drm helper library to help drivers implement > > PSR. Drivers choosing to use it will register connectors with > > PSR-capable displays connected and will receive callbacks when it's time > > to enter or exit PSR. > > > > In its current form, it has a timer which will trigger after a > > driver-specified amount of inactivity. When the timer triggers, the > > helpers will save the current atomic state and issue a new state which > > has the PSR-enabled pipes turned off. On the next update, the drm core > > will poke the PSR helpers to restore the saved state to the driver before > > servicing said update. > > > > From the driver's perspective, this works like a regular disable/enable > > cycle. The driver need only check the 'psr_transition' state in > > connector_state and keep the panel turned on when in .disable(), while > > everything else will cycle off as normal. If drivers want more control, > > they can use the psr_transition state to enter a low-power state to > > minimize PSR exit time. > > > > While this carries the PSR moniker, it is not specific to the > > DisplayPort technology. This can be used for power savings with other > > types of self refresh, such as MIPI command mode. > > > > Cc: Zain Wang > > Cc: Tomasz Figa > > Signed-off-by: Sean Paul /snip to the good part > > So for the high-level design, before looking at the implementation > details: > - I agree with Jose that a per-crtc state sounds more like what we want, > instead of global. Just from a conceptual point. Agreed this would be better. I was mostly worried about resource sharing between crtcs. ie: If 2 crtcs share a clock, 1 goes to PSR and the other changes the rate to something incompatible. However I suppose the driver would be responsible for sussing this all out, so sure. It'll be nice to avoid the global lock for psr. > - We can imo flat-out require that your driver is using the fancy new > dirtyfb helpers to remap the dirtyfb call to an atomic update. It's the > clean design for sw controlled manual update displays anyway. > - That means your single entry points (instead of trying to catch all of > them like above, and missing some like you do) are ->atomic_check and > ->atomic_commit. That also gives you the clean hook into helpers. The reason I did this was because new state was being calculated off the disabled state. So the psr disable commit needed to precede the atomic check. However, with your suggestions below I think we can avoid that :) > - The duplicated state only works when no one else is looking, it's very > fragile. single-threaded (from a driver pov) suspend/resume is ok, I > don't think it's a good idea to expand this. Yeah, fair. I was trying to stay out of the way of the existing code, but I'll integrate more tightly. > > Here's what I'd do: > - Stuff a new self_refresh_active state into drm_crtc_state (not sure we > should call this psr or self_refresh - latter is imo better name since > not associated with DP, but longer). I struggled with this too, naming is hard. > > - Use crtc_state->self_refresh_active and crtc_state->active to compute > the reported active state to userspace in the get_prop functions. This > because doing a mass search&replace over all drivers is too much. > Something like > > real_active == active || self_refresh > > - In duplicate_state always reset the state > active = real_active(); > self_refresh = false; > to disable self refresh and set active to what userspace the "ACTIVE" > property should be. We'll also have to alter the flags when they don't include DRM_MODE_ATOMIC_ALLOW_MODESET, and async commits would need to go through the synchronous path. Conversely, non-blocking commits will get back to userspace more quickly with this design. This is the primary reason I kept the psr disable in a separate commit, so the original request could go through as intended (albeit a bit delayed, but there's no getting around that). > > - self_refresh state in connector_state sounds like a good idea > > - Your idle worker would do a normal atomic commit, no evil state > duplicate, and then set: > self_fresh = active; > active = false; > Handling races left as an exercise :-) > > - Somewhere in the commit helpers put a function to arm your idle work > (per-crtc imo simplest). > > This should give you a clean lasagne going from core ioctl -> core atomic > -> helpers <-> drivers. And not the spaghetti sprawl of finely sprinkling > the self refresh helpers all over. Alright, I'll mock this up and see if it floats. Thanks for the detailed feedback! Sean > > Aside: Going snowboarding next week, so if this is a bonghits idea I'm > afraid will take 1 week until I can spin something new :-) > > Cheers, Daniel > > > diff --gi
Re: [PATCH] drm/vkms: Solve bug on kms_crc_cursor tests
On Fri, Mar 01, 2019 at 11:55:11AM -0300, Shayenne Moura wrote: > Em qui, 28 de fev de 2019 às 11:03, Ville Syrjälä > escreveu: > > > > On Thu, Feb 28, 2019 at 11:11:07AM +0100, Daniel Vetter wrote: > > > On Mon, Feb 25, 2019 at 11:26:06AM -0300, Shayenne Moura wrote: > > > > vkms_crc_work_handle needs the value of the actual frame to > > > > schedule the workqueue that calls periodically the vblank > > > > handler and the destroy state functions. However, the frame > > > > value returned from vkms_vblank_simulate is updated and > > > > diminished in vblank_get_timestamp because it is not in a > > > > vblank interrupt, and return an inaccurate value. > > > > > > > > Solve this getting the actual vblank frame directly from the > > > > vblank->count inside the `struct drm_crtc`, instead of using > > > > the `drm_accurate_vblank_count` function. > > > > > > > > Signed-off-by: Shayenne Moura > > > > > > Sorry for the delay, I'm a bit swamped right now :-/ > > > > > > Debug work you're doing here is really impressive! But I have no idea > > > what's going on. It doesn't look like it's just papering over a bug (like > > > the in_vblank_irq check we've discussed on irc), but I also have no idea > > > why it works. > > > > > > I'll pull in Ville, he understands this better than me. > > > > It's not entirely clear what we're trying to fix. From what I can see > > the crc work seems to be in no way synchronized with page flips, so > > I'm not sure how all this is really supposed to work. > > > > Hi, Ville! > > Thank you for the review! :) > > I do not understand well what crc code is doing, but the issue that I found > is related to the vblank timestamp and frame count. > > When vkms handles the crc_cursor it uses the start frame and end frame > values to verify if it needs to call the function 'drm_crtc_add_crc_entry()' > for each frame. > > However, when getting the frame count, the code is calling the function > drm_update_vblank_count(dev, pipe, false) and, because of the 'false', > subtracting the actual vblank timestamp (consequently, the frame count > value), causing conflicts. The in_vblank_irq behavour looks sane to me. What are these conflicts? > > Does it make sense? I am not sure about this crc code behavior. > > Shayenne > > > > -Daniel > > > > > > > --- > > > > drivers/gpu/drm/vkms/vkms_crc.c | 4 +++- > > > > drivers/gpu/drm/vkms/vkms_crtc.c | 4 +++- > > > > 2 files changed, 6 insertions(+), 2 deletions(-) > > > > > > > > diff --git a/drivers/gpu/drm/vkms/vkms_crc.c > > > > b/drivers/gpu/drm/vkms/vkms_crc.c > > > > index d7b409a3c0f8..09a8b00ef1f1 100644 > > > > --- a/drivers/gpu/drm/vkms/vkms_crc.c > > > > +++ b/drivers/gpu/drm/vkms/vkms_crc.c > > > > @@ -161,6 +161,8 @@ void vkms_crc_work_handle(struct work_struct *work) > > > > struct vkms_output *out = drm_crtc_to_vkms_output(crtc); > > > > struct vkms_device *vdev = container_of(out, struct vkms_device, > > > > output); > > > > + unsigned int pipe = drm_crtc_index(crtc); > > > > + struct drm_vblank_crtc *vblank = &crtc->dev->vblank[pipe]; > > > > struct vkms_crc_data *primary_crc = NULL; > > > > struct vkms_crc_data *cursor_crc = NULL; > > > > struct drm_plane *plane; > > > > @@ -196,7 +198,7 @@ void vkms_crc_work_handle(struct work_struct *work) > > > > if (primary_crc) > > > > crc32 = _vkms_get_crc(primary_crc, cursor_crc); > > > > > > > > - frame_end = drm_crtc_accurate_vblank_count(crtc); > > > > + frame_end = vblank->count; > > > > > > > > /* queue_work can fail to schedule crc_work; add crc for > > > > * missing frames > > > > diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c > > > > b/drivers/gpu/drm/vkms/vkms_crtc.c > > > > index 8a9aeb0a9ea8..9bf3268e2e92 100644 > > > > --- a/drivers/gpu/drm/vkms/vkms_crtc.c > > > > +++ b/drivers/gpu/drm/vkms/vkms_crtc.c > > > > @@ -10,6 +10,8 @@ static enum hrtimer_restart > > > > vkms_vblank_simulate(struct hrtimer *timer) > > > > vblank_hrtimer); > > > > struct drm_crtc *crtc = &output->crtc; > > > > struct vkms_crtc_state *state = to_vkms_crtc_state(crtc->state); > > > > + unsigned int pipe = drm_crtc_index(crtc); > > > > + struct drm_vblank_crtc *vblank = &crtc->dev->vblank[pipe]; > > > > u64 ret_overrun; > > > > bool ret; > > > > > > > > @@ -20,7 +22,7 @@ static enum hrtimer_restart > > > > vkms_vblank_simulate(struct hrtimer *timer) > > > > DRM_ERROR("vkms failure on handling vblank"); > > > > > > > > if (state && output->crc_enabled) { > > > > - u64 frame = drm_crtc_accurate_vblank_count(crtc); > > > > + u64 frame = vblank->count; > > > > > > > > /* update frame_start only if a queued > > > > vkms_crc_work_handle() > > > > * has read the data > > > > -- > > > > 2.17.1 > > > > > > > > > > -- > > > Daniel Vetter > > > Software Engineer, Intel Corporation > > > ht
Re: [PATCH 12/17] drm/rcar-du: Convert to using __drm_atomic_helper_crtc_reset() for reset.
Hi Marteen, On Fri, Mar 01, 2019 at 03:47:02PM +0100, Maarten Lankhorst wrote: > Op 01-03-2019 om 15:36 schreef Laurent Pinchart: > > On Fri, Mar 01, 2019 at 03:08:20PM +0100, Maarten Lankhorst wrote: > >> Op 01-03-2019 om 14:13 schreef Laurent Pinchart: > >>> On Fri, Mar 01, 2019 at 01:56:22PM +0100, Maarten Lankhorst wrote: > Convert rcar-du to using __drm_atomic_helper_crtc_reset(), instead of > writing its own version. Instead of open coding destroy_state(), call > it directly for freeing the old state. > >>> I don't think the second sentence applies to this patch. > >>> > Signed-off-by: Maarten Lankhorst > Cc: Laurent Pinchart > Cc: Kieran Bingham > Cc: linux-renesas-...@vger.kernel.org > --- > drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 11 +++ > 1 file changed, 3 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c > b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c > index 4cdea14d552f..7766551e67fc 100644 > --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c > +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c > @@ -891,22 +891,17 @@ static void rcar_du_crtc_cleanup(struct drm_crtc > *crtc) > > static void rcar_du_crtc_reset(struct drm_crtc *crtc) > { > -struct rcar_du_crtc_state *state; > +struct rcar_du_crtc_state *state = kzalloc(sizeof(*state), > GFP_KERNEL); > > -if (crtc->state) { > +if (crtc->state) > rcar_du_crtc_atomic_destroy_state(crtc, crtc->state); > -crtc->state = NULL; > -} > > -state = kzalloc(sizeof(*state), GFP_KERNEL); > +__drm_atomic_helper_crtc_reset(crtc, &state->state); > >>> state may be NULL here if the above kzalloc() failed. Let's keep the > >>> original order of the function, and simply call > >>> __drm_atomic_helper_crtc_reset() after the NULL check below. > >> There were 10 different ways crtc was implemented, I felt it was good to > >> settle on one. > >> > >> We don't handle during reset at all, would need to start propagating this > >> first before we should handle errors, imho. > > That's not the point. As state can be NULL, you could end up > > dereferencing a NULL pointer. The fact that the base state is the first > > field in the rcar_du_crtc_state structure is just luck, and shouldn't be > > relied on. > > Would it be ok if I changed it to state ? &state->state : NULL and let > the compiler deal with it? What's wrong with a proper implementation ? static void rcar_du_crtc_reset(struct drm_crtc *crtc) { struct rcar_du_crtc_state *state; if (crtc->state) { rcar_du_crtc_atomic_destroy_state(crtc, crtc->state); crtc->state = NULL; } state = kzalloc(sizeof(*state), GFP_KERNEL); if (state == NULL) return; __drm_atomic_helper_crtc_reset(crtc, &state->state); state->crc.source = VSP1_DU_CRC_NONE; state->crc.index = 0; } > Will probably fix up all other patches as well before committing. You won't commit this one before I ack it, right ? :-) > >> Looking more closely, it's the same way that errors in > >> rcar_du_plane_reset() are handled. :) > > It's not, the return value of kzalloc() is checked explicitly in > > rcar_du_plane_reset() before calling __drm_atomic_helper_plane_reset(). > > Please copy the code flow of rcar_du_plane_reset() to implement > > rcar_du_crtc_reset(). -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 0/3] drm/sun4i: DE2/DE3 improvements
On Thu, Feb 28, 2019 at 09:03:26PM +0100, Jernej Skrabec wrote: > DE2 and DE3 VI channels support coarse scaling to overcome VI scaler > limitations. That is especially useful for downscaling big planes, for > example 4K to 1080p. > > Following patches were tested on H3 and A64 with 4K video playback on > 1080p monitor. Without them, picture was mangled. Applied all three, thanks! Maxime -- Maxime Ripard, Bootlin Embedded Linux and Kernel engineering https://bootlin.com signature.asc Description: PGP signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/vkms: Solve bug on kms_crc_cursor tests
Em qui, 28 de fev de 2019 às 11:03, Ville Syrjälä escreveu: > > On Thu, Feb 28, 2019 at 11:11:07AM +0100, Daniel Vetter wrote: > > On Mon, Feb 25, 2019 at 11:26:06AM -0300, Shayenne Moura wrote: > > > vkms_crc_work_handle needs the value of the actual frame to > > > schedule the workqueue that calls periodically the vblank > > > handler and the destroy state functions. However, the frame > > > value returned from vkms_vblank_simulate is updated and > > > diminished in vblank_get_timestamp because it is not in a > > > vblank interrupt, and return an inaccurate value. > > > > > > Solve this getting the actual vblank frame directly from the > > > vblank->count inside the `struct drm_crtc`, instead of using > > > the `drm_accurate_vblank_count` function. > > > > > > Signed-off-by: Shayenne Moura > > > > Sorry for the delay, I'm a bit swamped right now :-/ > > > > Debug work you're doing here is really impressive! But I have no idea > > what's going on. It doesn't look like it's just papering over a bug (like > > the in_vblank_irq check we've discussed on irc), but I also have no idea > > why it works. > > > > I'll pull in Ville, he understands this better than me. > > It's not entirely clear what we're trying to fix. From what I can see > the crc work seems to be in no way synchronized with page flips, so > I'm not sure how all this is really supposed to work. > Hi, Ville! Thank you for the review! :) I do not understand well what crc code is doing, but the issue that I found is related to the vblank timestamp and frame count. When vkms handles the crc_cursor it uses the start frame and end frame values to verify if it needs to call the function 'drm_crtc_add_crc_entry()' for each frame. However, when getting the frame count, the code is calling the function drm_update_vblank_count(dev, pipe, false) and, because of the 'false', subtracting the actual vblank timestamp (consequently, the frame count value), causing conflicts. Does it make sense? I am not sure about this crc code behavior. Shayenne > > -Daniel > > > > > --- > > > drivers/gpu/drm/vkms/vkms_crc.c | 4 +++- > > > drivers/gpu/drm/vkms/vkms_crtc.c | 4 +++- > > > 2 files changed, 6 insertions(+), 2 deletions(-) > > > > > > diff --git a/drivers/gpu/drm/vkms/vkms_crc.c > > > b/drivers/gpu/drm/vkms/vkms_crc.c > > > index d7b409a3c0f8..09a8b00ef1f1 100644 > > > --- a/drivers/gpu/drm/vkms/vkms_crc.c > > > +++ b/drivers/gpu/drm/vkms/vkms_crc.c > > > @@ -161,6 +161,8 @@ void vkms_crc_work_handle(struct work_struct *work) > > > struct vkms_output *out = drm_crtc_to_vkms_output(crtc); > > > struct vkms_device *vdev = container_of(out, struct vkms_device, > > > output); > > > + unsigned int pipe = drm_crtc_index(crtc); > > > + struct drm_vblank_crtc *vblank = &crtc->dev->vblank[pipe]; > > > struct vkms_crc_data *primary_crc = NULL; > > > struct vkms_crc_data *cursor_crc = NULL; > > > struct drm_plane *plane; > > > @@ -196,7 +198,7 @@ void vkms_crc_work_handle(struct work_struct *work) > > > if (primary_crc) > > > crc32 = _vkms_get_crc(primary_crc, cursor_crc); > > > > > > - frame_end = drm_crtc_accurate_vblank_count(crtc); > > > + frame_end = vblank->count; > > > > > > /* queue_work can fail to schedule crc_work; add crc for > > > * missing frames > > > diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c > > > b/drivers/gpu/drm/vkms/vkms_crtc.c > > > index 8a9aeb0a9ea8..9bf3268e2e92 100644 > > > --- a/drivers/gpu/drm/vkms/vkms_crtc.c > > > +++ b/drivers/gpu/drm/vkms/vkms_crtc.c > > > @@ -10,6 +10,8 @@ static enum hrtimer_restart vkms_vblank_simulate(struct > > > hrtimer *timer) > > > vblank_hrtimer); > > > struct drm_crtc *crtc = &output->crtc; > > > struct vkms_crtc_state *state = to_vkms_crtc_state(crtc->state); > > > + unsigned int pipe = drm_crtc_index(crtc); > > > + struct drm_vblank_crtc *vblank = &crtc->dev->vblank[pipe]; > > > u64 ret_overrun; > > > bool ret; > > > > > > @@ -20,7 +22,7 @@ static enum hrtimer_restart vkms_vblank_simulate(struct > > > hrtimer *timer) > > > DRM_ERROR("vkms failure on handling vblank"); > > > > > > if (state && output->crc_enabled) { > > > - u64 frame = drm_crtc_accurate_vblank_count(crtc); > > > + u64 frame = vblank->count; > > > > > > /* update frame_start only if a queued vkms_crc_work_handle() > > > * has read the data > > > -- > > > 2.17.1 > > > > > > > -- > > Daniel Vetter > > Software Engineer, Intel Corporation > > http://blog.ffwll.ch > > ___ > > dri-devel mailing list > > dri-devel@lists.freedesktop.org > > https://lists.freedesktop.org/mailman/listinfo/dri-devel > > -- > Ville Syrjälä > Intel ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/
Re: [PATCH -next] fbdev: omap2: omapfb: trivial code cleanup
Hi, On 03/01/2019 02:53 AM, Yue Haibing wrote: > From: YueHaibing > > After commit 60d2fa0dad06 ("fbdev: omap2: no need to check > return value of debugfs_create functions"), there are corner > code need to be cleaned. > > Signed-off-by: YueHaibing Thanks but I've already applied earlier patch from Anders Roxell: https://marc.info/?l=linux-fbdev&m=155004766902831&w=2 > --- > drivers/video/fbdev/omap2/omapfb/dss/core.c | 3 --- > 1 file changed, 3 deletions(-) > > diff --git a/drivers/video/fbdev/omap2/omapfb/dss/core.c > b/drivers/video/fbdev/omap2/omapfb/dss/core.c > index 7e6a3eb..b5956a1 100644 > --- a/drivers/video/fbdev/omap2/omapfb/dss/core.c > +++ b/drivers/video/fbdev/omap2/omapfb/dss/core.c > @@ -136,7 +136,6 @@ static inline void dss_uninitialize_debugfs(void) > } > void dss_debugfs_create_file(const char *name, void (*write)(struct seq_file > *)) > { > - return 0; > } > #endif /* CONFIG_FB_OMAP2_DSS_DEBUGFS */ > > @@ -169,8 +168,6 @@ static struct notifier_block omap_dss_pm_notif_block = { > > static int __init omap_dss_probe(struct platform_device *pdev) > { > - int r; > - > core.pdev = pdev; > > dss_features_init(omapdss_get_version()); Best regards, -- Bartlomiej Zolnierkiewicz Samsung R&D Institute Poland Samsung Electronics ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 12/17] drm/rcar-du: Convert to using __drm_atomic_helper_crtc_reset() for reset.
Op 01-03-2019 om 15:36 schreef Laurent Pinchart: > Hi Marteen, > > On Fri, Mar 01, 2019 at 03:08:20PM +0100, Maarten Lankhorst wrote: >> Op 01-03-2019 om 14:13 schreef Laurent Pinchart: >>> On Fri, Mar 01, 2019 at 01:56:22PM +0100, Maarten Lankhorst wrote: Convert rcar-du to using __drm_atomic_helper_crtc_reset(), instead of writing its own version. Instead of open coding destroy_state(), call it directly for freeing the old state. >>> I don't think the second sentence applies to this patch. >>> Signed-off-by: Maarten Lankhorst Cc: Laurent Pinchart Cc: Kieran Bingham Cc: linux-renesas-...@vger.kernel.org --- drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 11 +++ 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index 4cdea14d552f..7766551e67fc 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c @@ -891,22 +891,17 @@ static void rcar_du_crtc_cleanup(struct drm_crtc *crtc) static void rcar_du_crtc_reset(struct drm_crtc *crtc) { - struct rcar_du_crtc_state *state; + struct rcar_du_crtc_state *state = kzalloc(sizeof(*state), GFP_KERNEL); - if (crtc->state) { + if (crtc->state) rcar_du_crtc_atomic_destroy_state(crtc, crtc->state); - crtc->state = NULL; - } - state = kzalloc(sizeof(*state), GFP_KERNEL); + __drm_atomic_helper_crtc_reset(crtc, &state->state); >>> state may be NULL here if the above kzalloc() failed. Let's keep the >>> original order of the function, and simply call >>> __drm_atomic_helper_crtc_reset() after the NULL check below. >> There were 10 different ways crtc was implemented, I felt it was good to >> settle on one. >> >> We don't handle during reset at all, would need to start propagating this >> first before we should handle errors, imho. > That's not the point. As state can be NULL, you could end up > dereferencing a NULL pointer. The fact that the base state is the first > field in the rcar_du_crtc_state structure is just luck, and shouldn't be > relied on. Would it be ok if I changed it to state ? &state->state : NULL and let the compiler deal with it? Will probably fix up all other patches as well before committing. >> Looking more closely, it's the same way that errors in >> rcar_du_plane_reset() are handled. :) > It's not, the return value of kzalloc() is checked explicitly in > rcar_du_plane_reset() before calling __drm_atomic_helper_plane_reset(). > Please copy the code flow of rcar_du_plane_reset() to implement > rcar_du_crtc_reset(). > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] fbdev: omap2: fix warnings in dss core
On 02/13/2019 09:47 AM, Anders Roxell wrote: > Commit 60d2fa0dad06 ("fbdev: omap2: no need to check return value of > debugfs_create functions") changed the declaration of the return value > of function dss_debugfs_create_file() and the following two warnings > appeared: > > drivers/video/fbdev/omap2/omapfb/dss/core.c: In function > ‘dss_debugfs_create_file’: > drivers/video/fbdev/omap2/omapfb/dss/core.c:139:9: warning: ‘return’ with a > value, > in function returning void > return 0; > ^ > drivers/video/fbdev/omap2/omapfb/dss/core.c: In function ‘omap_dss_probe’: > drivers/video/fbdev/omap2/omapfb/dss/core.c:172:6: warning: unused variable > ‘r’ > [-Wunused-variable] > int r; > ^ > > Rework so function dss_debugfs_create_file() that is declared to return > void don't 'return 0' and remove the declaration of the unused variable > 'r'. > > Signed-off-by: Anders Roxell Patch queued for v5.1, thanks. Best regards, -- Bartlomiej Zolnierkiewicz Samsung R&D Institute Poland Samsung Electronics ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 12/17] drm/rcar-du: Convert to using __drm_atomic_helper_crtc_reset() for reset.
Hi Marteen, On Fri, Mar 01, 2019 at 03:08:20PM +0100, Maarten Lankhorst wrote: > Op 01-03-2019 om 14:13 schreef Laurent Pinchart: > > On Fri, Mar 01, 2019 at 01:56:22PM +0100, Maarten Lankhorst wrote: > >> Convert rcar-du to using __drm_atomic_helper_crtc_reset(), instead of > >> writing its own version. Instead of open coding destroy_state(), call > >> it directly for freeing the old state. > > I don't think the second sentence applies to this patch. > > > >> Signed-off-by: Maarten Lankhorst > >> Cc: Laurent Pinchart > >> Cc: Kieran Bingham > >> Cc: linux-renesas-...@vger.kernel.org > >> --- > >> drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 11 +++ > >> 1 file changed, 3 insertions(+), 8 deletions(-) > >> > >> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c > >> b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c > >> index 4cdea14d552f..7766551e67fc 100644 > >> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c > >> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c > >> @@ -891,22 +891,17 @@ static void rcar_du_crtc_cleanup(struct drm_crtc > >> *crtc) > >> > >> static void rcar_du_crtc_reset(struct drm_crtc *crtc) > >> { > >> - struct rcar_du_crtc_state *state; > >> + struct rcar_du_crtc_state *state = kzalloc(sizeof(*state), GFP_KERNEL); > >> > >> - if (crtc->state) { > >> + if (crtc->state) > >>rcar_du_crtc_atomic_destroy_state(crtc, crtc->state); > >> - crtc->state = NULL; > >> - } > >> > >> - state = kzalloc(sizeof(*state), GFP_KERNEL); > >> + __drm_atomic_helper_crtc_reset(crtc, &state->state); > > > > state may be NULL here if the above kzalloc() failed. Let's keep the > > original order of the function, and simply call > > __drm_atomic_helper_crtc_reset() after the NULL check below. > > There were 10 different ways crtc was implemented, I felt it was good to > settle on one. > > We don't handle during reset at all, would need to start propagating this > first before we should handle errors, imho. That's not the point. As state can be NULL, you could end up dereferencing a NULL pointer. The fact that the base state is the first field in the rcar_du_crtc_state structure is just luck, and shouldn't be relied on. > Looking more closely, it's the same way that errors in > rcar_du_plane_reset() are handled. :) It's not, the return value of kzalloc() is checked explicitly in rcar_du_plane_reset() before calling __drm_atomic_helper_plane_reset(). Please copy the code flow of rcar_du_plane_reset() to implement rcar_du_crtc_reset(). -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/virtio: Allow userspace to mmap() framebuffer
On Fri, 2019-03-01 at 06:51 +0100, Gerd Hoffmann wrote: > On Thu, Feb 28, 2019 at 10:47:41AM -0600, Joshua Watt wrote: > > Reports the size of the virtgpu framebuffer to userspace and > > installs > > the deferred I/O handlers so that userspace can mmap() and write to > > it. > > Fixed already, as side effect of switching virtio to the generic > fbdev > emulation. Patches are in the drm-misc-next branch and should land > upstream in the 5.1 merge window. Excellent. I gave it a try and that did what I needed. Thanks! > > cheers, > Gerd > -- Joshua Watt ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 12/17] drm/rcar-du: Convert to using __drm_atomic_helper_crtc_reset() for reset.
Op 01-03-2019 om 14:13 schreef Laurent Pinchart: > Hi Maarten, > > Thank you for the patch. > > On Fri, Mar 01, 2019 at 01:56:22PM +0100, Maarten Lankhorst wrote: >> Convert rcar-du to using __drm_atomic_helper_crtc_reset(), instead of >> writing its own version. Instead of open coding destroy_state(), call >> it directly for freeing the old state. > I don't think the second sentence applies to this patch. > >> Signed-off-by: Maarten Lankhorst >> Cc: Laurent Pinchart >> Cc: Kieran Bingham >> Cc: linux-renesas-...@vger.kernel.org >> --- >> drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 11 +++ >> 1 file changed, 3 insertions(+), 8 deletions(-) >> >> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c >> b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c >> index 4cdea14d552f..7766551e67fc 100644 >> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c >> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c >> @@ -891,22 +891,17 @@ static void rcar_du_crtc_cleanup(struct drm_crtc *crtc) >> >> static void rcar_du_crtc_reset(struct drm_crtc *crtc) >> { >> -struct rcar_du_crtc_state *state; >> +struct rcar_du_crtc_state *state = kzalloc(sizeof(*state), GFP_KERNEL); >> >> -if (crtc->state) { >> +if (crtc->state) >> rcar_du_crtc_atomic_destroy_state(crtc, crtc->state); >> -crtc->state = NULL; >> -} >> >> -state = kzalloc(sizeof(*state), GFP_KERNEL); >> +__drm_atomic_helper_crtc_reset(crtc, &state->state); > state may be NULL here if the above kzalloc() failed. Let's keep the > original order of the function, and simply call > __drm_atomic_helper_crtc_reset() after the NULL check below. There were 10 different ways crtc was implemented, I felt it was good to settle on one. We don't handle during reset at all, would need to start propagating this first before we should handle errors, imho. Looking more closely, it's the same way that errors in rcar_du_plane_reset() are handled. :) Cheers, ~Maarten ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 05/17] drm/mali: Convert to using __drm_atomic_helper_crtc_reset() for reset.
Hi Maarten, On Fri, Mar 01, 2019 at 01:56:15PM +0100, Maarten Lankhorst wrote: > Convert mali to using __drm_atomic_helper_crtc_reset(), instead of > writing its own version. Instead of open coding > malidp_crtc_destroy_state(), call it directly for freeing the old state. > > Signed-off-by: Maarten Lankhorst > Cc: Liviu Dudau Acked-by: Liviu Dudau If you need me to take this patch into malidp tree let me know, otherwise I expect is going to show up in drm-misc-next at some moment. Best regards, Liviu > Cc: Brian Starkey > --- > drivers/gpu/drm/arm/malidp_crtc.c | 28 +++- > 1 file changed, 11 insertions(+), 17 deletions(-) > > diff --git a/drivers/gpu/drm/arm/malidp_crtc.c > b/drivers/gpu/drm/arm/malidp_crtc.c > index 56aad288666e..d6690e016f0b 100644 > --- a/drivers/gpu/drm/arm/malidp_crtc.c > +++ b/drivers/gpu/drm/arm/malidp_crtc.c > @@ -463,23 +463,6 @@ static struct drm_crtc_state > *malidp_crtc_duplicate_state(struct drm_crtc *crtc) > return &state->base; > } > > -static void malidp_crtc_reset(struct drm_crtc *crtc) > -{ > - struct malidp_crtc_state *state = NULL; > - > - if (crtc->state) { > - state = to_malidp_crtc_state(crtc->state); > - __drm_atomic_helper_crtc_destroy_state(crtc->state); > - } > - > - kfree(state); > - state = kzalloc(sizeof(*state), GFP_KERNEL); > - if (state) { > - crtc->state = &state->base; > - crtc->state->crtc = crtc; > - } > -} > - > static void malidp_crtc_destroy_state(struct drm_crtc *crtc, > struct drm_crtc_state *state) > { > @@ -493,6 +476,17 @@ static void malidp_crtc_destroy_state(struct drm_crtc > *crtc, > kfree(mali_state); > } > > +static void malidp_crtc_reset(struct drm_crtc *crtc) > +{ > + struct malidp_crtc_state *state = > + kzalloc(sizeof(*state), GFP_KERNEL); > + > + if (crtc->state) > + malidp_crtc_destroy_state(crtc, crtc->state); > + > + __drm_atomic_helper_crtc_reset(crtc, &state->base); > +} > + > static int malidp_crtc_enable_vblank(struct drm_crtc *crtc) > { > struct malidp_drm *malidp = crtc_to_malidp_device(crtc); > -- > 2.20.1 > > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel -- | I would like to | | fix the world, | | but they're not | | giving me the | \ source code! / --- ¯\_(ツ)_/¯ ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 12/17] drm/rcar-du: Convert to using __drm_atomic_helper_crtc_reset() for reset.
Hi Maarten, Thank you for the patch. On Fri, Mar 01, 2019 at 01:56:22PM +0100, Maarten Lankhorst wrote: > Convert rcar-du to using __drm_atomic_helper_crtc_reset(), instead of > writing its own version. Instead of open coding destroy_state(), call > it directly for freeing the old state. I don't think the second sentence applies to this patch. > Signed-off-by: Maarten Lankhorst > Cc: Laurent Pinchart > Cc: Kieran Bingham > Cc: linux-renesas-...@vger.kernel.org > --- > drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 11 +++ > 1 file changed, 3 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c > b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c > index 4cdea14d552f..7766551e67fc 100644 > --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c > +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c > @@ -891,22 +891,17 @@ static void rcar_du_crtc_cleanup(struct drm_crtc *crtc) > > static void rcar_du_crtc_reset(struct drm_crtc *crtc) > { > - struct rcar_du_crtc_state *state; > + struct rcar_du_crtc_state *state = kzalloc(sizeof(*state), GFP_KERNEL); > > - if (crtc->state) { > + if (crtc->state) > rcar_du_crtc_atomic_destroy_state(crtc, crtc->state); > - crtc->state = NULL; > - } > > - state = kzalloc(sizeof(*state), GFP_KERNEL); > + __drm_atomic_helper_crtc_reset(crtc, &state->state); state may be NULL here if the above kzalloc() failed. Let's keep the original order of the function, and simply call __drm_atomic_helper_crtc_reset() after the NULL check below. > if (state == NULL) > return; > > state->crc.source = VSP1_DU_CRC_NONE; > state->crc.index = 0; > - > - crtc->state = &state->state; > - crtc->state->crtc = crtc; > } > > static int rcar_du_crtc_enable_vblank(struct drm_crtc *crtc) -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 3/3] drm/panel: Add Rocktech jh057n00900 panel driver
Support Rocktech jh057n00900 5.5" 720x1440 TFT LCD panel. It is a MIPI DSI video mode panel. The panel seems to use a Sitronix ST7703 look alike (most of the commands look similar to the ST7703's data sheet but use a different number of parameters). The initial version of the DSI init sequence (including sleeps) were provided by the vendor. Sleeps were reduced considerably though to speed up initialization. Signed-off-by: Guido Günther Cc: guido.gunt...@puri.sm --- drivers/gpu/drm/panel/Kconfig | 13 + drivers/gpu/drm/panel/Makefile| 1 + .../drm/panel/panel-rocktech-jh057n00900.c| 385 ++ 3 files changed, 399 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-rocktech-jh057n00900.c diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index 3e070153ef21..42f541fe57ae 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -149,6 +149,19 @@ config DRM_PANEL_RAYDIUM_RM68200 Say Y here if you want to enable support for Raydium RM68200 720x1280 DSI video mode panel. +config DRM_PANEL_ROCKTECH_JH057N00900 + tristate "Rocktech JH057N00900 MIPI touchscreen panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to enable support for Rocktech JH057N00900 + MIPI DSI panel as e.g. used in the Librem 5 devkit. It has a + resolution of 720x1440 pixels, a built in backlight and touch + controller. + Touch input support is provided by the goodix driver and needs to be + selected separately. + config DRM_PANEL_SAMSUNG_S6D16D0 tristate "Samsung S6D16D0 DSI video mode panel" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index e7ab71968bbf..902e871059d0 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_DRM_PANEL_ORISETECH_OTM8009A) += panel-orisetech-otm8009a.o obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o obj-$(CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN) += panel-raspberrypi-touchscreen.o obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM68200) += panel-raydium-rm68200.o +obj-$(CONFIG_DRM_PANEL_ROCKTECH_JH057N00900) += panel-rocktech-jh057n00900.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6D16D0) += panel-samsung-s6d16d0.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2) += panel-samsung-s6e3ha2.o diff --git a/drivers/gpu/drm/panel/panel-rocktech-jh057n00900.c b/drivers/gpu/drm/panel/panel-rocktech-jh057n00900.c new file mode 100644 index ..7df72040a90d --- /dev/null +++ b/drivers/gpu/drm/panel/panel-rocktech-jh057n00900.c @@ -0,0 +1,385 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Rockteck jh057n00900 5.5" MIPI-DSI panel driver + * + * Copyright (C) Purism SPC 2019 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "jh057n00900" + +/* Manufacturer specific Commands send via DSI */ +#define ST7703_CMD_ALL_PIXEL_OFF 0x22 +#define ST7703_CMD_ALL_PIXEL_ON 0x23 +#define ST7703_CMD_SETDISP 0xB2 +#define ST7703_CMD_SETRGBIF 0xB3 +#define ST7703_CMD_SETCYC 0xB4 +#define ST7703_CMD_SETBGP 0xB5 +#define ST7703_CMD_SETVCOM 0xB6 +#define ST7703_CMD_SETOTP 0xB7 +#define ST7703_CMD_SETPOWER_EXT 0xB8 +#define ST7703_CMD_SETEXTC 0xB9 +#define ST7703_CMD_SETMIPI 0xBA +#define ST7703_CMD_SETVDC 0xBC +#define ST7703_CMD_SETSCR 0xC0 +#define ST7703_CMD_SETPOWER 0xC1 +#define ST7703_CMD_SETPANEL 0xCC +#define ST7703_CMD_SETGAMMA 0xE0 +#define ST7703_CMD_SETEQ0xE3 +#define ST7703_CMD_SETGIP1 0xE9 +#define ST7703_CMD_SETGIP2 0xEA + +struct jh057n { + struct device *dev; + struct drm_panel panel; + struct gpio_desc *reset_gpio; + struct backlight_device *backlight; + bool prepared; + + struct dentry *debugfs; +}; + +static inline struct jh057n *panel_to_jh057n(struct drm_panel *panel) +{ + return container_of(panel, struct jh057n, panel); +} + +#define dsi_generic_write_seq(dsi, seq...) do { \ + static const u8 d[] = { seq }; \ + int ret;\ + ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d));\ + if (ret < 0)\ + return ret; \ + } while (0) + +static int jh057n_init_sequence(struct jh057n *ctx) +{ + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); + struct device *dev = ctx->dev; + int ret; + + /* +* Init sequ
[PATCH v2 1/3] dt-bindings: Add vendor prefix for ROCKTECH DISPLAYS LIMITED
Add ROCKTECH DISPLAYS LIMITED (https://rocktech.com.hk) LCD panel supplier. Signed-off-by: Guido Günther --- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 413c6f30ce88..cc24619a4249 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -338,6 +338,7 @@ ricoh Ricoh Co. Ltd. rikomagic Rikomagic Tech Corp. Ltd riscv RISC-V Foundation rockchip Fuzhou Rockchip Electronics Co., Ltd +rocktech ROCKTECH DISPLAYS LIMITED rohm ROHM Semiconductor Co., Ltd roofullShenzhen Roofull Technology Co, Ltd samsungSamsung Semiconductor -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 0/3] drm/panel: Support Rocktech jh057n00900 DSI panel
It's a 5.5" 720x1440 TFT LCD MIPI DSI panel with built in touchscreen and backlight as found in the Librem 5 devkit. These patches are against linux next as of 2019-02-08. Changes from v1 * As per review comments from Sam Ravnborg * Make SPDX-License-Identifier match MODULE_LICENSE * Sort include files alphabetically * Drop drmP.h and use individual includes * Drop superfuous 'x' in mode printout on error path * Allpixelson_set: Add proper space around '*' * Drop superfluous put_device(&ctx->backlight->dev); * Add /* Sentinel */ in jh057n_of_match * Drop jh057n->enabled * Drop drm_display_info_set_bus_formats * Kconfig: Depend on BACKLIGHT_CLASS_DEVICE which somehow got lost * Move jh057n_enable close to jh057n_disable Guido Günther (3): dt-bindings: Add vendor prefix for ROCKTECH DISPLAYS LIMITED dt-bindings: Add Rocktech jh057n00900 panel bindings drm/panel: Add Rocktech jh057n00900 panel driver .../display/panel/rocktech,jh057n00900.txt| 18 + .../devicetree/bindings/vendor-prefixes.txt | 1 + drivers/gpu/drm/panel/Kconfig | 13 + drivers/gpu/drm/panel/Makefile| 1 + .../drm/panel/panel-rocktech-jh057n00900.c| 385 ++ 5 files changed, 418 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.txt create mode 100644 drivers/gpu/drm/panel/panel-rocktech-jh057n00900.c -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 2/3] dt-bindings: Add Rocktech jh057n00900 panel bindings
The Rocktec jh057n00900 is a 5.5" MIPI DSI video mode panel with a 720x1440 resolution and a built in backlight. Signed-off-by: Guido Günther --- .../display/panel/rocktech,jh057n00900.txt | 18 ++ 1 file changed, 18 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.txt diff --git a/Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.txt b/Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.txt new file mode 100644 index ..32f4001d2d6f --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.txt @@ -0,0 +1,18 @@ +Rocktech jh057n00900 5.5" 720x1440 TFT LCD panel + +Required properties: +- compatible: should be "rocktech,jh057n00900" +- reg: DSI virtual channel of the peripheral +- reset-gpios: panel reset gpio +- backlight: phandle of the backlight device attached to the panel + +Example: + + &mipi_dsi { + panel { + compatible = "rocktech,jh057n00900"; + reg = <0>; + backlight = <&backlight>; + reset-gpios = <&gpio3 13 GPIO_ACTIVE_LOW>; + }; + }; -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 16/17] drm/vkms: Convert to using __drm_atomic_helper_crtc_reset() for reset.
Convert vkms to using __drm_atomic_helper_crtc_reset(), instead of writing its own version. Instead of open coding destroy_state(), call it directly for freeing the old state. Signed-off-by: Maarten Lankhorst Cc: Rodrigo Siqueira Cc: Haneen Mohammed Cc: Daniel Vetter --- drivers/gpu/drm/vkms/vkms_crtc.c | 33 +--- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c index 8a9aeb0a9ea8..550888e72c96 100644 --- a/drivers/gpu/drm/vkms/vkms_crtc.c +++ b/drivers/gpu/drm/vkms/vkms_crtc.c @@ -83,26 +83,6 @@ bool vkms_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, return true; } -static void vkms_atomic_crtc_reset(struct drm_crtc *crtc) -{ - struct vkms_crtc_state *vkms_state = NULL; - - if (crtc->state) { - vkms_state = to_vkms_crtc_state(crtc->state); - __drm_atomic_helper_crtc_destroy_state(crtc->state); - kfree(vkms_state); - crtc->state = NULL; - } - - vkms_state = kzalloc(sizeof(*vkms_state), GFP_KERNEL); - if (!vkms_state) - return; - INIT_WORK(&vkms_state->crc_work, vkms_crc_work_handle); - - crtc->state = &vkms_state->base; - crtc->state->crtc = crtc; -} - static struct drm_crtc_state * vkms_atomic_crtc_duplicate_state(struct drm_crtc *crtc) { @@ -135,6 +115,19 @@ static void vkms_atomic_crtc_destroy_state(struct drm_crtc *crtc, } } +static void vkms_atomic_crtc_reset(struct drm_crtc *crtc) +{ + struct vkms_crtc_state *vkms_state = + kzalloc(sizeof(*vkms_state), GFP_KERNEL); + + if (crtc->state) + vkms_atomic_crtc_destroy_state(crtc, crtc->state); + + __drm_atomic_helper_crtc_reset(crtc, &vkms_state->base); + if (vkms_state) + INIT_WORK(&vkms_state->crc_work, vkms_crc_work_handle); +} + static const struct drm_crtc_funcs vkms_crtc_funcs = { .set_config = drm_atomic_helper_set_config, .destroy= drm_crtc_cleanup, -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 14/17] drm/tegra: Convert to using __drm_atomic_helper_crtc_reset() for reset.
Convert tegra to using __drm_atomic_helper_crtc_reset(), instead of writing its own version. Instead of open coding destroy_state(), call it directly for freeing the old state. Signed-off-by: Maarten Lankhorst Cc: Thierry Reding Cc: Jonathan Hunter Cc: linux-te...@vger.kernel.org --- drivers/gpu/drm/tegra/dc.c | 30 +++--- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 607a6ea17ecc..57c88d78cdaa 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -1153,25 +1153,6 @@ static void tegra_dc_destroy(struct drm_crtc *crtc) drm_crtc_cleanup(crtc); } -static void tegra_crtc_reset(struct drm_crtc *crtc) -{ - struct tegra_dc_state *state; - - if (crtc->state) - __drm_atomic_helper_crtc_destroy_state(crtc->state); - - kfree(crtc->state); - crtc->state = NULL; - - state = kzalloc(sizeof(*state), GFP_KERNEL); - if (state) { - crtc->state = &state->base; - crtc->state->crtc = crtc; - } - - drm_crtc_vblank_reset(crtc); -} - static struct drm_crtc_state * tegra_crtc_atomic_duplicate_state(struct drm_crtc *crtc) { @@ -1198,6 +1179,17 @@ static void tegra_crtc_atomic_destroy_state(struct drm_crtc *crtc, kfree(state); } +static void tegra_crtc_reset(struct drm_crtc *crtc) +{ + struct tegra_dc_state *state = kzalloc(sizeof(*state), GFP_KERNEL); + + if (crtc->state) + tegra_crtc_atomic_destroy_state(crtc, crtc->state); + + __drm_atomic_helper_crtc_reset(crtc, &state->base); + drm_crtc_vblank_reset(crtc); +} + #define DEBUGFS_REG32(_name) { .name = #_name, .offset = _name } static const struct debugfs_reg32 tegra_dc_regs[] = { -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 17/17] drm/vmwgfx: Convert to using __drm_atomic_helper_crtc_reset() for reset.
Convert vmwgfx to using __drm_atomic_helper_crtc_reset(), instead of writing its own version. Instead of open coding destroy_state(), call it directly for freeing the old state. Signed-off-by: Maarten Lankhorst Cc: Thomas Hellstrom --- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 20 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index ed2f67822f45..602f549f09f6 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -611,24 +611,12 @@ vmw_du_crtc_duplicate_state(struct drm_crtc *crtc) */ void vmw_du_crtc_reset(struct drm_crtc *crtc) { - struct vmw_crtc_state *vcs; - - - if (crtc->state) { - __drm_atomic_helper_crtc_destroy_state(crtc->state); - - kfree(vmw_crtc_state_to_vcs(crtc->state)); - } + struct vmw_crtc_state *vcs = kzalloc(sizeof(*vcs), GFP_KERNEL); - vcs = kzalloc(sizeof(*vcs), GFP_KERNEL); - - if (!vcs) { - DRM_ERROR("Cannot allocate vmw_crtc_state\n"); - return; - } + if (crtc->state) + vmw_du_crtc_destroy_state(crtc, crtc->state); - crtc->state = &vcs->base; - crtc->state->crtc = crtc; + __drm_atomic_helper_crtc_reset(crtc, &vcs->base); } -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 01/17] drm/vc4: Fix memory leak during gpu reset.
__drm_atomic_helper_crtc_destroy_state does not free memory, it only cleans it up. Fix this by calling the functions own destroy function. Fixes: 6d6e50039187 ("drm/vc4: Allocate the right amount of space for boot-time CRTC state.") Cc: Eric Anholt Cc: # v4.6+ Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/vc4/vc4_crtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 730008d3da76..e7c04a9eb219 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -1042,7 +1042,7 @@ static void vc4_crtc_reset(struct drm_crtc *crtc) { if (crtc->state) - __drm_atomic_helper_crtc_destroy_state(crtc->state); + vc4_crtc_destroy_state(crtc->state); crtc->state = kzalloc(sizeof(struct vc4_crtc_state), GFP_KERNEL); if (crtc->state) -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 09/17] drm/mediatek: Convert to using __drm_atomic_helper_crtc_reset() for reset.
Convert mediatek to using __drm_atomic_helper_crtc_reset(), instead of writing its own version. Instead of open coding destroy_state(), call it directly for freeing the old state. Signed-off-by: Maarten Lankhorst Cc: CK Hu Cc: Philipp Zabel Cc: Matthias Brugger --- drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 29 + 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index acad088173da..3b18bbadd415 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -108,25 +108,6 @@ static void mtk_drm_crtc_destroy(struct drm_crtc *crtc) drm_crtc_cleanup(crtc); } -static void mtk_drm_crtc_reset(struct drm_crtc *crtc) -{ - struct mtk_crtc_state *state; - - if (crtc->state) { - __drm_atomic_helper_crtc_destroy_state(crtc->state); - - state = to_mtk_crtc_state(crtc->state); - memset(state, 0, sizeof(*state)); - } else { - state = kzalloc(sizeof(*state), GFP_KERNEL); - if (!state) - return; - crtc->state = &state->base; - } - - state->base.crtc = crtc; -} - static struct drm_crtc_state *mtk_drm_crtc_duplicate_state(struct drm_crtc *crtc) { struct mtk_crtc_state *state; @@ -150,6 +131,16 @@ static void mtk_drm_crtc_destroy_state(struct drm_crtc *crtc, kfree(to_mtk_crtc_state(state)); } +static void mtk_drm_crtc_reset(struct drm_crtc *crtc) +{ + struct mtk_crtc_state *state = kzalloc(sizeof(*state), GFP_KERNEL); + + if (crtc->state) + mtk_drm_crtc_destroy_state(crtc, &state->base); + + __drm_atomic_helper_crtc_reset(crtc, &state->base); +} + static bool mtk_drm_crtc_mode_fixup(struct drm_crtc *crtc, const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 05/17] drm/mali: Convert to using __drm_atomic_helper_crtc_reset() for reset.
Convert mali to using __drm_atomic_helper_crtc_reset(), instead of writing its own version. Instead of open coding malidp_crtc_destroy_state(), call it directly for freeing the old state. Signed-off-by: Maarten Lankhorst Cc: Liviu Dudau Cc: Brian Starkey --- drivers/gpu/drm/arm/malidp_crtc.c | 28 +++- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/arm/malidp_crtc.c b/drivers/gpu/drm/arm/malidp_crtc.c index 56aad288666e..d6690e016f0b 100644 --- a/drivers/gpu/drm/arm/malidp_crtc.c +++ b/drivers/gpu/drm/arm/malidp_crtc.c @@ -463,23 +463,6 @@ static struct drm_crtc_state *malidp_crtc_duplicate_state(struct drm_crtc *crtc) return &state->base; } -static void malidp_crtc_reset(struct drm_crtc *crtc) -{ - struct malidp_crtc_state *state = NULL; - - if (crtc->state) { - state = to_malidp_crtc_state(crtc->state); - __drm_atomic_helper_crtc_destroy_state(crtc->state); - } - - kfree(state); - state = kzalloc(sizeof(*state), GFP_KERNEL); - if (state) { - crtc->state = &state->base; - crtc->state->crtc = crtc; - } -} - static void malidp_crtc_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state *state) { @@ -493,6 +476,17 @@ static void malidp_crtc_destroy_state(struct drm_crtc *crtc, kfree(mali_state); } +static void malidp_crtc_reset(struct drm_crtc *crtc) +{ + struct malidp_crtc_state *state = + kzalloc(sizeof(*state), GFP_KERNEL); + + if (crtc->state) + malidp_crtc_destroy_state(crtc, crtc->state); + + __drm_atomic_helper_crtc_reset(crtc, &state->base); +} + static int malidp_crtc_enable_vblank(struct drm_crtc *crtc) { struct malidp_drm *malidp = crtc_to_malidp_device(crtc); -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 00/17] drm: Start subclassing crtc_state.
When we want to start adding default values to crtc_state, it makes sense fix all drivers to call __drm_atomic_helper_crtc_reset, like we do for connectors and planes. Maarten Lankhorst (17): drm/vc4: Fix memory leak during gpu reset. drm/atomic: Create __drm_atomic_helper_crtc_reset() for subclassing crtc_state. drm/docs: Fix typo in __drm_atomic_helper_connector_reset drm/amd: Convert to using __drm_atomic_helper_crtc_reset() for reset. drm/mali: Convert to using __drm_atomic_helper_crtc_reset() for reset. drm/atmel-hlcdc: Convert to using __drm_atomic_helper_crtc_reset() for reset. drm/i915: Use the new __drm_atomic_helper_crtc_reset() helper. drm/imx: Convert to using __drm_atomic_helper_crtc_reset() for reset. drm/mediatek: Convert to using __drm_atomic_helper_crtc_reset() for reset. drm/msm: Convert to using __drm_atomic_helper_crtc_reset() for reset. drm/omap: Convert to using __drm_atomic_helper_crtc_reset() for reset. drm/rcar-du: Convert to using __drm_atomic_helper_crtc_reset() for reset. drm/rockchip: Convert to using __drm_atomic_helper_crtc_reset() for reset. drm/tegra: Convert to using __drm_atomic_helper_crtc_reset() for reset. drm/vc4: Convert to using __drm_atomic_helper_crtc_reset() for reset. drm/vkms: Convert to using __drm_atomic_helper_crtc_reset() for reset. drm/vmwgfx: Convert to using __drm_atomic_helper_crtc_reset() for reset. .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 ++ drivers/gpu/drm/arm/malidp_crtc.c | 28 ++- .../gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c| 29 ++- drivers/gpu/drm/drm_atomic_state_helper.c | 36 +++ drivers/gpu/drm/i915/intel_display.c | 5 ++- drivers/gpu/drm/imx/ipuv3-crtc.c | 30 ++-- drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 29 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 6 ++-- drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 28 ++- drivers/gpu/drm/nouveau/dispnv50/head.c | 13 ++- drivers/gpu/drm/omapdrm/omap_crtc.c | 11 +++--- drivers/gpu/drm/rcar-du/rcar_du_crtc.c| 11 ++ drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 22 ++-- drivers/gpu/drm/tegra/dc.c| 30 ++-- drivers/gpu/drm/vc4/vc4_crtc.c| 9 ++--- drivers/gpu/drm/vkms/vkms_crtc.c | 33 +++-- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 20 +++ include/drm/drm_atomic_state_helper.h | 2 ++ 18 files changed, 145 insertions(+), 207 deletions(-) -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 15/17] drm/vc4: Convert to using __drm_atomic_helper_crtc_reset() for reset.
Convert vc4 to using __drm_atomic_helper_crtc_reset(), instead of writing its own version. Instead of open coding destroy_state(), call it directly for freeing the old state. Signed-off-by: Maarten Lankhorst Cc: Eric Anholt --- drivers/gpu/drm/vc4/vc4_crtc.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index e7c04a9eb219..fdf21594b050 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -1041,12 +1041,13 @@ static void vc4_crtc_destroy_state(struct drm_crtc *crtc, static void vc4_crtc_reset(struct drm_crtc *crtc) { - if (crtc->state) - vc4_crtc_destroy_state(crtc->state); + struct vc4_crtc_state *crtc_state = + kzalloc(sizeof(*crtc_state), GFP_KERNEL); - crtc->state = kzalloc(sizeof(struct vc4_crtc_state), GFP_KERNEL); if (crtc->state) - crtc->state->crtc = crtc; + vc4_crtc_destroy_state(crtc, crtc->state); + + __drm_atomic_helper_crtc_reset(crtc, &crtc_state->base); } static const struct drm_crtc_funcs vc4_crtc_funcs = { -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 11/17] drm/omap: Convert to using __drm_atomic_helper_crtc_reset() for reset.
Convert omap to using __drm_atomic_helper_crtc_reset(), instead of writing its own version. Instead of open coding destroy_state(), call it directly for freeing the old state. Signed-off-by: Maarten Lankhorst Cc: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/omap_crtc.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index d99e24dcc0bf..2546002b1c5c 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -549,14 +549,13 @@ static int omap_crtc_atomic_get_property(struct drm_crtc *crtc, static void omap_crtc_reset(struct drm_crtc *crtc) { - if (crtc->state) - __drm_atomic_helper_crtc_destroy_state(crtc->state); - - kfree(crtc->state); - crtc->state = kzalloc(sizeof(struct omap_crtc_state), GFP_KERNEL); + struct omap_crtc_state *crtc_state = + kzalloc(sizeof(*crtc_state), GFP_KERNEL); if (crtc->state) - crtc->state->crtc = crtc; + drm_atomic_helper_crtc_destroy_state(crtc, crtc->state); + + __drm_atomic_helper_crtc_reset(crtc, &crtc_state->base); } static struct drm_crtc_state * -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 12/17] drm/rcar-du: Convert to using __drm_atomic_helper_crtc_reset() for reset.
Convert rcar-du to using __drm_atomic_helper_crtc_reset(), instead of writing its own version. Instead of open coding destroy_state(), call it directly for freeing the old state. Signed-off-by: Maarten Lankhorst Cc: Laurent Pinchart Cc: Kieran Bingham Cc: linux-renesas-...@vger.kernel.org --- drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 11 +++ 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index 4cdea14d552f..7766551e67fc 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c @@ -891,22 +891,17 @@ static void rcar_du_crtc_cleanup(struct drm_crtc *crtc) static void rcar_du_crtc_reset(struct drm_crtc *crtc) { - struct rcar_du_crtc_state *state; + struct rcar_du_crtc_state *state = kzalloc(sizeof(*state), GFP_KERNEL); - if (crtc->state) { + if (crtc->state) rcar_du_crtc_atomic_destroy_state(crtc, crtc->state); - crtc->state = NULL; - } - state = kzalloc(sizeof(*state), GFP_KERNEL); + __drm_atomic_helper_crtc_reset(crtc, &state->state); if (state == NULL) return; state->crc.source = VSP1_DU_CRC_NONE; state->crc.index = 0; - - crtc->state = &state->state; - crtc->state->crtc = crtc; } static int rcar_du_crtc_enable_vblank(struct drm_crtc *crtc) -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 10/17] drm/msm: Convert to using __drm_atomic_helper_crtc_reset() for reset.
Convert msm to using __drm_atomic_helper_crtc_reset(), instead of writing its own version. Instead of open coding destroy_state(), call it directly for freeing the old state. Signed-off-by: Maarten Lankhorst Cc: Rob Clark Cc: Sean Paul --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 6 ++--- drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 28 +-- 2 files changed, 13 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index b776fca571f3..eb156cb73dd4 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -753,14 +753,12 @@ void dpu_crtc_commit_kickoff(struct drm_crtc *crtc, bool async) static void dpu_crtc_reset(struct drm_crtc *crtc) { - struct dpu_crtc_state *cstate; + struct dpu_crtc_state *cstate = kzalloc(sizeof(*cstate), GFP_KERNEL); if (crtc->state) dpu_crtc_destroy_state(crtc, crtc->state); - crtc->state = kzalloc(sizeof(*cstate), GFP_KERNEL); - if (crtc->state) - crtc->state->crtc = crtc; + __drm_atomic_helper_crtc_reset(crtc, &cstate->base); } /** diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c index b0cf63c4e3d7..bf24a08feab9 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c @@ -1002,23 +1002,6 @@ mdp5_crtc_atomic_print_state(struct drm_printer *p, drm_printf(p, "\tcmd_mode=%d\n", mdp5_cstate->cmd_mode); } -static void mdp5_crtc_reset(struct drm_crtc *crtc) -{ - struct mdp5_crtc_state *mdp5_cstate; - - if (crtc->state) { - __drm_atomic_helper_crtc_destroy_state(crtc->state); - kfree(to_mdp5_crtc_state(crtc->state)); - } - - mdp5_cstate = kzalloc(sizeof(*mdp5_cstate), GFP_KERNEL); - - if (mdp5_cstate) { - mdp5_cstate->base.crtc = crtc; - crtc->state = &mdp5_cstate->base; - } -} - static struct drm_crtc_state * mdp5_crtc_duplicate_state(struct drm_crtc *crtc) { @@ -1046,6 +1029,17 @@ static void mdp5_crtc_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state kfree(mdp5_cstate); } +static void mdp5_crtc_reset(struct drm_crtc *crtc) +{ + struct mdp5_crtc_state *mdp5_cstate = + mdp5_cstate = kzalloc(sizeof(*mdp5_cstate), GFP_KERNEL); + + if (crtc->state) + mdp5_crtc_destroy_state(crtc, crtc->state); + + __drm_atomic_helper_crtc_reset(crtc, &mdp5_cstate->base); +} + static const struct drm_crtc_funcs mdp5_crtc_funcs = { .set_config = drm_atomic_helper_set_config, .destroy = mdp5_crtc_destroy, -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 13/17] drm/rockchip: Convert to using __drm_atomic_helper_crtc_reset() for reset.
Convert rockchip to using __drm_atomic_helper_crtc_reset(), instead of writing its own version. Instead of open coding destroy_state(), call it directly for freeing the old state. Signed-off-by: Maarten Lankhorst Cc: Sandy Huang Cc: "Heiko Stübner" Cc: linux-rockc...@lists.infradead.org --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 22 ++--- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index c7d4c6073ea5..1cf1658f1c01 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -1201,17 +1201,6 @@ static void vop_crtc_destroy(struct drm_crtc *crtc) drm_crtc_cleanup(crtc); } -static void vop_crtc_reset(struct drm_crtc *crtc) -{ - if (crtc->state) - __drm_atomic_helper_crtc_destroy_state(crtc->state); - kfree(crtc->state); - - crtc->state = kzalloc(sizeof(struct rockchip_crtc_state), GFP_KERNEL); - if (crtc->state) - crtc->state->crtc = crtc; -} - static struct drm_crtc_state *vop_crtc_duplicate_state(struct drm_crtc *crtc) { struct rockchip_crtc_state *rockchip_state; @@ -1233,6 +1222,17 @@ static void vop_crtc_destroy_state(struct drm_crtc *crtc, kfree(s); } +static void vop_crtc_reset(struct drm_crtc *crtc) +{ + struct rockchip_crtc_state *crtc_state = + kzalloc(sizeof(*crtc_state), GFP_KERNEL); + + if (crtc->state) + vop_crtc_destroy_state(crtc, crtc->state); + + __drm_atomic_helper_crtc_reset(crtc, &crtc_state->base); +} + #ifdef CONFIG_DRM_ANALOGIX_DP static struct drm_connector *vop_get_edp_connector(struct vop *vop) { -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 03/17] drm/docs: Fix typo in __drm_atomic_helper_connector_reset
Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/drm_atomic_state_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index bc5ee66f75b3..172c8c698a46 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -335,7 +335,7 @@ EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state); * @conn_state: connector state to assign * * Initializes the newly allocated @conn_state and assigns it to - * the &drm_conector->state pointer of @connector, usually required when + * the &drm_connector->state pointer of @connector, usually required when * initializing the drivers or when called from the &drm_connector_funcs.reset * hook. * -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 07/17] drm/i915: Use the new __drm_atomic_helper_crtc_reset() helper.
i915 has its own hw readout and doesn't use the reset helpers directly. Still it has 2 places where it initialises the crtc_state. Fix those by calling __drm_atomic_helper_crtc_reset(). Signed-off-by: Maarten Lankhorst Cc: Jani Nikula Cc: Joonas Lahtinen Cc: Rodrigo Vivi --- drivers/gpu/drm/i915/intel_display.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 7c5e84ef5171..2e14a50dbf6f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -14447,9 +14447,8 @@ static int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe) ret = -ENOMEM; goto fail; } + __drm_atomic_helper_crtc_reset(&intel_crtc->base, &crtc_state->base); intel_crtc->config = crtc_state; - intel_crtc->base.state = &crtc_state->base; - crtc_state->base.crtc = &intel_crtc->base; primary = intel_primary_plane_create(dev_priv, pipe); if (IS_ERR(primary)) { @@ -15986,7 +15985,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) __drm_atomic_helper_crtc_destroy_state(&crtc_state->base); memset(crtc_state, 0, sizeof(*crtc_state)); - crtc_state->base.crtc = &crtc->base; + __drm_atomic_helper_crtc_reset(&crtc->base, &crtc_state->base); crtc_state->base.active = crtc_state->base.enable = dev_priv->display.get_pipe_config(crtc, crtc_state); -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 06/17] drm/atmel-hlcdc: Convert to using __drm_atomic_helper_crtc_reset() for reset.
Convert atmel-hlcdc to using __drm_atomic_helper_crtc_reset(), instead of writing its own version. Instead of open coding destroy_state(), call it directly for freeing the old state. Signed-off-by: Maarten Lankhorst Cc: Boris Brezillon --- .../gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c| 29 +++ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c index 8070a558d7b1..816161d0a09d 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c @@ -400,24 +400,6 @@ void atmel_hlcdc_crtc_irq(struct drm_crtc *c) atmel_hlcdc_crtc_finish_page_flip(drm_crtc_to_atmel_hlcdc_crtc(c)); } -static void atmel_hlcdc_crtc_reset(struct drm_crtc *crtc) -{ - struct atmel_hlcdc_crtc_state *state; - - if (crtc->state) { - __drm_atomic_helper_crtc_destroy_state(crtc->state); - state = drm_crtc_state_to_atmel_hlcdc_crtc_state(crtc->state); - kfree(state); - crtc->state = NULL; - } - - state = kzalloc(sizeof(*state), GFP_KERNEL); - if (state) { - crtc->state = &state->base; - crtc->state->crtc = crtc; - } -} - static struct drm_crtc_state * atmel_hlcdc_crtc_duplicate_state(struct drm_crtc *crtc) { @@ -447,6 +429,17 @@ static void atmel_hlcdc_crtc_destroy_state(struct drm_crtc *crtc, kfree(state); } +static void atmel_hlcdc_crtc_reset(struct drm_crtc *crtc) +{ + struct atmel_hlcdc_crtc_state *state = + kzalloc(sizeof(*state), GFP_KERNEL); + + if (crtc->state) + atmel_hlcdc_crtc_destroy_state(crtc, crtc->state); + + __drm_atomic_helper_crtc_reset(crtc, &state->base); +} + static int atmel_hlcdc_crtc_enable_vblank(struct drm_crtc *c) { struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c); -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 02/17] drm/atomic: Create __drm_atomic_helper_crtc_reset() for subclassing crtc_state.
We already have __drm_atomic_helper_connector_reset() and __drm_atomic_helper_plane_reset(), extend this to crtc as well. This will allow us to set default values in the crtc_state, without having to do it in each driver separately. Of all drivers that need conversion, only nouveau is done in this commit, because it wrote its own __drm_atomic_helper_crtc_reset(), clashing with the drm core. Signed-off-by: Maarten Lankhorst Cc: Ben Skeggs --- drivers/gpu/drm/drm_atomic_state_helper.c | 34 +++ drivers/gpu/drm/nouveau/dispnv50/head.c | 13 ++--- include/drm/drm_atomic_state_helper.h | 2 ++ 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index 4985384e51f6..bc5ee66f75b3 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -55,6 +55,29 @@ * for these functions. */ +/** + * __drm_atomic_helper_crtc_reset - reset state on CRTC + * @crtc: drm CRTC + * @crtc_state: CRTC state to assign + * + * Initializes the newly allocated @crtc_state and assigns it to + * the &drm_crtc->state pointer of @crtc, usually required when + * initializing the drivers or when called from the &drm_crtc_funcs.reset + * hook. + * + * This is useful for drivers that subclass the CRTC state. + */ +void +__drm_atomic_helper_crtc_reset(struct drm_crtc *crtc, + struct drm_crtc_state *crtc_state) +{ + if (crtc_state) + crtc_state->crtc = crtc; + + crtc->state = crtc_state; +} +EXPORT_SYMBOL(__drm_atomic_helper_crtc_reset); + /** * drm_atomic_helper_crtc_reset - default &drm_crtc_funcs.reset hook for CRTCs * @crtc: drm CRTC @@ -64,14 +87,13 @@ */ void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc) { - if (crtc->state) - __drm_atomic_helper_crtc_destroy_state(crtc->state); - - kfree(crtc->state); - crtc->state = kzalloc(sizeof(*crtc->state), GFP_KERNEL); + struct drm_crtc_state *crtc_state = + kzalloc(sizeof(*crtc->state), GFP_KERNEL); if (crtc->state) - crtc->state->crtc = crtc; + crtc->funcs->atomic_destroy_state(crtc, crtc->state); + + __drm_atomic_helper_crtc_reset(crtc, crtc_state); } EXPORT_SYMBOL(drm_atomic_helper_crtc_reset); diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.c b/drivers/gpu/drm/nouveau/dispnv50/head.c index 2e7a0c347ddb..93754743090f 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head.c @@ -419,16 +419,6 @@ nv50_head_atomic_duplicate_state(struct drm_crtc *crtc) return &asyh->state; } -static void -__drm_atomic_helper_crtc_reset(struct drm_crtc *crtc, - struct drm_crtc_state *state) -{ - if (crtc->state) - crtc->funcs->atomic_destroy_state(crtc, crtc->state); - crtc->state = state; - crtc->state->crtc = crtc; -} - static void nv50_head_reset(struct drm_crtc *crtc) { @@ -437,6 +427,9 @@ nv50_head_reset(struct drm_crtc *crtc) if (WARN_ON(!(asyh = kzalloc(sizeof(*asyh), GFP_KERNEL return; + if (crtc->state) + nv50_head_atomic_destroy_state(crtc, crtc->state); + __drm_atomic_helper_crtc_reset(crtc, &asyh->state); } diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h index 66c92cbd8e16..4e6d2e7a40b8 100644 --- a/include/drm/drm_atomic_state_helper.h +++ b/include/drm/drm_atomic_state_helper.h @@ -37,6 +37,8 @@ struct drm_private_state; struct drm_modeset_acquire_ctx; struct drm_device; +void __drm_atomic_helper_crtc_reset(struct drm_crtc *crtc, + struct drm_crtc_state *state); void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc); void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc, struct drm_crtc_state *state); -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 08/17] drm/imx: Convert to using __drm_atomic_helper_crtc_reset() for reset.
Convert imx to using __drm_atomic_helper_crtc_reset(), instead of writing its own version. Instead of open coding destroy_state(), call it directly for freeing the old state. Signed-off-by: Maarten Lankhorst Cc: Philipp Zabel --- drivers/gpu/drm/imx/ipuv3-crtc.c | 30 ++ 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c index ec3602ebbc1c..54a32c6f2407 100644 --- a/drivers/gpu/drm/imx/ipuv3-crtc.c +++ b/drivers/gpu/drm/imx/ipuv3-crtc.c @@ -101,26 +101,6 @@ static void ipu_crtc_atomic_disable(struct drm_crtc *crtc, drm_crtc_vblank_off(crtc); } -static void imx_drm_crtc_reset(struct drm_crtc *crtc) -{ - struct imx_crtc_state *state; - - if (crtc->state) { - if (crtc->state->mode_blob) - drm_property_blob_put(crtc->state->mode_blob); - - state = to_imx_crtc_state(crtc->state); - memset(state, 0, sizeof(*state)); - } else { - state = kzalloc(sizeof(*state), GFP_KERNEL); - if (!state) - return; - crtc->state = &state->base; - } - - state->base.crtc = crtc; -} - static struct drm_crtc_state *imx_drm_crtc_duplicate_state(struct drm_crtc *crtc) { struct imx_crtc_state *state; @@ -144,6 +124,16 @@ static void imx_drm_crtc_destroy_state(struct drm_crtc *crtc, kfree(to_imx_crtc_state(state)); } +static void imx_drm_crtc_reset(struct drm_crtc *crtc) +{ + struct imx_crtc_state *state = kzalloc(sizeof(*state), GFP_KERNEL); + + if (crtc->state) + imx_drm_crtc_destroy_state(crtc, crtc->state); + + __drm_atomic_helper_crtc_reset(crtc, &state->base); +} + static int ipu_enable_vblank(struct drm_crtc *crtc) { struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 04/17] drm/amd: Convert to using __drm_atomic_helper_crtc_reset() for reset.
Convert amd to using __drm_atomic_helper_crtc_reset(), instead of writing its own version. Signed-off-by: Maarten Lankhorst Cc: Harry Wentland Cc: Leo Li Cc: Alex Deucher Cc: "Christian König" Cc: "David (ChunMing) Zhou" --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 ++ 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 0642dfe22582..975ed22e39d2 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3072,18 +3072,12 @@ static void dm_crtc_destroy_state(struct drm_crtc *crtc, static void dm_crtc_reset_state(struct drm_crtc *crtc) { - struct dm_crtc_state *state; + struct dm_crtc_state *state = kzalloc(sizeof(*state), GFP_KERNEL); if (crtc->state) dm_crtc_destroy_state(crtc, crtc->state); - state = kzalloc(sizeof(*state), GFP_KERNEL); - if (WARN_ON(!state)) - return; - - crtc->state = &state->base; - crtc->state->crtc = crtc; - + __drm_atomic_helper_crtc_reset(crtc, &state->base); } static struct drm_crtc_state * -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 20/23] drm/exynos/decon5433: add local path support
GSCALERs in Exynos5433 have local path to DECON and DECON_TV. They can be used as extra planes with support for non-RGB formats and scaling. To enable it on DECON update_plane and disable_plane callback should be modified. Moreover DSD mux should be set accordingly, and finally atomic_check callback should be used to limit the number of active planes. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 80 +++ drivers/gpu/drm/exynos/regs-decon5433.h | 6 ++ 2 files changed, 72 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index 958972e3ee1e..b0332763594e 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -26,6 +26,10 @@ #include "exynos_drm_fb.h" #include "regs-decon5433.h" +#define DSD_CFG 0x1000 +#define DSD_CFG_GSCL_MODE(gsc, decon, wb) (((wb) << 1) | decon) << (3 + ((gsc) << 1)) +#define DSD_CFG_GSCL_MODE_MASK(gsc) DSD_CFG_GSCL_MODE(gsc, 1, 1) + #define DSD_CFG_MUX 0x1004 #define DSD_CFG_MUX_TE_UNMASK_GLOBAL BIT(13) @@ -47,6 +51,7 @@ static const char * const decon_clks_name[] = { "pclk_smmu_decon1x", "sclk_decon_vclk", "sclk_decon_eclk", + "dsd" }; struct decon_context { @@ -370,11 +375,40 @@ static void decon_shadow_protect(struct decon_context *ctx, bool protect) protect ? ~0 : 0); } +static int decon_atomic_check(struct exynos_drm_crtc *crtc, + struct drm_crtc_state *state) +{ + struct decon_context *ctx = to_decon(crtc); + + if (hweight32(state->plane_mask) > WINDOWS_NR - ctx->first_win) + return -EINVAL; + return 0; +} + +static void decon_set_gscl_mode(struct decon_context *ctx) +{ + u32 plane_mask = ctx->crtc.base.state->plane_mask; + struct drm_plane *bplane; + u32 mask = 0, val = 0; + bool decon_id = ctx->out_type & IFTYPE_HDMI; + + drm_for_each_plane_mask(bplane, ctx->drm_dev, plane_mask) { + struct exynos_drm_plane *plane = to_exynos_plane(bplane); + + if (!(plane->capabilities & EXYNOS_DRM_PLANE_CAP_GSCALER)) + continue; + mask |= DSD_CFG_GSCL_MODE_MASK(plane->index); + val |= DSD_CFG_GSCL_MODE(plane->index, decon_id, 0); + } + regmap_update_bits(ctx->sysreg, DSD_CFG, mask, val); +} + static void decon_atomic_begin(struct exynos_drm_crtc *crtc) { struct decon_context *ctx = to_decon(crtc); decon_shadow_protect(ctx, true); + decon_set_gscl_mode(ctx); } #define BIT_VAL(x, e, s) (((x) & ((1 << ((e) - (s) + 1)) - 1)) << (s)) @@ -394,6 +428,9 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, dma_addr_t dma_addr = exynos_drm_fb_dma_addr(fb, 0); u32 val; + if (plane->ops && plane->ops->update_plane) + plane->ops->update_plane(plane); + if (crtc->base.mode.flags & DRM_MODE_FLAG_INTERLACE) { val = COORDINATE_X(state->crtc.x) | COORDINATE_Y(state->crtc.y / 2); @@ -419,25 +456,38 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, VIDOSD_Wx_ALPHA_B_F(0x0); writel(val, ctx->addr + DECON_VIDOSDxD(win)); - writel(dma_addr, ctx->addr + DECON_VIDW0xADD0B0(win)); - - val = dma_addr + pitch * state->src.h; - writel(val, ctx->addr + DECON_VIDW0xADD1B0(win)); - - if (!(ctx->out_type & IFTYPE_HDMI)) - val = BIT_VAL(pitch - state->crtc.w * cpp, 27, 14) - | BIT_VAL(state->crtc.w * cpp, 13, 0); - else - val = BIT_VAL(pitch - state->crtc.w * cpp, 29, 15) - | BIT_VAL(state->crtc.w * cpp, 14, 0); - writel(val, ctx->addr + DECON_VIDW0xADD2(win)); - decon_win_set_pixfmt(ctx, plane); + if (plane->capabilities & EXYNOS_DRM_PLANE_CAP_GSCALER) { + writel(UPDATE_SCHEME_OTF_PER_FRAME, + ctx->addr + DECON_UPDATE_SCHEME); + decon_set_bits(ctx, DECON_WINCONx(win), + WINCONx_ENLOCAL_F | WINCONx_LOCALSEL_MASK, + WINCONx_ENLOCAL_F | WINCONx_LOCALSEL_F(plane->index)); + } else { + writel(dma_addr, ctx->addr + DECON_VIDW0xADD0B0(win)); + val = dma_addr + pitch * state->src.h; + writel(val, ctx->addr + DECON_VIDW0xADD1B0(win)); + if (!(ctx->out_type & IFTYPE_HDMI)) + val = BIT_VAL(pitch - state->crtc.w * cpp, 27, 14) + | BIT_VAL(state->crtc.w * cpp, 13, 0); + else + val = BIT_VAL(pitch - state->crtc.w * cpp, 29, 15) + | BIT_VAL(state->crtc.w * cpp, 14, 0); + writel(val, ctx->addr + DECON_VIDW0xADD2(win)); +
[PATCH 07/23] drm/exynos/fimd: embed exynos_drm_crtc directly into context
Since crtc maps 1:1 to the device there is no point in allocating it separately, another benefit is possibility of direct initialisation of its fields which is more readable and allows further expansion. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 60 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 2d34ca375ee1..8ea1cfd51736 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -169,7 +169,7 @@ static struct fimd_driver_data exynos5420_fimd_driver_data = { struct fimd_context { struct device *dev; struct drm_device *drm_dev; - struct exynos_drm_crtc *crtc; + struct exynos_drm_crtc crtc; struct exynos_drm_plane planes[WINDOWS_NR]; struct clk *bus_clk; struct clk *lcd_clk; @@ -193,6 +193,8 @@ struct fimd_context { struct exynos_drm_clk dp_clk; }; +#define to_fimd(ptr) container_of(ptr, struct fimd_context, ptr) + static const struct of_device_id fimd_driver_dt_match[] = { { .compatible = "samsung,s3c6400-fimd", .data = &s3c64xx_fimd_driver_data }, @@ -235,7 +237,7 @@ static inline void fimd_set_bits(struct fimd_context *ctx, u32 reg, u32 mask, static int fimd_enable_vblank(struct exynos_drm_crtc *crtc) { - struct fimd_context *ctx = crtc->ctx; + struct fimd_context *ctx = to_fimd(crtc); u32 val; if (ctx->suspended) @@ -267,7 +269,7 @@ static int fimd_enable_vblank(struct exynos_drm_crtc *crtc) static void fimd_disable_vblank(struct exynos_drm_crtc *crtc) { - struct fimd_context *ctx = crtc->ctx; + struct fimd_context *ctx = to_fimd(crtc); u32 val; if (ctx->suspended) @@ -291,7 +293,7 @@ static void fimd_disable_vblank(struct exynos_drm_crtc *crtc) static void fimd_wait_for_vblank(struct exynos_drm_crtc *crtc) { - struct fimd_context *ctx = crtc->ctx; + struct fimd_context *ctx = to_fimd(crtc); if (ctx->suspended) return; @@ -345,7 +347,7 @@ static void fimd_disable_win(struct fimd_context *ctx, int win) static void fimd_clear_channels(struct exynos_drm_crtc *crtc) { - struct fimd_context *ctx = crtc->ctx; + struct fimd_context *ctx = to_fimd(crtc); unsigned int win, ch_enabled = 0; DRM_DEBUG_KMS("%s\n", __FILE__); @@ -370,9 +372,9 @@ static void fimd_clear_channels(struct exynos_drm_crtc *crtc) if (ch_enabled) { ctx->suspended = false; - fimd_enable_vblank(ctx->crtc); - fimd_wait_for_vblank(ctx->crtc); - fimd_disable_vblank(ctx->crtc); + fimd_enable_vblank(&ctx->crtc); + fimd_wait_for_vblank(&ctx->crtc); + fimd_disable_vblank(&ctx->crtc); ctx->suspended = true; } @@ -388,7 +390,7 @@ static int fimd_atomic_check(struct exynos_drm_crtc *crtc, struct drm_crtc_state *state) { struct drm_display_mode *mode = &state->adjusted_mode; - struct fimd_context *ctx = crtc->ctx; + struct fimd_context *ctx = to_fimd(crtc); unsigned long ideal_clk, lcd_rate; u32 clkdiv; @@ -448,7 +450,7 @@ static void fimd_setup_trigger(struct fimd_context *ctx) static void fimd_commit(struct exynos_drm_crtc *crtc) { - struct fimd_context *ctx = crtc->ctx; + struct fimd_context *ctx = to_fimd(crtc); struct drm_display_mode *mode = &crtc->base.state->adjusted_mode; const struct fimd_driver_data *driver_data = ctx->driver_data; void *timing_base = ctx->regs + driver_data->timing_base; @@ -754,7 +756,7 @@ static void fimd_shadow_protect_win(struct fimd_context *ctx, static void fimd_atomic_begin(struct exynos_drm_crtc *crtc) { - struct fimd_context *ctx = crtc->ctx; + struct fimd_context *ctx = to_fimd(crtc); int i; if (ctx->suspended) @@ -766,7 +768,7 @@ static void fimd_atomic_begin(struct exynos_drm_crtc *crtc) static void fimd_atomic_flush(struct exynos_drm_crtc *crtc) { - struct fimd_context *ctx = crtc->ctx; + struct fimd_context *ctx = to_fimd(crtc); int i; if (ctx->suspended) @@ -789,7 +791,7 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc, { struct exynos_drm_plane_state *state = to_exynos_plane_state(plane->base.state); - struct fimd_context *ctx = crtc->ctx; + struct fimd_context *ctx = to_fimd(crtc); struct drm_framebuffer *fb = state->base.fb; dma_addr_t dma_addr; unsigned long val, size, offset; @@ -878,7 +880,7 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc, static void fimd_enab
[PATCH 22/23] drm/exynos/gscaler: change supported color format BGRX8888 to XBGR8888
GSCALER does not support BGRX, instead it supports XBGR. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos_drm_gsc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c index 28a738a68a82..c7a97d053ab1 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c @@ -502,7 +502,7 @@ static void gsc_src_set_fmt(struct gsc_context *ctx, u32 fmt, bool tiled) case DRM_FORMAT_ARGB: cfg |= GSC_IN_XRGB; break; - case DRM_FORMAT_BGRX: + case DRM_FORMAT_XBGR: cfg |= (GSC_IN_XRGB | GSC_IN_RB_SWAP); break; case DRM_FORMAT_YUYV: @@ -689,7 +689,7 @@ static void gsc_dst_set_fmt(struct gsc_context *ctx, u32 fmt, bool tiled) case DRM_FORMAT_XRGB: cfg |= (GSC_OUT_XRGB | GSC_OUT_GLOBAL_ALPHA(0xff)); break; - case DRM_FORMAT_BGRX: + case DRM_FORMAT_XBGR: cfg |= (GSC_OUT_XRGB | GSC_OUT_RB_SWAP); break; case DRM_FORMAT_YUYV: @@ -1197,7 +1197,7 @@ static struct exynos_drm_ipp_funcs ipp_funcs = { }; static const unsigned int gsc_formats[] = { - DRM_FORMAT_ARGB, DRM_FORMAT_XRGB, DRM_FORMAT_BGRX, + DRM_FORMAT_ARGB, DRM_FORMAT_XRGB, DRM_FORMAT_XBGR, DRM_FORMAT_RGB565, DRM_FORMAT_NV12, DRM_FORMAT_NV16, DRM_FORMAT_NV21, DRM_FORMAT_NV61, DRM_FORMAT_UYVY, DRM_FORMAT_VYUY, DRM_FORMAT_YUYV, DRM_FORMAT_YVYU, -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 09/23] drm/exynos/vidi: embed exynos_drm_crtc directly into context
Since crtc maps 1:1 to the device there is no point in allocating it separately, another benefit is possibility of direct initialisation of its fields which is more readable and allows further expansion. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos_drm_vidi.c | 26 +--- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index b61ae3415b8c..377aae5f7631 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -41,7 +41,7 @@ struct vidi_context { struct drm_encoder encoder; struct platform_device *pdev; struct drm_device *drm_dev; - struct exynos_drm_crtc *crtc; + struct exynos_drm_crtc crtc; struct drm_connectorconnector; struct exynos_drm_plane planes[WINDOWS_NR]; struct edid *raw_edid; @@ -57,6 +57,8 @@ static inline struct vidi_context *encoder_to_vidi(struct drm_encoder *e) return container_of(e, struct vidi_context, encoder); } +#define to_vidi(ptr) container_of(ptr, struct vidi_context, ptr) + static const char fake_edid_info[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x4c, 0x2d, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x30, 0x12, 0x01, 0x03, 0x80, 0x10, 0x09, 0x78, @@ -96,7 +98,7 @@ static const enum drm_plane_type vidi_win_types[WINDOWS_NR] = { static int vidi_enable_vblank(struct exynos_drm_crtc *crtc) { - struct vidi_context *ctx = crtc->ctx; + struct vidi_context *ctx = to_vidi(crtc); if (ctx->suspended) return -EPERM; @@ -115,7 +117,7 @@ static void vidi_update_plane(struct exynos_drm_crtc *crtc, struct exynos_drm_plane *plane) { struct drm_plane_state *state = plane->base.state; - struct vidi_context *ctx = crtc->ctx; + struct vidi_context *ctx = to_vidi(crtc); dma_addr_t addr; if (ctx->suspended) @@ -127,7 +129,7 @@ static void vidi_update_plane(struct exynos_drm_crtc *crtc, static void vidi_enable(struct exynos_drm_crtc *crtc) { - struct vidi_context *ctx = crtc->ctx; + struct vidi_context *ctx = to_vidi(crtc); mutex_lock(&ctx->lock); @@ -140,7 +142,7 @@ static void vidi_enable(struct exynos_drm_crtc *crtc) static void vidi_disable(struct exynos_drm_crtc *crtc) { - struct vidi_context *ctx = crtc->ctx; + struct vidi_context *ctx = to_vidi(crtc); drm_crtc_vblank_off(&crtc->base); @@ -164,7 +166,7 @@ static void vidi_fake_vblank_timer(struct timer_list *t) { struct vidi_context *ctx = from_timer(ctx, t, timer); - if (drm_crtc_handle_vblank(&ctx->crtc->base)) + if (drm_crtc_handle_vblank(&ctx->crtc.base)) mod_timer(&ctx->timer, jiffies + msecs_to_jiffies(VIDI_REFRESH_TIME) - 1); } @@ -377,7 +379,6 @@ static int vidi_bind(struct device *dev, struct device *master, void *data) struct vidi_context *ctx = dev_get_drvdata(dev); struct drm_device *drm_dev = data; struct drm_encoder *encoder = &ctx->encoder; - struct exynos_drm_plane *exynos_plane; unsigned int i; int ret; @@ -390,13 +391,14 @@ static int vidi_bind(struct device *dev, struct device *master, void *data) return ret; } - exynos_plane = &ctx->planes[DEFAULT_WIN]; - ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base, - EXYNOS_DISPLAY_TYPE_VIDI, &vidi_crtc_ops, ctx); - if (IS_ERR(ctx->crtc)) { + ctx->crtc.type = EXYNOS_DISPLAY_TYPE_VIDI; + ctx->crtc.ops = &vidi_crtc_ops; + ret = exynos_drm_crtc_init(&ctx->crtc, drm_dev); + if (ret) { DRM_ERROR("failed to create crtc.\n"); - return PTR_ERR(ctx->crtc); + return ret; } + ctx->crtc.base.primary = &ctx->planes[DEFAULT_WIN].base; drm_encoder_init(drm_dev, encoder, &exynos_vidi_encoder_funcs, DRM_MODE_ENCODER_TMDS, NULL); -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 15/23] drm/exynos: add GSCALER plane capability
This bit will indicate the plane is provided by GSCALER. Tests shows that GSCALER does not like to convert from/to too small buffers. Since exact constraints are not provided by documentation rough estimate of 64 pixel has been applied. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos_drm_drv.h | 1 + drivers/gpu/drm/exynos/exynos_drm_plane.c | 14 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 5d06e796dc80..7bdbac639b2b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -75,6 +75,7 @@ to_exynos_plane_state(struct drm_plane_state *state) #define EXYNOS_DRM_PLANE_CAP_TILE (1 << 3) #define EXYNOS_DRM_PLANE_CAP_PIX_BLEND (1 << 4) #define EXYNOS_DRM_PLANE_CAP_WIN_BLEND (1 << 5) +#define EXYNOS_DRM_PLANE_CAP_GSCALER (1 << 6) struct exynos_drm_plane; struct exynos_drm_plane_ops { diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index 5f8f56b69369..89168157e1e2 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -198,6 +198,11 @@ exynos_drm_plane_check_format(struct exynos_drm_plane_state *state) return 0; } +static bool is_in_range(int val, int min, int max) +{ + return (val >= min) && (val < max); +} + static int exynos_drm_plane_check_size(struct exynos_drm_plane_state *state) { @@ -205,7 +210,7 @@ exynos_drm_plane_check_size(struct exynos_drm_plane_state *state) bool width_ok = false, height_ok = false; if (plane->capabilities & EXYNOS_DRM_PLANE_CAP_SCALE) - return 0; + width_ok = height_ok = true; if (state->src.w == state->crtc.w) width_ok = true; @@ -221,6 +226,13 @@ exynos_drm_plane_check_size(struct exynos_drm_plane_state *state) state->v_ratio == (1 << 15)) height_ok = true; + if (plane->capabilities & EXYNOS_DRM_PLANE_CAP_GSCALER) { + width_ok = is_in_range(state->src.w, 64, 4800) && + is_in_range(state->crtc.w, 64, 4800); + height_ok = is_in_range(state->src.h, 64, 3344) && + is_in_range(state->crtc.h, 64, 3344); + } + if (width_ok && height_ok) return 0; -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 23/23] drm/exynos/gscaler: fix handling YVU420 pixel format
YVU420 requires swapping addresses of U and V planes. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos_drm_gsc.c | 52 ++--- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c index c7a97d053ab1..f75739e8bc55 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c @@ -535,10 +535,8 @@ static void gsc_src_set_fmt(struct gsc_context *ctx, u32 fmt, bool tiled) cfg |= GSC_IN_YUV422_3P; break; case DRM_FORMAT_YUV420: - cfg |= (GSC_IN_CHROMA_ORDER_CBCR | GSC_IN_YUV420_3P); - break; case DRM_FORMAT_YVU420: - cfg |= (GSC_IN_CHROMA_ORDER_CRCB | GSC_IN_YUV420_3P); + cfg |= (GSC_IN_CHROMA_ORDER_CBCR | GSC_IN_YUV420_3P); break; case DRM_FORMAT_NV12: cfg |= (GSC_IN_CHROMA_ORDER_CBCR | GSC_IN_YUV420_2P); @@ -658,13 +656,32 @@ static void gsc_src_set_buf_seq(struct gsc_context *ctx, u32 buf_id, gsc_write(cfg, GSC_IN_BASE_ADDR_CR_MASK); } +/* returns HW plane index based on pixel format */ +static int gsc_hw_plane_index(int index, u32 format) +{ + switch (format) { + case DRM_FORMAT_YVU420: + switch (index) { + case 0: return 0; + case 1: return 2; + case 2: return 1; + } + default: + return index; + } +} + static void gsc_src_set_addr(struct gsc_context *ctx, u32 buf_id, struct exynos_drm_ipp_buffer *buf) { + int idx; + /* address register set */ gsc_write(buf->dma_addr[0], GSC_IN_BASE_ADDR_Y(buf_id)); - gsc_write(buf->dma_addr[1], GSC_IN_BASE_ADDR_CB(buf_id)); - gsc_write(buf->dma_addr[2], GSC_IN_BASE_ADDR_CR(buf_id)); + idx = gsc_hw_plane_index(1, buf->format->format); + gsc_write(buf->dma_addr[idx], GSC_IN_BASE_ADDR_CB(buf_id)); + idx = gsc_hw_plane_index(2, buf->format->format); + gsc_write(buf->dma_addr[idx], GSC_IN_BASE_ADDR_CR(buf_id)); gsc_src_set_buf_seq(ctx, buf_id, true); } @@ -722,10 +739,8 @@ static void gsc_dst_set_fmt(struct gsc_context *ctx, u32 fmt, bool tiled) cfg |= GSC_OUT_YUV422_3P; break; case DRM_FORMAT_YUV420: - cfg |= (GSC_OUT_CHROMA_ORDER_CBCR | GSC_OUT_YUV420_3P); - break; case DRM_FORMAT_YVU420: - cfg |= (GSC_OUT_CHROMA_ORDER_CRCB | GSC_OUT_YUV420_3P); + cfg |= (GSC_OUT_CHROMA_ORDER_CBCR | GSC_OUT_YUV420_3P); break; case DRM_FORMAT_NV12: cfg |= (GSC_OUT_CHROMA_ORDER_CBCR | GSC_OUT_YUV420_2P); @@ -985,10 +1000,13 @@ static void gsc_dst_set_buf_seq(struct gsc_context *ctx, u32 buf_id, static void gsc_dst_set_addr(struct gsc_context *ctx, u32 buf_id, struct exynos_drm_ipp_buffer *buf) { - /* address register set */ + int i; + gsc_write(buf->dma_addr[0], GSC_OUT_BASE_ADDR_Y(buf_id)); - gsc_write(buf->dma_addr[1], GSC_OUT_BASE_ADDR_CB(buf_id)); - gsc_write(buf->dma_addr[2], GSC_OUT_BASE_ADDR_CR(buf_id)); + i = gsc_hw_plane_index(1, buf->format->format); + gsc_write(buf->dma_addr[i], GSC_OUT_BASE_ADDR_CB(buf_id)); + i = gsc_hw_plane_index(2, buf->format->format); + gsc_write(buf->dma_addr[i], GSC_OUT_BASE_ADDR_CR(buf_id)); gsc_dst_set_buf_seq(ctx, buf_id, true); } @@ -1238,10 +1256,14 @@ static void gsc_update_plane(struct exynos_drm_plane *plane) gsc_write(BIT(16) * cropped_w / scaled_w, GSC_MAIN_H_RATIO); gsc_write(BIT(16) * cropped_h / scaled_h, GSC_MAIN_V_RATIO); gsc_write(exynos_drm_fb_dma_addr(fb, 0), GSC_IN_BASE_ADDR_Y(0)); - if (fb->format->num_planes > 1) - gsc_write(exynos_drm_fb_dma_addr(fb, 1), GSC_IN_BASE_ADDR_CB(0)); - if (fb->format->num_planes > 2) - gsc_write(exynos_drm_fb_dma_addr(fb, 2), GSC_IN_BASE_ADDR_CR(0)); + if (fb->format->num_planes > 1) { + i = gsc_hw_plane_index(1, fb->format->format); + gsc_write(exynos_drm_fb_dma_addr(fb, i), GSC_IN_BASE_ADDR_CB(0)); + } + if (fb->format->num_planes > 2) { + i = gsc_hw_plane_index(2, fb->format->format); + gsc_write(exynos_drm_fb_dma_addr(fb, i), GSC_IN_BASE_ADDR_CR(0)); + } gsc_src_set_fmt(ctx, fb->format->format, fb->modifier); gsc_write(scaled_w * scaled_h, GSC_SMART_IF_PIXEL_NUM); gsc_write(GSC_ENABLE_SFR_UPDATE | GSC_ENABLE_ON, GSC_ENABLE); -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 18/23] arm64: dts: exynos: add DSD/GSD clocks to DECONs and GSCALERs
To support local paths both DECON and GSCALER should enable respective Smart Deck clocks DSD and GSD. Signed-off-by: Andrzej Hajda --- arch/arm64/boot/dts/exynos/exynos5433.dtsi | 25 +- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi index e7cd3b67d818..e6d32b2fb3c0 100644 --- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi @@ -848,12 +848,13 @@ <&cmu_disp CLK_ACLK_XIU_DECON1X>, <&cmu_disp CLK_PCLK_SMMU_DECON1X>, <&cmu_disp CLK_SCLK_DECON_VCLK>, - <&cmu_disp CLK_SCLK_DECON_ECLK>; + <&cmu_disp CLK_SCLK_DECON_ECLK>, + <&cmu_disp CLK_SCLK_DSD>; clock-names = "pclk", "aclk_decon", "aclk_smmu_decon0x", "aclk_xiu_decon0x", "pclk_smmu_decon0x", "aclk_smmu_decon1x", "aclk_xiu_decon1x", "pclk_smmu_decon1x", "sclk_decon_vclk", - "sclk_decon_eclk"; + "sclk_decon_eclk", "dsd"; power-domains = <&pd_disp>; interrupt-names = "fifo", "vsync", "lcd_sys"; interrupts = , @@ -890,12 +891,13 @@ <&cmu_disp CLK_ACLK_XIU_TV1X>, <&cmu_disp CLK_PCLK_SMMU_TV1X>, <&cmu_disp CLK_SCLK_DECON_TV_VCLK>, -<&cmu_disp CLK_SCLK_DECON_TV_ECLK>; +<&cmu_disp CLK_SCLK_DECON_TV_ECLK>, +<&cmu_disp CLK_SCLK_DSD>; clock-names = "pclk", "aclk_decon", "aclk_smmu_decon0x", "aclk_xiu_decon0x", "pclk_smmu_decon0x", "aclk_smmu_decon1x", "aclk_xiu_decon1x", "pclk_smmu_decon1x", "sclk_decon_vclk", - "sclk_decon_eclk"; + "sclk_decon_eclk", "dsd"; samsung,disp-sysreg = <&syscon_disp>; power-domains = <&pd_disp>; interrupt-names = "fifo", "vsync", "lcd_sys"; @@ -1022,11 +1024,12 @@ reg = <0x13c0 0x1000>; interrupts = ; clock-names = "pclk", "aclk", "aclk_xiu", - "aclk_gsclbend"; + "aclk_gsclbend", "gsd"; clocks = <&cmu_gscl CLK_PCLK_GSCL0>, <&cmu_gscl CLK_ACLK_GSCL0>, <&cmu_gscl CLK_ACLK_XIU_GSCLX>, -<&cmu_gscl CLK_ACLK_GSCLBEND_333>; +<&cmu_gscl CLK_ACLK_GSCLBEND_333>, +<&cmu_gscl CLK_ACLK_GSD>; iommus = <&sysmmu_gscl0>; power-domains = <&pd_gscl>; }; @@ -1036,11 +1039,12 @@ reg = <0x13c1 0x1000>; interrupts = ; clock-names = "pclk", "aclk", "aclk_xiu", - "aclk_gsclbend"; + "aclk_gsclbend", "gsd"; clocks = <&cmu_gscl CLK_PCLK_GSCL1>, <&cmu_gscl CLK_ACLK_GSCL1>, <&cmu_gscl CLK_ACLK_XIU_GSCLX>, -<&cmu_gscl CLK_ACLK_GSCLBEND_333>; +<&cmu_gscl CLK_ACLK_GSCLBEND_333>, +<&cmu_gscl CLK_ACLK_GSD>; iommus = <&sysmmu_gscl1>; power-domains = <&pd_gscl>; }; @@ -1050,11 +1054,12 @@ reg = <0x13c2 0x1000>; interrupts = ; clock-names = "pclk", "aclk", "aclk_xiu", - "aclk_gsclbend"; + "aclk_gsclbend", "gsd"; clocks = <&cmu_gscl CLK_PCLK_GSCL2>, <&cmu_gscl CLK_ACLK_GSCL2>, <&cmu_gscl CLK_ACLK_XIU_GSCLX>, -<&cmu_gscl CLK_ACLK_GSCLBEND_333>; +<&cmu_gscl CLK_ACLK_GSCLBEND_333>, +<&cmu_gscl CLK_ACLK_GSD>; iommus = <&sysmmu_gscl2>; power-domains = <&pd_gscl>; }; -- 2.17.1 ___ dri-devel mailing list
[PATCH 13/23] drm/exynos: set primary and cursor planes in exynos_drm_crtc_init
exynos_drm_crtc_init has all information necessary to discover primary and cursor planes. Let's move logic for setting these planes into this function. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 3 --- drivers/gpu/drm/exynos/exynos7_drm_decon.c| 1 - drivers/gpu/drm/exynos/exynos_drm_crtc.c | 12 +++- drivers/gpu/drm/exynos/exynos_drm_drv.h | 2 -- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 1 - drivers/gpu/drm/exynos/exynos_drm_vidi.c | 1 - drivers/gpu/drm/exynos/exynos_mixer.c | 1 - 7 files changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index 663446ca2d09..958972e3ee1e 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -30,8 +30,6 @@ #define DSD_CFG_MUX_TE_UNMASK_GLOBAL BIT(13) #define WINDOWS_NR 5 -#define PRIMARY_WIN2 -#define CURSON_WIN 4 #define MIN_FB_WIDTH_FOR_16WORD_BURST 128 @@ -625,7 +623,6 @@ static int decon_bind(struct device *dev, struct device *master, void *data) ret = exynos_drm_crtc_init(&ctx->crtc, drm_dev); if (ret) return ret; - ctx->crtc.base.primary = &ctx->planes[PRIMARY_WIN].base; decon_clear_channels(&ctx->crtc); diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c index b6ad2faed159..3d8c96f0b02a 100644 --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c @@ -635,7 +635,6 @@ static int decon_bind(struct device *dev, struct device *master, void *data) decon_ctx_remove(ctx); return ret; } - ctx->crtc.base.primary = &ctx->planes[DEFAULT_WIN].base; if (ctx->encoder) exynos_dpi_bind(drm_dev, ctx->encoder); diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 72e224e80565..303df018f0a1 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -176,9 +176,19 @@ int exynos_drm_crtc_init(struct exynos_drm_crtc *exynos_crtc, struct drm_device *drm_dev) { struct drm_crtc *crtc = &exynos_crtc->base; + struct drm_plane *primary = NULL, *cursor = NULL, *plane; + + drm_for_each_plane(plane, drm_dev) { + if (plane->possible_crtcs != BIT(drm_dev->mode_config.num_crtc)) + continue; + if (!primary && plane->type == DRM_PLANE_TYPE_PRIMARY) + primary = plane; + if (!cursor && plane->type == DRM_PLANE_TYPE_CURSOR) + cursor = plane; + } drm_crtc_helper_add(crtc, &exynos_crtc_helper_funcs); - return drm_crtc_init_with_planes(drm_dev, crtc, NULL, NULL, + return drm_crtc_init_with_planes(drm_dev, crtc, primary, cursor, &exynos_crtc_funcs, NULL); } diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 23b27b82de6e..6643db865500 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -21,8 +21,6 @@ #define MAX_PLANE 5 #define MAX_FB_BUFFER 4 -#define DEFAULT_WIN0 - #define to_exynos_crtc(x) container_of(x, struct exynos_drm_crtc, base) #define to_exynos_plane(x) container_of(x, struct exynos_drm_plane, base) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index b3c11bca5aed..14e70971547a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -1051,7 +1051,6 @@ static int fimd_bind(struct device *dev, struct device *master, void *data) ret = exynos_drm_crtc_init(&ctx->crtc, drm_dev); if (ret) return ret; - ctx->crtc.base.primary = &ctx->planes[DEFAULT_WIN].base; if (ctx->driver_data->has_dp_clk) { ctx->dp_clk.enable = fimd_dp_clock_enable; diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index eb1fd3a2cdf3..19cd7275b20f 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -387,7 +387,6 @@ static int vidi_bind(struct device *dev, struct device *master, void *data) DRM_ERROR("failed to create crtc.\n"); return ret; } - ctx->crtc.base.primary = &ctx->planes[DEFAULT_WIN].base; drm_encoder_init(drm_dev, encoder, &exynos_vidi_encoder_funcs, DRM_MODE_ENCODER_TMDS, NULL); diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index d0dcbbfc67e5..8bb31a0e572e 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/
[PATCH 08/23] drm/exynos/mixer: embed exynos_drm_crtc directly into context
Since crtc maps 1:1 to the device there is no point in allocating it separately, another benefit is possibility of direct initialisation of its fields which is more readable and allows further expansion. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos_mixer.c | 39 ++- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 750f682e9c31..946d62ae83e3 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -98,7 +98,7 @@ struct mixer_context { struct platform_device *pdev; struct device *dev; struct drm_device *drm_dev; - struct exynos_drm_crtc *crtc; + struct exynos_drm_crtc crtc; struct exynos_drm_plane planes[MIXER_WIN_NR]; unsigned long flags; @@ -116,6 +116,8 @@ struct mixer_context { int scan_value; }; +#define to_mixer(ptr) container_of(ptr, struct mixer_context, ptr) + struct mixer_drv_data { enum mixer_version_id version; boolis_vp_enabled; @@ -426,7 +428,7 @@ static void mixer_stop(struct mixer_context *ctx) static void mixer_commit(struct mixer_context *ctx) { - struct drm_display_mode *mode = &ctx->crtc->base.state->adjusted_mode; + struct drm_display_mode *mode = &ctx->crtc.base.state->adjusted_mode; mixer_cfg_scan(ctx, mode->hdisplay, mode->vdisplay); mixer_cfg_rgb_fmt(ctx, mode); @@ -712,7 +714,7 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg) goto out; } - drm_crtc_handle_vblank(&ctx->crtc->base); + drm_crtc_handle_vblank(&ctx->crtc.base); } out: @@ -856,7 +858,7 @@ static void mixer_ctx_remove(struct mixer_context *mixer_ctx) static int mixer_enable_vblank(struct exynos_drm_crtc *crtc) { - struct mixer_context *mixer_ctx = crtc->ctx; + struct mixer_context *mixer_ctx = to_mixer(crtc); __set_bit(MXR_BIT_VSYNC, &mixer_ctx->flags); if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags)) @@ -871,7 +873,7 @@ static int mixer_enable_vblank(struct exynos_drm_crtc *crtc) static void mixer_disable_vblank(struct exynos_drm_crtc *crtc) { - struct mixer_context *mixer_ctx = crtc->ctx; + struct mixer_context *mixer_ctx = to_mixer(crtc); __clear_bit(MXR_BIT_VSYNC, &mixer_ctx->flags); @@ -885,7 +887,7 @@ static void mixer_disable_vblank(struct exynos_drm_crtc *crtc) static void mixer_atomic_begin(struct exynos_drm_crtc *crtc) { - struct mixer_context *mixer_ctx = crtc->ctx; + struct mixer_context *mixer_ctx = to_mixer(crtc); if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags)) return; @@ -896,7 +898,7 @@ static void mixer_atomic_begin(struct exynos_drm_crtc *crtc) static void mixer_update_plane(struct exynos_drm_crtc *crtc, struct exynos_drm_plane *plane) { - struct mixer_context *mixer_ctx = crtc->ctx; + struct mixer_context *mixer_ctx = to_mixer(crtc); DRM_DEBUG_KMS("win: %d\n", plane->index); @@ -912,7 +914,7 @@ static void mixer_update_plane(struct exynos_drm_crtc *crtc, static void mixer_disable_plane(struct exynos_drm_crtc *crtc, struct exynos_drm_plane *plane) { - struct mixer_context *mixer_ctx = crtc->ctx; + struct mixer_context *mixer_ctx = to_mixer(crtc); unsigned long flags; DRM_DEBUG_KMS("win: %d\n", plane->index); @@ -927,7 +929,7 @@ static void mixer_disable_plane(struct exynos_drm_crtc *crtc, static void mixer_atomic_flush(struct exynos_drm_crtc *crtc) { - struct mixer_context *mixer_ctx = crtc->ctx; + struct mixer_context *mixer_ctx = to_mixer(crtc); if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags)) return; @@ -938,7 +940,7 @@ static void mixer_atomic_flush(struct exynos_drm_crtc *crtc) static void mixer_enable(struct exynos_drm_crtc *crtc) { - struct mixer_context *ctx = crtc->ctx; + struct mixer_context *ctx = to_mixer(crtc); if (test_bit(MXR_BIT_POWERED, &ctx->flags)) return; @@ -967,7 +969,7 @@ static void mixer_enable(struct exynos_drm_crtc *crtc) static void mixer_disable(struct exynos_drm_crtc *crtc) { - struct mixer_context *ctx = crtc->ctx; + struct mixer_context *ctx = to_mixer(crtc); int i; if (!test_bit(MXR_BIT_POWERED, &ctx->flags)) @@ -989,7 +991,7 @@ static void mixer_disable(struct exynos_drm_crtc *crtc) static int mixer_mode_valid(struct exynos_drm_crtc *crtc, const struct drm_display_mode *mode) { - struct mixer_context *ctx = crtc->ctx; + struct mixer_context *ctx = to_mixer(crtc); u32 w = mode->hdisplay, h = mode->vdisplay;
[PATCH 12/23] drm/exynos: unify plane type assignment
Since all Exynos CRTCs uses the first plane as primary plane and the last one as cursor plane we can drop custom assignments per CRTC and replace it with common code. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 7 +-- drivers/gpu/drm/exynos/exynos7_drm_decon.c| 7 +-- drivers/gpu/drm/exynos/exynos_drm_drv.h | 2 +- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 10 +- drivers/gpu/drm/exynos/exynos_drm_plane.c | 19 +-- drivers/gpu/drm/exynos/exynos_drm_vidi.c | 8 +--- drivers/gpu/drm/exynos/exynos_mixer.c | 6 ++ 7 files changed, 20 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index 0d409f453923..663446ca2d09 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -78,11 +78,6 @@ static const uint32_t decon_formats[] = { DRM_FORMAT_ARGB, }; -static const enum drm_plane_type decon_win_types[WINDOWS_NR] = { - [PRIMARY_WIN] = DRM_PLANE_TYPE_PRIMARY, - [CURSON_WIN] = DRM_PLANE_TYPE_CURSOR, -}; - static inline void decon_set_bits(struct decon_context *ctx, u32 reg, u32 mask, u32 val) { @@ -619,7 +614,7 @@ static int decon_bind(struct device *dev, struct device *master, void *data) | EXYNOS_DRM_PLANE_CAP_PIX_BLEND; ret = exynos_plane_init(drm_dev, &ctx->planes[i], decon_formats, ARRAY_SIZE(decon_formats), - decon_win_types[i]); + WINDOWS_NR - ctx->first_win); if (ret) return ret; } diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c index 22659f2da755..b6ad2faed159 100644 --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c @@ -78,11 +78,6 @@ static const uint32_t decon_formats[] = { DRM_FORMAT_BGRA, }; -static const enum drm_plane_type decon_win_types[WINDOWS_NR] = { - DRM_PLANE_TYPE_PRIMARY, - DRM_PLANE_TYPE_CURSOR, -}; - static void decon_wait_for_vblank(struct exynos_drm_crtc *crtc) { struct decon_context *ctx = to_decon(crtc); @@ -628,7 +623,7 @@ static int decon_bind(struct device *dev, struct device *master, void *data) for (i = 0; i < WINDOWS_NR; i++) { ctx->planes[i].index = i; ret = exynos_plane_init(drm_dev, &ctx->planes[i], decon_formats, - ARRAY_SIZE(decon_formats), decon_win_types[i]); + ARRAY_SIZE(decon_formats), WINDOWS_NR); if (ret) return ret; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 82af112be03d..23b27b82de6e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -97,7 +97,7 @@ struct exynos_drm_plane { int exynos_plane_init(struct drm_device *dev, struct exynos_drm_plane *plane, const uint32_t *pixel_formats, int num_pixel_formats, - enum drm_plane_type type); + int win_count); /* * Exynos drm crtc ops diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 8ea1cfd51736..b3c11bca5aed 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -212,14 +212,6 @@ static const struct of_device_id fimd_driver_dt_match[] = { }; MODULE_DEVICE_TABLE(of, fimd_driver_dt_match); -static const enum drm_plane_type fimd_win_types[WINDOWS_NR] = { - DRM_PLANE_TYPE_PRIMARY, - DRM_PLANE_TYPE_OVERLAY, - DRM_PLANE_TYPE_OVERLAY, - DRM_PLANE_TYPE_OVERLAY, - DRM_PLANE_TYPE_CURSOR, -}; - static const uint32_t fimd_formats[] = { DRM_FORMAT_C8, DRM_FORMAT_XRGB1555, @@ -1049,7 +1041,7 @@ static int fimd_bind(struct device *dev, struct device *master, void *data) | EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND; ret = exynos_plane_init(drm_dev, &ctx->planes[i], fimd_formats, - ARRAY_SIZE(fimd_formats), fimd_win_types[i]); + ARRAY_SIZE(fimd_formats), WINDOWS_NR); if (ret) return ret; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index e1aa504539fa..5f8f56b69369 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -291,9 +291,18 @@ static void exynos_plane_attach_zpos_property(struct drm_plane *plane, d
[PATCH 04/23] drm/exynos: add exynos_drm_crtc_init function
Since exynos_drm_crtc is a struct which maps 1:1 to underlying device it is better to put it directly into device's context instead of allocating it separately. Another benefit is possibility of initialisation of its fields directly, without expanding exynos_drm_crtc_create which is already overloaded with number of arguments. As a first step of the transition initialisation function should be created. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos_drm_crtc.c | 10 ++ drivers/gpu/drm/exynos/exynos_drm_crtc.h | 2 ++ 2 files changed, 12 insertions(+) diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 1eebfa3fa8da..4ff1e0ff2255 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -172,6 +172,16 @@ static const struct drm_crtc_funcs exynos_crtc_funcs = { .disable_vblank = exynos_drm_crtc_disable_vblank, }; +int exynos_drm_crtc_init(struct exynos_drm_crtc *exynos_crtc, +struct drm_device *drm_dev) +{ + struct drm_crtc *crtc = &exynos_crtc->base; + + drm_crtc_helper_add(crtc, &exynos_crtc_helper_funcs); + return drm_crtc_init_with_planes(drm_dev, crtc, NULL, NULL, +&exynos_crtc_funcs, NULL); +} + struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev, struct drm_plane *plane, enum exynos_drm_output_type type, diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.h b/drivers/gpu/drm/exynos/exynos_drm_crtc.h index dec446109e6c..9e35a9e02332 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.h +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.h @@ -18,6 +18,8 @@ #include "exynos_drm_drv.h" +int exynos_drm_crtc_init(struct exynos_drm_crtc *exynos_crtc, +struct drm_device *drm_dev); struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev, struct drm_plane *plane, enum exynos_drm_output_type out_type, -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 02/23] drm/exynos: remove spare macro
MAX_CRTC macro is not used at all. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos_drm_drv.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 6e38d0dc4457..1f6bb5516170 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -18,7 +18,6 @@ #include #include -#define MAX_CRTC 3 #define MAX_PLANE 5 #define MAX_FB_BUFFER 4 -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 00/23] drm/exynos: add support for GSCALER planes on Exynos5433
Hi Inki, GSCALERs in Exynos SoCs support conversion between wide range of image formats, plus scaling and rotation. Driver already supports mem2mem mode - via ExynosDRM IPP framework. This patchset adds support for mem to display mode - framebuffers can be converted, scaled and send directly to Display Controller. From DRM framework's point of view every GSCALER exposes drm_plane which can be connected to display controller (display panel or TV). The feature is not well documented so the development was quite difficult - a process of trial and error, vendor code analysis, guessing from datasheets. Hopefully most of the issues were solved. I have developed and tested it on TM2 device with panel and TV paths. The patchset contains three parts: 1. Preparatory patches - mostly cleanup and refactoring of drm_crtc and drm_plane related structures, to allow usage of planes which are not physically bound to crtcs (01-13). 2. Adding local path support to GSCALER and DECON (14-20). 3. Few fixes of bugs existing already in the code but discovered due to added local path support (21-23). The patchset is based on exynos_drm_next plus my patchset adding zpos to DECON and FIMD - 'drm/exynos: add support for dynamic zpos in DECON and FIMD' - it is required to allow set z-pos position of GSCALER planes. To simplify tests I have also created branch containing all required patches: Repo: https://git.tizen.org/cgit/platform/kernel/linux-exynos Branch: sandbox/ahajda/dev/exynos-drm-local-path Regards Andrzej Andrzej Hajda (23): drm/exynos: remove exynos_drm_plane.h header drm/exynos: remove spare macro drm/exynos: drop exynos_drm_plane_config structure drm/exynos: add exynos_drm_crtc_init function drm/exynos/decon5433: embed exynos_drm_crtc directly into context drm/exynos/decon7: embed exynos_drm_crtc directly into context drm/exynos/fimd: embed exynos_drm_crtc directly into context drm/exynos/mixer: embed exynos_drm_crtc directly into context drm/exynos/vidi: embed exynos_drm_crtc directly into context drm/exynos: remove standalone exynos_drm_crtc leftovers drm/exynos/vidi: remove encoder_to_vidi helper drm/exynos: unify plane type assignment drm/exynos: set primary and cursor planes in exynos_drm_crtc_init drm/exynos: add plane update/disable callbacks for planes drm/exynos: add GSCALER plane capability drm/exynos/gscaler: fix id assignement arm64: dts: exynos: configure GSCALER related clocks arm64: dts: exynos: add DSD/GSD clocks to DECONs and GSCALERs drm/exynos/gscaler: add local path support drm/exynos/decon5433: add local path support drm/exynos/decon5433: wait for finish previous update drm/exynos/gscaler: change supported color format BGRX to XBGR drm/exynos/gscaler: fix handling YVU420 pixel format .../dts/exynos/exynos5433-tm2-common.dtsi | 6 + arch/arm64/boot/dts/exynos/exynos5433-tm2.dts | 6 +- arch/arm64/boot/dts/exynos/exynos5433.dtsi| 25 +- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 162 - drivers/gpu/drm/exynos/exynos7_drm_decon.c| 66 +++-- drivers/gpu/drm/exynos/exynos_drm_crtc.c | 46 ++-- drivers/gpu/drm/exynos/exynos_drm_crtc.h | 7 +- drivers/gpu/drm/exynos/exynos_drm_drv.c | 1 - drivers/gpu/drm/exynos/exynos_drm_drv.h | 50 ++-- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 85 +++ drivers/gpu/drm/exynos/exynos_drm_gsc.c | 229 ++ drivers/gpu/drm/exynos/exynos_drm_plane.c | 84 --- drivers/gpu/drm/exynos/exynos_drm_plane.h | 14 -- drivers/gpu/drm/exynos/exynos_drm_vidi.c | 48 ++-- drivers/gpu/drm/exynos/exynos_mixer.c | 95 +++- drivers/gpu/drm/exynos/regs-decon5433.h | 6 + drivers/gpu/drm/exynos/regs-gsc.h | 6 + 17 files changed, 529 insertions(+), 407 deletions(-) delete mode 100644 drivers/gpu/drm/exynos/exynos_drm_plane.h -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 21/23] drm/exynos/decon5433: wait for finish previous update
DECON should wait for previous update before starting new one. Otherwise internal registers can be updated in non-atomic, error prone way. This patch fixes occasional occurrences of vblank timeouts on tm2 platform: [ 3167.968742] [CRTC:55:crtc-0] vblank wait timed out [ 3167.987440] WARNING: CPU: 1 PID: 194 at ../drivers/gpu/drm/drm_atomic_helper.c:1423 drm_atomic_helper_wait_for_vblanks.part.9+0x2c0/0x2c8 [ 3168.029990] Modules linked in: [ 3168.047240] CPU: 1 PID: 194 Comm: modetest Tainted: GW 5.0.0-rc1+ #694 [ 3168.069539] Hardware name: Samsung TM2 board (DT) ... [ 3168.453566] Call trace: [ 3168.469705] drm_atomic_helper_wait_for_vblanks.part.9+0x2c0/0x2c8 [ 3168.489983] drm_atomic_helper_commit_tail_rpm+0x60/0x78 [ 3168.509463] commit_tail+0x44/0x78 [ 3168.527053] drm_atomic_helper_commit+0xe8/0x160 [ 3168.546010] drm_atomic_commit+0x48/0x58 [ 3168.564304] drm_atomic_helper_update_plane+0x11c/0x140 [ 3168.584080] __setplane_atomic+0x130/0x150 [ 3168.602799] setplane_internal+0xb0/0x1a8 [ 3168.621493] drm_mode_setplane+0xc4/0x1b8 [ 3168.640219] drm_ioctl_kernel+0x94/0x110 [ 3168.658920] drm_ioctl+0x1c8/0x428 ... Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index b0332763594e..09f035f52444 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -406,6 +406,11 @@ static void decon_set_gscl_mode(struct decon_context *ctx) static void decon_atomic_begin(struct exynos_drm_crtc *crtc) { struct decon_context *ctx = to_decon(crtc); + u32 val; + + /* wait for finish previous updates */ + if (readl_poll_timeout(ctx->addr + DECON_UPDATE, val, !val, 1000, 2) < 0) + dev_err(ctx->dev, "DECON_UPDATE timeout\n"); decon_shadow_protect(ctx, true); decon_set_gscl_mode(ctx); -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 01/23] drm/exynos: remove exynos_drm_plane.h header
The header contains only declaration of one function, the rest of exynos plane declaration is in exynos_drm_drv.h. Let's merge it together. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 1 - drivers/gpu/drm/exynos/exynos7_drm_decon.c| 1 - drivers/gpu/drm/exynos/exynos_drm_crtc.c | 1 - drivers/gpu/drm/exynos/exynos_drm_drv.c | 1 - drivers/gpu/drm/exynos/exynos_drm_drv.h | 4 drivers/gpu/drm/exynos/exynos_drm_fimd.c | 1 - drivers/gpu/drm/exynos/exynos_drm_plane.c | 1 - drivers/gpu/drm/exynos/exynos_drm_plane.h | 14 -- drivers/gpu/drm/exynos/exynos_drm_vidi.c | 1 - drivers/gpu/drm/exynos/exynos_mixer.c | 1 - 10 files changed, 4 insertions(+), 22 deletions(-) delete mode 100644 drivers/gpu/drm/exynos/exynos_drm_plane.h diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index bdfec5f977e9..24df0b307b2f 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -24,7 +24,6 @@ #include "exynos_drm_drv.h" #include "exynos_drm_crtc.h" #include "exynos_drm_fb.h" -#include "exynos_drm_plane.h" #include "regs-decon5433.h" #define DSD_CFG_MUX 0x1004 diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c index 381aa3d60e37..812941b84287 100644 --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c @@ -27,7 +27,6 @@ #include #include "exynos_drm_crtc.h" -#include "exynos_drm_plane.h" #include "exynos_drm_drv.h" #include "exynos_drm_fb.h" #include "regs-decon7.h" diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 96ee83a798c4..1eebfa3fa8da 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -20,7 +20,6 @@ #include "exynos_drm_crtc.h" #include "exynos_drm_drv.h" -#include "exynos_drm_plane.h" static void exynos_drm_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index e1ef9dc9ebf3..2155586646dc 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -26,7 +26,6 @@ #include "exynos_drm_fbdev.h" #include "exynos_drm_fb.h" #include "exynos_drm_gem.h" -#include "exynos_drm_plane.h" #include "exynos_drm_ipp.h" #include "exynos_drm_vidi.h" #include "exynos_drm_g2d.h" diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 71eb240bc1f4..6e38d0dc4457 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -113,6 +113,10 @@ struct exynos_drm_plane_config { unsigned int capabilities; }; +int exynos_plane_init(struct drm_device *dev, + struct exynos_drm_plane *exynos_plane, unsigned int index, + const struct exynos_drm_plane_config *config); + /* * Exynos drm crtc ops * diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 46588a14f0c3..b1a9502a4140 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -31,7 +31,6 @@ #include "exynos_drm_drv.h" #include "exynos_drm_fb.h" #include "exynos_drm_crtc.h" -#include "exynos_drm_plane.h" /* * FIMD stands for Fully Interactive Mobile Display and diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index df0508e0e49e..8af0eba3f362 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -19,7 +19,6 @@ #include "exynos_drm_crtc.h" #include "exynos_drm_fb.h" #include "exynos_drm_gem.h" -#include "exynos_drm_plane.h" /* * This function is to get X or Y size shown via screen. This needs length and diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.h b/drivers/gpu/drm/exynos/exynos_drm_plane.h deleted file mode 100644 index 497047b19614.. --- a/drivers/gpu/drm/exynos/exynos_drm_plane.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (C) 2011 Samsung Electronics Co.Ltd - * Authors: Joonyoung Shim - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -int exynos_plane_init(struct drm_device *dev, - struct exynos_drm_plane *exynos_plane, unsigned int index, - const struct exynos_drm_plane_config *config); diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index 29f4c1932ae
[PATCH 11/23] drm/exynos/vidi: remove encoder_to_vidi helper
It can be replaced by recently introduced to_vidi helper. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos_drm_vidi.c | 7 +-- 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index 377aae5f7631..2579462aec70 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -52,11 +52,6 @@ struct vidi_context { struct mutexlock; }; -static inline struct vidi_context *encoder_to_vidi(struct drm_encoder *e) -{ - return container_of(e, struct vidi_context, encoder); -} - #define to_vidi(ptr) container_of(ptr, struct vidi_context, ptr) static const char fake_edid_info[] = { @@ -331,7 +326,7 @@ static const struct drm_connector_helper_funcs vidi_connector_helper_funcs = { static int vidi_create_connector(struct drm_encoder *encoder) { - struct vidi_context *ctx = encoder_to_vidi(encoder); + struct vidi_context *ctx = to_vidi(encoder); struct drm_connector *connector = &ctx->connector; int ret; -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 17/23] arm64: dts: exynos: configure GSCALER related clocks
GSCALER should be feed with clock at certain rates. Signed-off-by: Andrzej Hajda --- arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi | 6 ++ arch/arm64/boot/dts/exynos/exynos5433-tm2.dts | 6 -- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi index d88e2f0e179a..d2de16645e10 100644 --- a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi @@ -289,6 +289,12 @@ assigned-clock-parents = <&cmu_top CLK_ACLK_MFC_400>; }; +&cmu_mif { + assigned-clocks = <&cmu_mif CLK_MOUT_SCLK_DSD_A>, <&cmu_mif CLK_DIV_SCLK_DSD>; + assigned-clock-parents = <&cmu_mif CLK_MOUT_MFC_PLL_DIV2>; + assigned-clock-rates = <0>, <33300>; +}; + &cmu_mscl { assigned-clocks = <&cmu_mscl CLK_MOUT_ACLK_MSCL_400_USER>, <&cmu_mscl CLK_MOUT_SCLK_JPEG_USER>, diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts index 3d7e0a782243..dda5d2746a74 100644 --- a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts +++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts @@ -33,7 +33,8 @@ <&cmu_disp CLK_MOUT_DISP_PLL>, <&cmu_mif CLK_MOUT_SCLK_DECON_TV_ECLK_A>, <&cmu_disp CLK_MOUT_SCLK_DECON_TV_ECLK_USER>, - <&cmu_disp CLK_MOUT_SCLK_DECON_TV_ECLK>; + <&cmu_disp CLK_MOUT_SCLK_DECON_TV_ECLK>, + <&cmu_disp CLK_MOUT_SCLK_DSD_USER>; assigned-clock-parents = <0>, <0>, <&cmu_mif CLK_ACLK_DISP_333>, <&cmu_mif CLK_SCLK_DSIM0_DISP>, @@ -45,7 +46,8 @@ <&cmu_disp CLK_FOUT_DISP_PLL>, <&cmu_mif CLK_MOUT_BUS_PLL_DIV2>, <&cmu_mif CLK_SCLK_DECON_TV_ECLK_DISP>, -<&cmu_disp CLK_MOUT_SCLK_DECON_TV_ECLK_USER>; +<&cmu_disp CLK_MOUT_SCLK_DECON_TV_ECLK_USER>, +<&cmu_mif CLK_SCLK_DSD_DISP>; assigned-clock-rates = <25000>, <4>; }; -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 05/23] drm/exynos/decon5433: embed exynos_drm_crtc directly into context
Since crtc maps 1:1 to the device there is no point in allocating it separately, another benefit is possibility of direct initialisation of its fields which is more readable and allows further expansion. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 52 +-- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index ae0f475eb633..0d409f453923 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -54,7 +54,7 @@ static const char * const decon_clks_name[] = { struct decon_context { struct device *dev; struct drm_device *drm_dev; - struct exynos_drm_crtc *crtc; + struct exynos_drm_crtc crtc; struct exynos_drm_plane planes[WINDOWS_NR]; void __iomem*addr; struct regmap *sysreg; @@ -69,6 +69,8 @@ struct decon_context { u32 frame_id; }; +#define to_decon(ptr) container_of(ptr, struct decon_context, ptr) + static const uint32_t decon_formats[] = { DRM_FORMAT_XRGB1555, DRM_FORMAT_RGB565, @@ -90,7 +92,7 @@ static inline void decon_set_bits(struct decon_context *ctx, u32 reg, u32 mask, static int decon_enable_vblank(struct exynos_drm_crtc *crtc) { - struct decon_context *ctx = crtc->ctx; + struct decon_context *ctx = to_decon(crtc); u32 val; val = VIDINTCON0_INTEN; @@ -110,7 +112,7 @@ static int decon_enable_vblank(struct exynos_drm_crtc *crtc) static void decon_disable_vblank(struct exynos_drm_crtc *crtc) { - struct decon_context *ctx = crtc->ctx; + struct decon_context *ctx = to_decon(crtc); if (!(ctx->out_type & I80_HW_TRG)) disable_irq_nosync(ctx->te_irq); @@ -143,7 +145,7 @@ static u32 decon_get_frame_count(struct decon_context *ctx, bool end) switch (status & (VIDCON1_VSTATUS_MASK | VIDCON1_I80_ACTIVE)) { case VIDCON1_VSTATUS_VS: - if (!(ctx->crtc->i80_mode)) + if (!(ctx->crtc.i80_mode)) --frm; break; case VIDCON1_VSTATUS_BP: @@ -163,7 +165,7 @@ static u32 decon_get_frame_count(struct decon_context *ctx, bool end) static void decon_setup_trigger(struct decon_context *ctx) { - if (!ctx->crtc->i80_mode && !(ctx->out_type & I80_HW_TRG)) + if (!ctx->crtc.i80_mode && !(ctx->out_type & I80_HW_TRG)) return; if (!(ctx->out_type & I80_HW_TRG)) { @@ -183,7 +185,7 @@ static void decon_setup_trigger(struct decon_context *ctx) static void decon_commit(struct exynos_drm_crtc *crtc) { - struct decon_context *ctx = crtc->ctx; + struct decon_context *ctx = to_decon(crtc); struct drm_display_mode *m = &crtc->base.mode; bool interlaced = false; u32 val; @@ -377,7 +379,7 @@ static void decon_shadow_protect(struct decon_context *ctx, bool protect) static void decon_atomic_begin(struct exynos_drm_crtc *crtc) { - struct decon_context *ctx = crtc->ctx; + struct decon_context *ctx = to_decon(crtc); decon_shadow_protect(ctx, true); } @@ -391,7 +393,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, { struct exynos_drm_plane_state *state = to_exynos_plane_state(plane->base.state); - struct decon_context *ctx = crtc->ctx; + struct decon_context *ctx = to_decon(crtc); struct drm_framebuffer *fb = state->base.fb; unsigned int win = state->base.normalized_zpos + ctx->first_win; unsigned int cpp = fb->format->cpp[0]; @@ -445,7 +447,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, static void decon_atomic_flush(struct exynos_drm_crtc *crtc) { - struct decon_context *ctx = crtc->ctx; + struct decon_context *ctx = to_decon(crtc); unsigned long flags; int win = hweight32(crtc->base.state->plane_mask) + ctx->first_win; @@ -502,7 +504,7 @@ static void decon_swreset(struct decon_context *ctx) static void decon_enable(struct exynos_drm_crtc *crtc) { - struct decon_context *ctx = crtc->ctx; + struct decon_context *ctx = to_decon(crtc); pm_runtime_get_sync(ctx->dev); @@ -510,12 +512,12 @@ static void decon_enable(struct exynos_drm_crtc *crtc) decon_swreset(ctx); - decon_commit(ctx->crtc); + decon_commit(&ctx->crtc); } static void decon_disable(struct exynos_drm_crtc *crtc) { - struct decon_context *ctx = crtc->ctx; + struct decon_context *ctx = to_decon(crtc); int i; if (!(ctx->out_type & I80_HW_TRG)) @@ -548,7 +550,7 @@ static irqreturn_t decon_te_irq_handler(int irq, void *dev_id) static void decon_clear_channels(struct exynos_
[PATCH 14/23] drm/exynos: add plane update/disable callbacks for planes
Display controllers in Exynos beside native planes/windows can use external planes provided by other IPs - GSCALER, FIMD, VPP. To add support to them we will need plane specific callbacks. Signed-off-by: Andrzej Hajda --- drivers/gpu/drm/exynos/exynos_drm_drv.h | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 6643db865500..5d06e796dc80 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -76,6 +76,12 @@ to_exynos_plane_state(struct drm_plane_state *state) #define EXYNOS_DRM_PLANE_CAP_PIX_BLEND (1 << 4) #define EXYNOS_DRM_PLANE_CAP_WIN_BLEND (1 << 5) +struct exynos_drm_plane; +struct exynos_drm_plane_ops { + void (*update_plane)(struct exynos_drm_plane *plane); + void (*disable_plane)(struct exynos_drm_plane *plane); +}; + /* * Exynos drm common overlay structure. * @@ -89,6 +95,7 @@ to_exynos_plane_state(struct drm_plane_state *state) struct exynos_drm_plane { struct drm_plane base; + const struct exynos_drm_plane_ops *ops; unsigned int index; unsigned int capabilities; }; -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel