1caab277bSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
214be3200SRob Clark /*
314be3200SRob Clark  * Copyright (c) 2014, The Linux Foundation. All rights reserved.
414be3200SRob Clark  * Copyright (C) 2013 Red Hat
514be3200SRob Clark  * Author: Rob Clark <robdclark@gmail.com>
614be3200SRob Clark  */
714be3200SRob Clark 
814be3200SRob Clark #ifndef __MDP5_SMP_H__
914be3200SRob Clark #define __MDP5_SMP_H__
1014be3200SRob Clark 
1114be3200SRob Clark #include <drm/drm_print.h>
1214be3200SRob Clark 
1314be3200SRob Clark #include "msm_drv.h"
1414be3200SRob Clark 
1514be3200SRob Clark /*
1614be3200SRob Clark  * SMP - Shared Memory Pool:
1714be3200SRob Clark  *
1814be3200SRob Clark  * SMP blocks are shared between all the clients, where each plane in
1914be3200SRob Clark  * a scanout buffer is a SMP client.  Ie. scanout of 3 plane I420 on
2014be3200SRob Clark  * pipe VIG0 => 3 clients: VIG0_Y, VIG0_CB, VIG0_CR.
2114be3200SRob Clark  *
2214be3200SRob Clark  * Based on the size of the attached scanout buffer, a certain # of
2314be3200SRob Clark  * blocks must be allocated to that client out of the shared pool.
2414be3200SRob Clark  *
2514be3200SRob Clark  * In some hw, some blocks are statically allocated for certain pipes
2614be3200SRob Clark  * and CANNOT be re-allocated (eg: MMB0 and MMB1 both tied to RGB0).
2714be3200SRob Clark  *
2814be3200SRob Clark  *
2914be3200SRob Clark  * Atomic SMP State:
3014be3200SRob Clark  *
3114be3200SRob Clark  * On atomic updates that modify SMP configuration, the state is cloned
3214be3200SRob Clark  * (copied) and modified.  For test-only, or in cases where atomic
3314be3200SRob Clark  * update fails (or if we hit ww_mutex deadlock/backoff condition) the
3414be3200SRob Clark  * new state is simply thrown away.
3514be3200SRob Clark  *
3614be3200SRob Clark  * Because the SMP registers are not double buffered, updates are a
3714be3200SRob Clark  * two step process:
3814be3200SRob Clark  *
3914be3200SRob Clark  * 1) in _prepare_commit() we configure things (via read-modify-write)
4014be3200SRob Clark  *    for the newly assigned pipes, so we don't take away blocks
4114be3200SRob Clark  *    assigned to pipes that are still scanning out
4214be3200SRob Clark  * 2) in _complete_commit(), after vblank/etc, we clear things for the
4314be3200SRob Clark  *    released clients, since at that point old pipes are no longer
4414be3200SRob Clark  *    scanning out.
4514be3200SRob Clark  */
4614be3200SRob Clark struct mdp5_smp_state {
4714be3200SRob Clark 	/* global state of what blocks are in use: */
4814be3200SRob Clark 	mdp5_smp_state_t state;
4914be3200SRob Clark 
5014be3200SRob Clark 	/* per client state of what blocks they are using: */
5114be3200SRob Clark 	mdp5_smp_state_t client_state[MAX_CLIENTS];
5214be3200SRob Clark 
5314be3200SRob Clark 	/* assigned pipes (hw updated at _prepare_commit()): */
5414be3200SRob Clark 	unsigned long assigned;
5514be3200SRob Clark 
5614be3200SRob Clark 	/* released pipes (hw updated at _complete_commit()): */
5714be3200SRob Clark 	unsigned long released;
5814be3200SRob Clark };
5914be3200SRob Clark 
6014be3200SRob Clark struct mdp5_kms;
6114be3200SRob Clark struct mdp5_smp;
6214be3200SRob Clark 
6314be3200SRob Clark /*
6414be3200SRob Clark  * SMP module prototypes:
6514be3200SRob Clark  * mdp5_smp_init() returns a SMP @handler,
6614be3200SRob Clark  * which is then used to call the other mdp5_smp_*(handler, ...) functions.
6714be3200SRob Clark  */
6814be3200SRob Clark 
6914be3200SRob Clark struct mdp5_smp *mdp5_smp_init(struct mdp5_kms *mdp5_kms,
7014be3200SRob Clark 		const struct mdp5_smp_block *cfg);
7114be3200SRob Clark void  mdp5_smp_destroy(struct mdp5_smp *smp);
7214be3200SRob Clark 
7314be3200SRob Clark void mdp5_smp_dump(struct mdp5_smp *smp, struct drm_printer *p);
7414be3200SRob Clark 
7514be3200SRob Clark uint32_t mdp5_smp_calculate(struct mdp5_smp *smp,
7614be3200SRob Clark 		const struct mdp_format *format,
7714be3200SRob Clark 		u32 width, bool hdecim);
7814be3200SRob Clark 
7914be3200SRob Clark int mdp5_smp_assign(struct mdp5_smp *smp, struct mdp5_smp_state *state,
8014be3200SRob Clark 		enum mdp5_pipe pipe, uint32_t blkcfg);
8114be3200SRob Clark void mdp5_smp_release(struct mdp5_smp *smp, struct mdp5_smp_state *state,
8214be3200SRob Clark 		enum mdp5_pipe pipe);
8314be3200SRob Clark 
8414be3200SRob Clark void mdp5_smp_prepare_commit(struct mdp5_smp *smp, struct mdp5_smp_state *state);
8514be3200SRob Clark void mdp5_smp_complete_commit(struct mdp5_smp *smp, struct mdp5_smp_state *state);
8614be3200SRob Clark 
8714be3200SRob Clark #endif /* __MDP5_SMP_H__ */
88