summaryrefslogblamecommitdiffstats
path: root/drivers/gpu/nvgpu/boardobj/boardobjgrp.h
blob: 625e791251975fa690fb0d05447244edddae2069 (plain) (tree)
1
2
3
  
                                                                    
 
















                                                                             





                       
             


                       

                                                                               


                              

                       




                                
                                                                   




                                                                             
                                                                   




















                                                                               
                                                                             






                                                                          
                                                      





                                                                              
                                                       







                                                                             
                                                    







                                                                        
                                               





                                                        
                                                     


                                                 
                                                       


                                                            
                                                                                










                                                                          


                                 











                                                                              
                       








                                                                              
                                                         

                                                                 
                                                                                     



                                          
                                                       
                                                 





                                                                             
                                                             









                                                                           
                        

























                                                              
                                    






























































                                                                                












                                                                            



















                                                                             
                                                                         
















                                                                               



                                                                          





                                                                                     







                                                                          


                                                                               
                                                                               

                                                                                            


                                                                                 


                                                                                

                                                







                                                                         

                                                                      







                                                              

                                                              


                                                                       


                                 


                                   








































                                                                        







                                                                       





                                                      
      
/*
* Copyright (c) 2016-2018, NVIDIA CORPORATION.  All rights reserved.
*
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
*/

#ifndef _BOARDOBJGRP_H_
#define _BOARDOBJGRP_H_

struct boardobjgrp;
struct gk20a;
struct nvgpu_list_node;
struct pmu_surface;


/* ------------------------ Includes ----------------------------------------*/
#include "ctrl/ctrlboardobj.h"
#include "boardobj.h"
#include "boardobjgrpmask.h"
#include <nvgpu/list.h>
#include <nvgpu/pmu.h>

/*
* Board Object Group destructor.
*
*/
typedef int boardobjgrp_destruct(struct boardobjgrp *pboardobjgrp);

/*
* Inserts a previously constructed Board Object into a Board Object Group for
* tracking. Objects are inserted in the array based on the given index.
*/
typedef int boardobjgrp_objinsert(struct boardobjgrp *pboardobjgrp,
		struct boardobj *pboardobj, u8 index);

/*
* Retrieves a Board Object from a Board Object Group using the group's index.
*
*/
typedef struct boardobj *boardobjgrp_objgetbyidx(
		struct boardobjgrp *pBobrdobjgrp, u8 index);

/*
* Retrieve Board Object immediately following one pointed by @ref pcurrentindex
* filtered out by the provided mask. If (pMask == NULL) => no filtering.
*/
typedef struct boardobj *boardobjgrp_objgetnext(
		struct boardobjgrp *pboardobjgrp,
		u8 *currentindex, struct boardobjgrpmask *mask);

/*
* Board Object Group Remover and destructor. This is used to remove and
* destruct specific entry from the Board Object Group.
*/
typedef int boardobjgrp_objremoveanddestroy(struct boardobjgrp *pboardobjgrp,
	u8 index);

/*
* BOARDOBJGRP handler for PMU_UNIT_INIT.  Calls the PMU_UNIT_INIT handlers
* for the constructed PMU CMDs, and then sets the object via the
* PMU_BOARDOBJ_CMD_GRP interface (if constructed).
*/
typedef int boardobjgrp_pmuinithandle(struct gk20a *g,
		struct boardobjgrp *pboardobjGrp);

/*
* Fills out the appropriate the PMU_BOARDOBJGRP_<xyz> driver<->PMU description
* header structure, more specifically a mask of BOARDOBJs.
*/
typedef int boardobjgrp_pmuhdrdatainit(struct gk20a *g,
		struct boardobjgrp *pboardobjgrp,
		struct nv_pmu_boardobjgrp_super *pboardobjgrppmu,
		struct boardobjgrpmask *mask);

/*
* Fills out the appropriate the PMU_BOARDOBJGRP_<xyz> driver->PMU description
* structure, describing the BOARDOBJGRP and all of its BOARDOBJs to the PMU.
*/
typedef int boardobjgrp_pmudatainit(struct gk20a *g,
		struct boardobjgrp *pboardobjgrp,
		struct nv_pmu_boardobjgrp_super *pboardobjgrppmu);

