/*
 * QEMU UFS
 *
 * Copyright (c) 2023 Samsung Electronics Co., Ltd. All rights reserved.
 *
 * Written by Jeuk Kim <jeuk20.kim@samsung.com>
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#ifndef HW_UFS_UFS_H
#define HW_UFS_UFS_H

#include "hw/pci/pci_device.h"
#include "hw/scsi/scsi.h"
#include "block/ufs.h"

#define UFS_MAX_LUS 32
#define UFS_MAX_MCQ_QNUM 32
#define UFS_BLOCK_SIZE_SHIFT 12
#define UFS_BLOCK_SIZE (1 << UFS_BLOCK_SIZE_SHIFT)

typedef struct UfsBusClass {
    BusClass parent_class;
    bool (*parent_check_address)(BusState *bus, DeviceState *dev, Error **errp);
} UfsBusClass;

typedef struct UfsBus {
    BusState parent_bus;
} UfsBus;

#define TYPE_UFS_BUS "ufs-bus"
DECLARE_OBJ_CHECKERS(UfsBus, UfsBusClass, UFS_BUS, TYPE_UFS_BUS)

typedef enum UfsRequestState {
    UFS_REQUEST_IDLE = 0,
    UFS_REQUEST_READY = 1,
    UFS_REQUEST_RUNNING = 2,
    UFS_REQUEST_COMPLETE = 3,
    UFS_REQUEST_ERROR = 4,
} UfsRequestState;

typedef enum UfsReqResult {
    UFS_REQUEST_SUCCESS = 0,
    UFS_REQUEST_FAIL = 1,
    UFS_REQUEST_NO_COMPLETE = 2,
} UfsReqResult;

#define UFS_INVALID_SLOT (-1)
typedef struct UfsRequest {
    struct UfsHc *hc;
    UfsRequestState state;
    int slot; /* -1 when it's a MCQ request */

    UtpTransferReqDesc utrd;
    UtpUpiuReq req_upiu;
    UtpUpiuRsp rsp_upiu;

    /* for scsi command */
    QEMUSGList *sg;
    uint32_t data_len;

    /* for MCQ */
    struct UfsSq *sq;
    struct UfsCqEntry cqe;
    QTAILQ_ENTRY(UfsRequest) entry;
} UfsRequest;

static inline bool ufs_mcq_req(UfsRequest *req)
{
    return req->sq != NULL;
}

struct UfsLu;
typedef UfsReqResult (*UfsScsiOp)(struct UfsLu *, UfsRequest *);

typedef struct UfsLu {
    DeviceState qdev;
    uint8_t lun;
    UnitDescriptor unit_desc;
    SCSIBus bus;
    SCSIDevice *scsi_dev;
    BlockConf conf;
    UfsScsiOp scsi_op;
} UfsLu;

typedef struct UfsParams {
    char *serial;
    uint8_t nutrs; /* Number of UTP Transfer Request Slots */
    uint8_t nutmrs; /* Number of UTP Task Management Request Slots */
    bool mcq; /* Multiple Command Queue support */
    uint8_t mcq_qcfgptr; /* MCQ Queue Configuration Pointer in MCQCAP */
    uint8_t mcq_maxq; /* MCQ Maximum number of Queues */
} UfsParams;

/*
 * MCQ Properties
 */
typedef struct UfsSq {
    struct UfsHc *u;
    uint8_t sqid;
    struct UfsCq *cq;
    uint64_t addr;
    uint16_t size; /* A number of entries (qdepth) */

    QEMUBH *bh; /* Bottom half to process requests in async */
    UfsRequest *req;
    QTAILQ_HEAD(, UfsRequest) req_list; /* Free request list */
} UfsSq;

typedef struct UfsCq {
    struct UfsHc *u;
    uint8_t cqid;
    uint64_t addr;
    uint16_t size; /* A number of entries (qdepth) */

    QEMUBH *bh;
    QTAILQ_HEAD(, UfsRequest) req_list;
} UfsCq;

