/* dedicate the last GPR_R15 to assign the register address to be poll */
 #define CMDQ_POLL_ADDR_GPR     (15)
 #define CMDQ_EOC_IRQ_EN                BIT(0)
+#define CMDQ_IMMEDIATE_VALUE   0
 #define CMDQ_REG_TYPE          1
 #define CMDQ_JUMP_RELATIVE     0
 #define CMDQ_JUMP_ABSOLUTE     1
        u8 op;
 };
 
+static inline u8 cmdq_operand_get_type(struct cmdq_operand *op)
+{
+       return op->reg ? CMDQ_REG_TYPE : CMDQ_IMMEDIATE_VALUE;
+}
+
+static inline u16 cmdq_operand_get_idx_value(struct cmdq_operand *op)
+{
+       return op->reg ? op->idx : op->value;
+}
+
 int cmdq_dev_get_client_reg(struct device *dev,
                            struct cmdq_client_reg *client_reg, int idx)
 {
 }
 EXPORT_SYMBOL(cmdq_pkt_poll_addr);
 
+int cmdq_pkt_logic_command(struct cmdq_pkt *pkt, u16 result_reg_idx,
+                          struct cmdq_operand *left_operand,
+                          enum cmdq_logic_op s_op,
+                          struct cmdq_operand *right_operand)
+{
+       struct cmdq_instruction inst = { {0} };
+
+       if (!left_operand || !right_operand || s_op >= CMDQ_LOGIC_MAX)
+               return -EINVAL;
+
+       inst.op = CMDQ_CODE_LOGIC;
+       inst.dst_t = CMDQ_REG_TYPE;
+       inst.src_t = cmdq_operand_get_type(left_operand);
+       inst.arg_c_t = cmdq_operand_get_type(right_operand);
+       inst.sop = s_op;
+       inst.reg_dst = result_reg_idx;
+       inst.src_reg = cmdq_operand_get_idx_value(left_operand);
+       inst.arg_c = cmdq_operand_get_idx_value(right_operand);
+
+       return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_logic_command);
+
 int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value)
 {
        struct cmdq_instruction inst = {};
 
 
 struct cmdq_pkt;
 
+enum cmdq_logic_op {
+       CMDQ_LOGIC_ASSIGN = 0,
+       CMDQ_LOGIC_ADD = 1,
+       CMDQ_LOGIC_SUBTRACT = 2,
+       CMDQ_LOGIC_MULTIPLY = 3,
+       CMDQ_LOGIC_XOR = 8,
+       CMDQ_LOGIC_NOT = 9,
+       CMDQ_LOGIC_OR = 10,
+       CMDQ_LOGIC_AND = 11,
+       CMDQ_LOGIC_LEFT_SHIFT = 12,
+       CMDQ_LOGIC_RIGHT_SHIFT = 13,
+       CMDQ_LOGIC_MAX,
+};
+
+struct cmdq_operand {
+       /* register type */
+       bool reg;
+       union {
+               /* index */
+               u16 idx;
+               /* value */
+               u16 value;
+       };
+};
+
 struct cmdq_client_reg {
        u8 subsys;
        u16 offset;
 int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
                       u16 offset, u32 value, u32 mask);
 
+/**
+ * cmdq_pkt_logic_command() - Append logic command to the CMDQ packet, ask GCE to
+ *                       execute an instruction that store the result of logic operation
+ *                       with left and right operand into result_reg_idx.
+ * @pkt:               the CMDQ packet
+ * @result_reg_idx:    SPR index that store operation result of left_operand and right_operand
+ * @left_operand:      left operand
+ * @s_op:              the logic operator enum
+ * @right_operand:     right operand
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_logic_command(struct cmdq_pkt *pkt, u16 result_reg_idx,
+                          struct cmdq_operand *left_operand,
+                          enum cmdq_logic_op s_op,
+                          struct cmdq_operand *right_operand);
+
 /**
  * cmdq_pkt_assign() - Append logic assign command to the CMDQ packet, ask GCE
  *                    to execute an instruction that set a constant value into