/*
* Sends a BOARDOBJGRP to the PMU via the PMU_BOARDOBJ_CMD_GRP interface.
* This interface leverages @ref boardobjgrp_pmudatainit to populate the
* structure.
*/
typedef int boardobjgrp_pmuset(struct gk20a *g,
		struct boardobjgrp *pboardobjgrp);

/*
* Gets the dynamic status of the PMU BOARDOBJGRP via the
* PMU_BOARDOBJ_CMD_GRP GET_STATUS interface.
*/
typedef int boardobjgrp_pmugetstatus(struct gk20a *g,
		struct boardobjgrp *pboardobjgrp,
		struct boardobjgrpmask *mask);

typedef int boardobjgrp_pmudatainstget(struct gk20a *g,
	struct nv_pmu_boardobjgrp  *boardobjgrppmu,
	struct nv_pmu_boardobj **ppboardobjpmudata, u8 idx);

typedef int boardobjgrp_pmustatusinstget(struct gk20a *g, void *pboardobjgrppmu,
	struct nv_pmu_boardobj_query **ppBoardobjpmustatus, u8 idx);

/*
* Structure describing an PMU CMD for interacting with the representaition
* of this BOARDOBJGRP within the PMU.
*/
struct boardobjgrp_pmu_cmd {
	u8   id;
	u8   msgid;
	u8   hdrsize;
	u8   entrysize;
	u16 dmem_buffer_size;
	u32 super_surface_offset;
	u32 fbsize;
	struct nv_pmu_boardobjgrp_super *buf;
	struct pmu_surface surf;
};

/*
* Structure of state describing how to communicate with representation of this
* BOARDOBJGRP in the PMU.
*/
struct boardobjgrp_pmu {
	u8   unitid;
	u8   classid;
	bool bset;
	u8 rpc_func_id;
	struct boardobjgrp_pmu_cmd set;
	struct boardobjgrp_pmu_cmd getstatus;
};

/*
* Function by which a class which implements BOARDOBJGRP can construct a PMU
* CMD.  This provides the various information describing the PMU CMD including
* the CMD and MSG ID and the size of the various sturctures in the payload.
*/
typedef int boardobjgrp_pmucmd_construct(struct gk20a *g,
		struct boardobjgrp *pboardobjgrp,
		struct boardobjgrp_pmu_cmd *cmd, u8 id, u8 msgid,
		u8 hdrsize, u8 entrysize, u16 fbsize, u32 ss_offset, u8 rpc_func_id);

/*
* Destroys BOARDOBJGRP PMU SW state.  CMD.
*/
typedef int boardobjgrp_pmucmd_destroy(struct gk20a *g,
		struct boardobjgrp_pmu_cmd *cmd);

/*
* init handler for the BOARDOBJGRP PMU CMD.  Allocates and maps the
* PMU CMD payload within both the PMU and driver so that it can be referenced
* at run-time.
*/
typedef int boardobjgrp_pmucmd_pmuinithandle(struct gk20a *g,
	struct boardobjgrp *pboardobjgrp,
	struct boardobjgrp_pmu_cmd *cmd);

/*
* Base Class Group for all physical or logical device on the PCB.
* Contains fields common to all devices on the board. Specific types of
* devices groups may extend this object adding any details specific to that
* device group or device-type.
*/
struct boardobjgrp {
	struct gk20a *g;
	u32  objmask;
	bool bconstructed;
	u8 type;
	u8 classid;
	struct boardobj **ppobjects;
	struct boardobjgrpmask *mask;
	u8  objslots;
	u8  objmaxidx;
	struct boardobjgrp_pmu  pmu;

	/* Basic interfaces */
	boardobjgrp_destruct  *destruct;
	boardobjgrp_objinsert *objinsert;
	boardobjgrp_objgetbyidx *objgetbyidx;
	boardobjgrp_objgetnext  *objgetnext;
	boardobjgrp_objremoveanddestroy  *objremoveanddestroy;

