root/drivers/gpu/drm/msm/disp/msm_disp_snapshot.h
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
 */

#ifndef MSM_DISP_SNAPSHOT_H_
#define MSM_DISP_SNAPSHOT_H_

#include <drm/drm_atomic_helper.h>
#include <drm/drm_device.h>
#include "../../../drm_crtc_internal.h"
#include <drm/drm_print.h>
#include <drm/drm_atomic.h>
#include <linux/debugfs.h>
#include <linux/list.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/ktime.h>
#include <linux/uaccess.h>
#include <linux/dma-buf.h>
#include <linux/slab.h>
#include <linux/list_sort.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/kthread.h>
#include <linux/devcoredump.h>
#include "msm_kms.h"

#define MSM_DISP_SNAPSHOT_MAX_BLKS              10

/* debug option to print the registers in logs */
#define MSM_DISP_SNAPSHOT_DUMP_IN_CONSOLE 0

/* print debug ranges in groups of 4 u32s */
#define REG_DUMP_ALIGN          16

/**
 * struct msm_disp_state - structure to store current dpu state
 * @dev: device pointer
 * @drm_dev: drm device pointer
 * @blocks: list head for hardware state blocks
 * @atomic_state: atomic state duplicated at the time of the error
 * @time: timestamp at which the coredump was captured
 */
struct msm_disp_state {
        struct device *dev;
        struct drm_device *drm_dev;

        struct list_head blocks;

        struct drm_atomic_commit *atomic_state;

        struct timespec64 time;
};

/**
 * struct msm_disp_state_block - structure to store each hardware block state
 * @name: name of the block
 * @node: handle to the linked list head
 * @size: size of the register space of this hardware block
 * @state: array holding the register dump of this hardware block
 * @base_addr: starting address of this hardware block's register space
 */
struct msm_disp_state_block {
        char name[SZ_128];
        struct list_head node;
        unsigned int size;
        u32 *state;
        void __iomem *base_addr;
};

/**
 * msm_disp_snapshot_init - initialize display snapshot
 * @drm_dev:    drm device handle
 *
 * Returns:             0 or -ERROR
 */
int msm_disp_snapshot_init(struct drm_device *drm_dev);

/**
 * msm_disp_snapshot_destroy - destroy the display snapshot
 * @drm_dev:    drm device handle
 *
 * Returns:     none
 */
void msm_disp_snapshot_destroy(struct drm_device *drm_dev);

/**
 * msm_disp_snapshot_state_sync - synchronously snapshot display state
 * @kms:  the kms object
 *
 * Returns: state or error
 *
 * Context:
 * Must be called with &kms->dump_mutex held
 */
struct msm_disp_state *msm_disp_snapshot_state_sync(struct msm_kms *kms);

/**
 * msm_disp_snapshot_state - trigger to dump the display snapshot
 * @drm_dev:    handle to drm device
 *
 * Returns:     none
 */
void msm_disp_snapshot_state(struct drm_device *drm_dev);

/**
 * msm_disp_state_print - print out the current dpu state
 * @disp_state:     handle to drm device
 * @p:      handle to drm printer
 *
 * Returns:     none
 */
void msm_disp_state_print(struct msm_disp_state *disp_state, struct drm_printer *p);

/**
 * msm_disp_snapshot_capture_state - utility to capture atomic state and hw registers
 * @disp_state:     handle to msm_disp_state struct
 *
 * Returns:     none
 */
void msm_disp_snapshot_capture_state(struct msm_disp_state *disp_state);

/**
 * msm_disp_state_free - free the memory after the coredump has been read
 * @data:           handle to struct msm_disp_state
 *
 * Returns: none
 */
void msm_disp_state_free(void *data);

/**
 * msm_disp_snapshot_add_block - add a hardware block with its register dump
 * @disp_state:     handle to struct msm_disp_state
 * @len:            size of the register space of the hardware block
 * @base_addr:      starting address of the register space of the hardware block
 * @fmt:            format in which the block names need to be printed
 *
 * Returns: none
 */
__printf(4, 5)
void msm_disp_snapshot_add_block(struct msm_disp_state *disp_state, u32 len,
                void __iomem *base_addr, const char *fmt, ...);

#endif /* MSM_DISP_SNAPSHOT_H_ */