typedef struct UfsHc {
    PCIDevice parent_obj;
    UfsBus bus;
    MemoryRegion iomem;
    UfsReg reg;
    UfsMcqReg mcq_reg[UFS_MAX_MCQ_QNUM];
    UfsMcqOpReg mcq_op_reg[UFS_MAX_MCQ_QNUM];
    UfsParams params;
    uint32_t reg_size;
    UfsRequest *req_list;

    UfsLu *lus[UFS_MAX_LUS];
    UfsLu report_wlu;
    UfsLu dev_wlu;
    UfsLu boot_wlu;
    UfsLu rpmb_wlu;
    DeviceDescriptor device_desc;
    GeometryDescriptor geometry_desc;
    Attributes attributes;
    Flags flags;

    qemu_irq irq;
    QEMUBH *doorbell_bh;
    QEMUBH *complete_bh;

    /* MCQ properties */
    UfsSq *sq[UFS_MAX_MCQ_QNUM];
    UfsCq *cq[UFS_MAX_MCQ_QNUM];
} UfsHc;

static inline uint32_t ufs_mcq_sq_tail(UfsHc *u, uint32_t qid)
{
    return u->mcq_op_reg[qid].sq.tp;
}

static inline void ufs_mcq_update_sq_tail(UfsHc *u, uint32_t qid, uint32_t db)
{
    u->mcq_op_reg[qid].sq.tp = db;
}

static inline uint32_t ufs_mcq_sq_head(UfsHc *u, uint32_t qid)
{
    return u->mcq_op_reg[qid].sq.hp;
}

static inline void ufs_mcq_update_sq_head(UfsHc *u, uint32_t qid, uint32_t db)
{
    u->mcq_op_reg[qid].sq.hp = db;
}

static inline bool ufs_mcq_sq_empty(UfsHc *u, uint32_t qid)
{
    return ufs_mcq_sq_tail(u, qid) == ufs_mcq_sq_head(u, qid);
}

static inline uint32_t ufs_mcq_cq_tail(UfsHc *u, uint32_t qid)
{
    return u->mcq_op_reg[qid].cq.tp;
}

static inline void ufs_mcq_update_cq_tail(UfsHc *u, uint32_t qid, uint32_t db)
{
    u->mcq_op_reg[qid].cq.tp = db;
}

static inline uint32_t ufs_mcq_cq_head(UfsHc *u, uint32_t qid)
{
    return u->mcq_op_reg[qid].cq.hp;
}

static inline void ufs_mcq_update_cq_head(UfsHc *u, uint32_t qid, uint32_t db)
{
    u->mcq_op_reg[qid].cq.hp = db;
}

static inline bool ufs_mcq_cq_empty(UfsHc *u, uint32_t qid)
{
    return ufs_mcq_cq_tail(u, qid) == ufs_mcq_cq_head(u, qid);
}

#define TYPE_UFS "ufs"
#define UFS(obj) OBJECT_CHECK(UfsHc, (obj), TYPE_UFS)

#define TYPE_UFS_LU "ufs-lu"
#define UFSLU(obj) OBJECT_CHECK(UfsLu, (obj), TYPE_UFS_LU)

typedef enum UfsQueryFlagPerm {
    UFS_QUERY_FLAG_NONE = 0x0,
    UFS_QUERY_FLAG_READ = 0x1,
    UFS_QUERY_FLAG_SET = 0x2,
    UFS_QUERY_FLAG_CLEAR = 0x4,
    UFS_QUERY_FLAG_TOGGLE = 0x8,
} UfsQueryFlagPerm;

typedef enum UfsQueryAttrPerm {
    UFS_QUERY_ATTR_NONE = 0x0,
    UFS_QUERY_ATTR_READ = 0x1,
    UFS_QUERY_ATTR_WRITE = 0x2,
} UfsQueryAttrPerm;

static inline bool is_wlun(uint8_t lun)
{
    return (lun == UFS_UPIU_REPORT_LUNS_WLUN ||
            lun == UFS_UPIU_UFS_DEVICE_WLUN || lun == UFS_UPIU_BOOT_WLUN ||
            lun == UFS_UPIU_RPMB_WLUN);
}

void ufs_build_upiu_header(UfsRequest *req, uint8_t trans_type, uint8_t flags,
                           uint8_t response, uint8_t scsi_status,
                           uint16_t data_segment_length);
void ufs_complete_req(UfsRequest *req, UfsReqResult req_result);
void ufs_init_wlu(UfsLu *wlu, uint8_t wlun);
#endif /* HW_UFS_UFS_H */