	/* PMU interfaces */
	boardobjgrp_pmuinithandle *pmuinithandle;
	boardobjgrp_pmuhdrdatainit  *pmuhdrdatainit;
	boardobjgrp_pmudatainit *pmudatainit;
	boardobjgrp_pmuset  *pmuset;
	boardobjgrp_pmugetstatus *pmugetstatus;

	boardobjgrp_pmudatainstget *pmudatainstget;
	boardobjgrp_pmustatusinstget *pmustatusinstget;
	struct nvgpu_list_node node;
};

/*
* Macro test whether a specified index into the BOARDOBJGRP is valid.
*
*/
#define boardobjgrp_idxisvalid(_pboardobjgrp, _idx)                           \
	(((_idx) < (_pboardobjgrp)->objslots) &&                               \
	((_pboardobjgrp)->ppobjects[(_idx)] != NULL))

/*
* Macro test whether a specified BOARDOBJGRP is empty.
*/
#define BOARDOBJGRP_IS_EMPTY(_pboardobjgrp)                                    \
	((!((_pboardobjgrp)->bconstructed)) ||                                 \
	((_pboardobjgrp)->objmaxidx == CTRL_BOARDOBJ_IDX_INVALID))

#define boardobjgrp_objinsert(_pboardobjgrp, _pboardobj, _idx)                 \
	((_pboardobjgrp)->objinsert((_pboardobjgrp), (_pboardobj), (_idx)))

/*
* Helper macro to determine the "next" open/empty index after all allocated
* objects.  This is intended to be used to find the index at which objects can
* be inserted contiguously (i.e. w/o fear of colliding with existing objects).
*/
#define BOARDOBJGRP_NEXT_EMPTY_IDX(_pboardobjgrp)                              \
	((CTRL_BOARDOBJ_IDX_INVALID == (_pboardobjgrp)->objmaxidx) ? 0 :       \
	((((_pboardobjgrp)->objmaxidx + 1) >= (_pboardobjgrp)->objslots) ?     \
	(u8)CTRL_BOARDOBJ_IDX_INVALID : (u8)((_pboardobjgrp)->objmaxidx + 1)))

/*
* Helper macro to determine the number of @ref BOARDOBJ pointers
* that are required to be allocated in PMU @ref ppObjects.
*/
#define BOARDOBJGRP_PMU_SLOTS_GET(_pboardobjgrp)                            \
	((CTRL_BOARDOBJ_IDX_INVALID == (_pboardobjgrp)->objmaxidx) ? 0 :    \
	(u8)((_pboardobjgrp)->objmaxidx + 1))

#define BOARDOBJGRP_OBJ_GET_BY_IDX(_pboardobjgrp, _idx)                     \
	((_pboardobjgrp)->objgetbyidx((_pboardobjgrp), (_idx)))

/*
* macro to look-up next object while tolerating error if
* Board Object Group is not constructed.
*/

#define boardobjgrpobjgetnextsafe(_pgrp, _pindex, _pmask)                      \
	((_pgrp)->bconstructed ?                                               \
	(_pgrp)->objgetnext((_pgrp), (_pindex), (_pmask)) : NULL)

/*
* Used to traverse all Board Objects stored within @ref _pgrp in the increasing
* index order.
* If @ref _pmask is provided only objects specified by the mask are traversed.
*/
#define BOARDOBJGRP_ITERATOR(_pgrp, _ptype, _pobj, _index, _pmask)             \
	for (_index = CTRL_BOARDOBJ_IDX_INVALID,                             \
	_pobj  = (_ptype)boardobjgrpobjgetnextsafe((_pgrp), &_index, (_pmask));\
	_pobj != NULL;                                                         \
	_pobj  = (_ptype)boardobjgrpobjgetnextsafe((_pgrp), &_index, (_pmask)))
#define BOARDOBJGRP_FOR_EACH(_pgrp, _ptype, _pobj, _index)                     \
	BOARDOBJGRP_ITERATOR(_pgrp, _ptype, _pobj, _index, NULL)

