Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/amd/display: Add 3DLUT DMA broadcast support

[WHY&HOW]
A single HUBP can be used to fetch 3DLUT and broadcast to a
single HUBP. Add logic to select the top pipe for a given
plane and use it's HUBP as the broadcast source for multiple
MPC's.

Reviewed-by: Ilya Bakoulin <ilya.bakoulin@amd.com>
Signed-off-by: Dillon Varone <Dillon.Varone@amd.com>
Signed-off-by: Chuanyu Tseng <chuanyu.tseng@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Dillon Varone and committed by
Alex Deucher
7d59465d 60e8ffaf

+66 -47
+1 -1
drivers/gpu/drm/amd/display/dc/core/dc.c
··· 4617 4617 srf_updates[i].cm->flags.bits.lut3d_enable && 4618 4618 srf_updates[i].cm->flags.bits.lut3d_dma_enable && 4619 4619 dc->hwss.trigger_3dlut_dma_load) 4620 - dc->hwss.trigger_3dlut_dma_load(dc, pipe_ctx); 4620 + dc->hwss.trigger_3dlut_dma_load(pipe_ctx); 4621 4621 4622 4622 /*program triple buffer after lock based on flip type*/ 4623 4623 if (dc->hwss.program_triplebuffer != NULL && dc->debug.enable_tri_buf) {
+63 -43
drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
··· 369 369 } 370 370 } 371 371 372 - void dcn401_trigger_3dlut_dma_load(struct dc *dc, struct pipe_ctx *pipe_ctx) 372 + void dcn401_trigger_3dlut_dma_load(struct pipe_ctx *pipe_ctx) 373 373 { 374 - struct hubp *hubp = pipe_ctx->plane_res.hubp; 374 + const struct pipe_ctx *primary_dpp_pipe_ctx = resource_get_primary_dpp_pipe(pipe_ctx); 375 + struct hubp *primary_hubp = primary_dpp_pipe_ctx ? 376 + primary_dpp_pipe_ctx->plane_res.hubp : NULL; 375 377 376 - if (hubp->funcs->hubp_enable_3dlut_fl) { 377 - hubp->funcs->hubp_enable_3dlut_fl(hubp, true); 378 + if (primary_hubp && primary_hubp->funcs->hubp_enable_3dlut_fl) { 379 + primary_hubp->funcs->hubp_enable_3dlut_fl(primary_hubp, true); 378 380 } 379 381 } 380 382 ··· 384 382 const struct dc_plane_state *plane_state) 385 383 { 386 384 struct dc *dc = pipe_ctx->plane_res.hubp->ctx->dc; 385 + const struct pipe_ctx *primary_dpp_pipe_ctx = resource_get_primary_dpp_pipe(pipe_ctx); 387 386 struct dpp *dpp_base = pipe_ctx->plane_res.dpp; 388 387 struct hubp *hubp = pipe_ctx->plane_res.hubp; 388 + struct hubp *primary_hubp = primary_dpp_pipe_ctx ? 389 + primary_dpp_pipe_ctx->plane_res.hubp : NULL; 389 390 const struct dc_plane_cm *cm = &plane_state->cm; 390 391 int mpcc_id = hubp->inst; 391 392 struct mpc *mpc = dc->res_pool->mpc; ··· 486 481 mpc->funcs->program_lut_read_write_control(mpc, MCM_LUT_3DLUT, lut_bank_a, 12, mpcc_id); 487 482 488 483 if (mpc->funcs->update_3dlut_fast_load_select) 489 - mpc->funcs->update_3dlut_fast_load_select(mpc, mpcc_id, hubp->inst); 484 + mpc->funcs->update_3dlut_fast_load_select(mpc, mpcc_id, primary_hubp->inst); 490 485 491 486 /* HUBP */ 492 - if (hubp->funcs->hubp_program_3dlut_fl_config) 493 - hubp->funcs->hubp_program_3dlut_fl_config(hubp, &cm->lut3d_dma); 487 + if (primary_hubp->inst == hubp->inst) { 488 + /* only program if this is the primary dpp pipe for the given plane */ 489 + if (hubp->funcs->hubp_program_3dlut_fl_config) 490 + hubp->funcs->hubp_program_3dlut_fl_config(hubp, &cm->lut3d_dma); 494 491 495 - if (hubp->funcs->hubp_program_3dlut_fl_crossbar) 496 - hubp->funcs->hubp_program_3dlut_fl_crossbar(hubp, cm->lut3d_dma.format); 492 + if (hubp->funcs->hubp_program_3dlut_fl_crossbar) 493 + hubp->funcs->hubp_program_3dlut_fl_crossbar(hubp, cm->lut3d_dma.format); 497 494 498 - if (hubp->funcs->hubp_program_3dlut_fl_addr) 499 - hubp->funcs->hubp_program_3dlut_fl_addr(hubp, &cm->lut3d_dma.addr); 495 + if (hubp->funcs->hubp_program_3dlut_fl_addr) 496 + hubp->funcs->hubp_program_3dlut_fl_addr(hubp, &cm->lut3d_dma.addr); 500 497 501 - if (hubp->funcs->hubp_enable_3dlut_fl) { 502 - hubp->funcs->hubp_enable_3dlut_fl(hubp, true); 498 + if (hubp->funcs->hubp_enable_3dlut_fl) { 499 + hubp->funcs->hubp_enable_3dlut_fl(hubp, true); 500 + } else { 501 + /* GPU memory only supports fast load path */ 502 + BREAK_TO_DEBUGGER(); 503 + lut_enable = false; 504 + result = false; 505 + } 503 506 } else { 504 - /* GPU memory only supports fast load path */ 505 - BREAK_TO_DEBUGGER(); 506 - lut_enable = false; 507 - result = false; 507 + /* re-trigger priamry HUBP to load 3DLUT */ 508 + if (primary_hubp->funcs->hubp_enable_3dlut_fl) { 509 + primary_hubp->funcs->hubp_enable_3dlut_fl(primary_hubp, true); 510 + } 511 + 512 + /* clear FL setup on this pipe's HUBP */ 513 + memset(&lut3d_dma, 0, sizeof(lut3d_dma)); 514 + if (hubp->funcs->hubp_program_3dlut_fl_config) 515 + hubp->funcs->hubp_program_3dlut_fl_config(hubp, &lut3d_dma); 516 + 517 + if (hubp->funcs->hubp_enable_3dlut_fl) 518 + hubp->funcs->hubp_enable_3dlut_fl(hubp, false); 508 519 } 509 520 } else { 510 521 /* Legacy (Host) Load Mode */ ··· 1830 1809 * This is meant to work around a known HW issue where VREADY will cancel the pending 3DLUT_ENABLE signal regardless 1831 1810 * of whether OTG lock is currently being held or not. 1832 1811 */ 1833 - struct pipe_ctx *wa_pipes[MAX_PIPES] = { NULL }; 1834 - struct pipe_ctx *odm_pipe, *mpc_pipe; 1835 - int i, wa_pipe_ct = 0; 1812 + const struct pipe_ctx *otg_master_pipe_ctx = resource_get_otg_master(pipe_ctx); 1813 + struct timing_generator *tg = otg_master_pipe_ctx ? 1814 + otg_master_pipe_ctx->stream_res.tg : NULL; 1815 + const struct pipe_ctx *primary_dpp_pipe_ctx = resource_is_pipe_type(pipe_ctx, DPP_PIPE) ? 1816 + resource_get_primary_dpp_pipe(pipe_ctx) : pipe_ctx; 1817 + struct hubp *primary_hubp = primary_dpp_pipe_ctx ? 1818 + primary_dpp_pipe_ctx->plane_res.hubp : NULL; 1836 1819 1837 - for (odm_pipe = pipe_ctx; odm_pipe != NULL; odm_pipe = odm_pipe->next_odm_pipe) { 1838 - for (mpc_pipe = odm_pipe; mpc_pipe != NULL; mpc_pipe = mpc_pipe->bottom_pipe) { 1839 - if (mpc_pipe->plane_state && 1840 - mpc_pipe->plane_state->cm.flags.bits.lut3d_enable && 1841 - mpc_pipe->plane_state->cm.flags.bits.lut3d_dma_enable) { 1842 - wa_pipes[wa_pipe_ct++] = mpc_pipe; 1843 - } 1844 - } 1820 + if (!otg_master_pipe_ctx && !tg) { 1821 + return; 1845 1822 } 1846 1823 1847 - if (wa_pipe_ct > 0) { 1848 - if (pipe_ctx->stream_res.tg->funcs->set_vupdate_keepout) 1849 - pipe_ctx->stream_res.tg->funcs->set_vupdate_keepout(pipe_ctx->stream_res.tg, true); 1824 + if (primary_dpp_pipe_ctx && 1825 + primary_dpp_pipe_ctx->plane_state && 1826 + primary_dpp_pipe_ctx->plane_state->cm.flags.bits.lut3d_enable && 1827 + primary_dpp_pipe_ctx->plane_state->cm.flags.bits.lut3d_dma_enable) { 1828 + if (tg->funcs->set_vupdate_keepout) 1829 + tg->funcs->set_vupdate_keepout(tg, true); 1850 1830 1851 - for (i = 0; i < wa_pipe_ct; ++i) { 1852 - if (wa_pipes[i]->plane_res.hubp->funcs->hubp_enable_3dlut_fl) 1853 - wa_pipes[i]->plane_res.hubp->funcs->hubp_enable_3dlut_fl(wa_pipes[i]->plane_res.hubp, true); 1831 + if (primary_hubp->funcs->hubp_enable_3dlut_fl) { 1832 + primary_hubp->funcs->hubp_enable_3dlut_fl(primary_hubp, true); 1854 1833 } 1855 1834 1856 - pipe_ctx->stream_res.tg->funcs->unlock(pipe_ctx->stream_res.tg); 1857 - if (pipe_ctx->stream_res.tg->funcs->wait_update_lock_status) 1858 - pipe_ctx->stream_res.tg->funcs->wait_update_lock_status(pipe_ctx->stream_res.tg, false); 1835 + tg->funcs->unlock(tg); 1836 + if (tg->funcs->wait_update_lock_status) 1837 + tg->funcs->wait_update_lock_status(tg, false); 1859 1838 1860 - for (i = 0; i < wa_pipe_ct; ++i) { 1861 - if (wa_pipes[i]->plane_res.hubp->funcs->hubp_enable_3dlut_fl) 1862 - wa_pipes[i]->plane_res.hubp->funcs->hubp_enable_3dlut_fl(wa_pipes[i]->plane_res.hubp, true); 1839 + if (primary_hubp->funcs->hubp_enable_3dlut_fl) { 1840 + primary_hubp->funcs->hubp_enable_3dlut_fl(primary_hubp, true); 1863 1841 } 1864 1842 1865 - if (pipe_ctx->stream_res.tg->funcs->set_vupdate_keepout) 1866 - pipe_ctx->stream_res.tg->funcs->set_vupdate_keepout(pipe_ctx->stream_res.tg, false); 1843 + if (tg->funcs->set_vupdate_keepout) 1844 + tg->funcs->set_vupdate_keepout(tg, false); 1867 1845 } else { 1868 - pipe_ctx->stream_res.tg->funcs->unlock(pipe_ctx->stream_res.tg); 1846 + tg->funcs->unlock(tg); 1869 1847 } 1870 1848 } 1871 1849
+1 -2
drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h
··· 41 41 bool dcn401_set_output_transfer_func(struct dc *dc, 42 42 struct pipe_ctx *pipe_ctx, 43 43 const struct dc_stream_state *stream); 44 - void dcn401_trigger_3dlut_dma_load(struct dc *dc, 45 - struct pipe_ctx *pipe_ctx); 44 + void dcn401_trigger_3dlut_dma_load(struct pipe_ctx *pipe_ctx); 46 45 void dcn401_calculate_dccg_tmds_div_value(struct pipe_ctx *pipe_ctx, 47 46 unsigned int *tmds_div); 48 47 enum dc_status dcn401_enable_stream_timing(
+1 -1
drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
··· 1120 1120 void (*program_output_csc)(struct dc *dc, struct pipe_ctx *pipe_ctx, 1121 1121 enum dc_color_space colorspace, 1122 1122 uint16_t *matrix, int opp_id); 1123 - void (*trigger_3dlut_dma_load)(struct dc *dc, struct pipe_ctx *pipe_ctx); 1123 + void (*trigger_3dlut_dma_load)(struct pipe_ctx *pipe_ctx); 1124 1124 1125 1125 /* VM Related */ 1126 1126 int (*init_sys_ctx)(struct dce_hwseq *hws,