#define BOARDOBJGRP_FOR_EACH_INDEX_IN_MASK(mask_width, index, mask)        \
{                                                           \
	u##mask_width lcl_msk = (u##mask_width)(mask);         \
	for (index = 0; lcl_msk != 0; index++, lcl_msk >>= 1) {     \
		if (((u##mask_width)((u64)1) & lcl_msk) == 0) {     \
			continue;                                       \
		}

#define BOARDOBJGRP_FOR_EACH_INDEX_IN_MASK_END                          \
	}                                                       \
}


/*!
* Invalid UNIT_ID.  Used to indicate that the implementing class has not set
* @ref BOARDOBJGRP::unitId and, thus, certain BOARDOBJGRP PMU interfaces are
* not supported.
*/
#define BOARDOBJGRP_UNIT_ID_INVALID                                   255

/*!
* Invalid UNIT_ID.  Used to indicate that the implementing class has not set
* @ref BOARDOBJGRP::grpType and, thus, certain BOARDOBJGRP PMU interfaces are
* not supported.
*/
#define BOARDOBJGRP_GRP_CLASS_ID_INVALID                              255

/*!
* Invalid UNIT_ID.  Used to indicate that the implementing class has not set
* @ref BOARDOBJGRP::grpSetCmdId and, thus, certain BOARDOBJGRP PMU interfaces
* are not supported.
*/
#define BOARDOBJGRP_GRP_CMD_ID_INVALID                                255
#define BOARDOBJGRP_GRP_RPC_FUNC_ID_INVALID                           255

/*!
* Helper macro to construct a BOARDOBJGRP's PMU SW state.
*
* @param[out] pboardobjgrp    BOARDOBJGRP pointer
* @param[in]  _eng
*     Implementing engine/unit which manages the BOARDOBJGRP.
* @param[in]  _class
*     Class ID of BOARDOBJGRP.
*/
#define BOARDOBJGRP_PMU_CONSTRUCT(pboardobjgrp, _ENG, _CLASS)	              \
do {                                                                          \
	(pboardobjgrp)->pmu.unitid  = PMU_UNIT_##_ENG;                        \
	(pboardobjgrp)->pmu.classid =                                         \
	NV_PMU_##_ENG##_BOARDOBJGRP_CLASS_ID_##_CLASS;                        \
} while (0)

#define BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT(g, pboardobjgrp, eng, ENG, \
	class, CLASS)                                                 \
	g->ops.pmu_ver.boardobj.boardobjgrp_pmucmd_construct_impl(    \
	g,                                              /* pgpu */    \
	pboardobjgrp,                                      /* pboardobjgrp */ \
	&((pboardobjgrp)->pmu.set),                        /* pcmd */         \
	NV_PMU_##ENG##_CMD_ID_BOARDOBJ_GRP_SET,               /* id */        \
	NV_PMU_##ENG##_MSG_ID_BOARDOBJ_GRP_SET,               /* msgid */     \
	(u32)sizeof(union nv_pmu_##eng##_##class##_boardobjgrp_set_header_aligned), \
	(u32)sizeof(union nv_pmu_##eng##_##class##_boardobj_set_union_aligned), \
	(u32)sizeof(struct nv_pmu_##eng##_##class##_boardobj_grp_set),	\
	(u32)offsetof(struct nv_pmu_super_surface, eng.class##_grp_set), \
	NV_PMU_RPC_ID_##ENG##_BOARD_OBJ_GRP_CMD)

#define BOARDOBJGRP_PMU_CMD_GRP_GET_STATUS_CONSTRUCT(g, pboardobjgrp, \
	eng, ENG, class, CLASS)                                       \
	g->ops.pmu_ver.boardobj.boardobjgrp_pmucmd_construct_impl(    \
	g,                                              /* pGpu */    \
	pboardobjgrp,                                      /* pBoardObjGrp */ \
	&((pboardobjgrp)->pmu.getstatus),                  /* pCmd */         \
	NV_PMU_##ENG##_CMD_ID_BOARDOBJ_GRP_GET_STATUS,        /* id */        \
	NV_PMU_##ENG##_MSG_ID_BOARDOBJ_GRP_GET_STATUS,        /* msgid */     \
	(u32)sizeof(union nv_pmu_##eng##_##class##_boardobjgrp_get_status_header_aligned), \
	(u32)sizeof(union nv_pmu_##eng##_##class##_boardobj_get_status_union_aligned), \
	(u32)sizeof(struct nv_pmu_##eng##_##class##_boardobj_grp_get_status),	\
	(u32)offsetof(struct nv_pmu_super_surface, eng.class##_grp_get_status), \
	NV_PMU_RPC_ID_##ENG##_BOARD_OBJ_GRP_CMD)

/* ------------------------ Function Prototypes ----------------------------- */
/* Constructor and destructor */
int boardobjgrp_construct_super(struct gk20a *g,
	struct boardobjgrp *pboardobjgrp);
boardobjgrp_destruct boardobjgrp_destruct_impl;
boardobjgrp_destruct boardobjgrp_destruct_super;

/* PMU_CMD interfaces */
boardobjgrp_pmucmd_construct     boardobjgrp_pmucmd_construct_impl;
boardobjgrp_pmucmd_destroy         boardobjgrp_pmucmd_destroy_impl;
boardobjgrp_pmucmd_pmuinithandle   boardobjgrp_pmucmd_pmuinithandle_impl;

boardobjgrp_pmucmd_construct     boardobjgrp_pmucmd_construct_impl_v1;

/* BOARDOBJGRP interfaces */
boardobjgrp_pmuinithandle    boardobjgrp_pmuinithandle_impl;
boardobjgrp_pmuhdrdatainit   boardobjgrp_pmuhdrdatainit_super;
boardobjgrp_pmudatainit      boardobjgrp_pmudatainit_super;

boardobjgrp_pmudatainit      boardobjgrp_pmudatainit_legacy;
boardobjgrp_pmuset           boardobjgrp_pmuset_impl;
boardobjgrp_pmugetstatus     boardobjgrp_pmugetstatus_impl;
boardobjgrp_pmuset           boardobjgrp_pmuset_impl_v1;
boardobjgrp_pmugetstatus     boardobjgrp_pmugetstatus_impl_v1;

void boardobjgrpe32hdrset(struct nv_pmu_boardobjgrp *hdr, u32 objmask);

#define HIGHESTBITIDX_32(n32)   \
{                               \
	u32 count = 0;        \
	while (n32 >>= 1) {       \
		count++;       \
	}                      \
	n32 = count;            \
}

#define LOWESTBIT(x)            ((x) &  (((x)-1) ^ (x)))

#define HIGHESTBIT(n32)     \
{                           \
	HIGHESTBITIDX_32(n32);  \
	n32 = NVBIT(n32);       \
}

#define ONEBITSET(x)            ((x) && (((x) & ((x)-1)) == 0))

#define LOWESTBITIDX_32(n32)  \
{                             \
	n32 = LOWESTBIT(n32); \
	IDX_32(n32);         \
}

#define NUMSETBITS_32(n32)                                         \
{                                                                  \
	n32 = n32 - ((n32 >> 1) & 0x55555555);                         \
	n32 = (n32 & 0x33333333) + ((n32 >> 2) & 0x33333333);          \
	n32 = (((n32 + (n32 >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;  \
}

#define IDX_32(n32)                     \
{                                       \
	u32 idx = 0;                      \
	if ((n32) & 0xFFFF0000)             \
		idx += 16;                  \
	if ((n32) & 0xFF00FF00)             \
		idx += 8;                   \
	if ((n32) & 0xF0F0F0F0)             \
		idx += 4;                   \
	if ((n32) & 0xCCCCCCCC)             \
		idx += 2;                   \
	if ((n32) & 0xAAAAAAAA)             \
		idx += 1;                   \
	(n32) = idx;                        \
}

static inline struct boardobjgrp *
boardobjgrp_from_node(struct nvgpu_list_node *node)
{
	return (struct boardobjgrp *)
		((uintptr_t)node - offsetof(struct boardobjgrp, node));
};

int is_boardobjgrp_pmucmd_id_valid_v0(struct gk20a *g,
	struct boardobjgrp *pboardobjgrp,
	struct boardobjgrp_pmu_cmd *cmd);
int is_boardobjgrp_pmucmd_id_valid_v1(struct gk20a *g,
	struct boardobjgrp *pboardobjgrp,
	struct boardobjgrp_pmu_cmd *cmd);
#endif