162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci#ifndef __842_H__ 462306a36Sopenharmony_ci#define __842_H__ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci/* The 842 compressed format is made up of multiple blocks, each of 762306a36Sopenharmony_ci * which have the format: 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * <template>[arg1][arg2][arg3][arg4] 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * where there are between 0 and 4 template args, depending on the specific 1262306a36Sopenharmony_ci * template operation. For normal operations, each arg is either a specific 1362306a36Sopenharmony_ci * number of data bytes to add to the output buffer, or an index pointing 1462306a36Sopenharmony_ci * to a previously-written number of data bytes to copy to the output buffer. 1562306a36Sopenharmony_ci * 1662306a36Sopenharmony_ci * The template code is a 5-bit value. This code indicates what to do with 1762306a36Sopenharmony_ci * the following data. Template codes from 0 to 0x19 should use the template 1862306a36Sopenharmony_ci * table, the static "decomp_ops" table used in decompress. For each template 1962306a36Sopenharmony_ci * (table row), there are between 1 and 4 actions; each action corresponds to 2062306a36Sopenharmony_ci * an arg following the template code bits. Each action is either a "data" 2162306a36Sopenharmony_ci * type action, or a "index" type action, and each action results in 2, 4, or 8 2262306a36Sopenharmony_ci * bytes being written to the output buffer. Each template (i.e. all actions 2362306a36Sopenharmony_ci * in the table row) will add up to 8 bytes being written to the output buffer. 2462306a36Sopenharmony_ci * Any row with less than 4 actions is padded with noop actions, indicated by 2562306a36Sopenharmony_ci * N0 (for which there is no corresponding arg in the compressed data buffer). 2662306a36Sopenharmony_ci * 2762306a36Sopenharmony_ci * "Data" actions, indicated in the table by D2, D4, and D8, mean that the 2862306a36Sopenharmony_ci * corresponding arg is 2, 4, or 8 bytes, respectively, in the compressed data 2962306a36Sopenharmony_ci * buffer should be copied directly to the output buffer. 3062306a36Sopenharmony_ci * 3162306a36Sopenharmony_ci * "Index" actions, indicated in the table by I2, I4, and I8, mean the 3262306a36Sopenharmony_ci * corresponding arg is an index parameter that points to, respectively, a 2, 3362306a36Sopenharmony_ci * 4, or 8 byte value already in the output buffer, that should be copied to 3462306a36Sopenharmony_ci * the end of the output buffer. Essentially, the index points to a position 3562306a36Sopenharmony_ci * in a ring buffer that contains the last N bytes of output buffer data. 3662306a36Sopenharmony_ci * The number of bits for each index's arg are: 8 bits for I2, 9 bits for I4, 3762306a36Sopenharmony_ci * and 8 bits for I8. Since each index points to a 2, 4, or 8 byte section, 3862306a36Sopenharmony_ci * this means that I2 can reference 512 bytes ((2^8 bits = 256) * 2 bytes), I4 3962306a36Sopenharmony_ci * can reference 2048 bytes ((2^9 = 512) * 4 bytes), and I8 can reference 2048 4062306a36Sopenharmony_ci * bytes ((2^8 = 256) * 8 bytes). Think of it as a kind-of ring buffer for 4162306a36Sopenharmony_ci * each of I2, I4, and I8 that are updated for each byte written to the output 4262306a36Sopenharmony_ci * buffer. In this implementation, the output buffer is directly used for each 4362306a36Sopenharmony_ci * index; there is no additional memory required. Note that the index is into 4462306a36Sopenharmony_ci * a ring buffer, not a sliding window; for example, if there have been 260 4562306a36Sopenharmony_ci * bytes written to the output buffer, an I2 index of 0 would index to byte 256 4662306a36Sopenharmony_ci * in the output buffer, while an I2 index of 16 would index to byte 16 in the 4762306a36Sopenharmony_ci * output buffer. 4862306a36Sopenharmony_ci * 4962306a36Sopenharmony_ci * There are also 3 special template codes; 0x1b for "repeat", 0x1c for 5062306a36Sopenharmony_ci * "zeros", and 0x1e for "end". The "repeat" operation is followed by a 6 bit 5162306a36Sopenharmony_ci * arg N indicating how many times to repeat. The last 8 bytes written to the 5262306a36Sopenharmony_ci * output buffer are written again to the output buffer, N + 1 times. The 5362306a36Sopenharmony_ci * "zeros" operation, which has no arg bits, writes 8 zeros to the output 5462306a36Sopenharmony_ci * buffer. The "end" operation, which also has no arg bits, signals the end 5562306a36Sopenharmony_ci * of the compressed data. There may be some number of padding (don't care, 5662306a36Sopenharmony_ci * but usually 0) bits after the "end" operation bits, to fill the buffer 5762306a36Sopenharmony_ci * length to a specific byte multiple (usually a multiple of 8, 16, or 32 5862306a36Sopenharmony_ci * bytes). 5962306a36Sopenharmony_ci * 6062306a36Sopenharmony_ci * This software implementation also uses one of the undefined template values, 6162306a36Sopenharmony_ci * 0x1d as a special "short data" template code, to represent less than 8 bytes 6262306a36Sopenharmony_ci * of uncompressed data. It is followed by a 3 bit arg N indicating how many 6362306a36Sopenharmony_ci * data bytes will follow, and then N bytes of data, which should be copied to 6462306a36Sopenharmony_ci * the output buffer. This allows the software 842 compressor to accept input 6562306a36Sopenharmony_ci * buffers that are not an exact multiple of 8 bytes long. However, those 6662306a36Sopenharmony_ci * compressed buffers containing this sw-only template will be rejected by 6762306a36Sopenharmony_ci * the 842 hardware decompressor, and must be decompressed with this software 6862306a36Sopenharmony_ci * library. The 842 software compression module includes a parameter to 6962306a36Sopenharmony_ci * disable using this sw-only "short data" template, and instead simply 7062306a36Sopenharmony_ci * reject any input buffer that is not a multiple of 8 bytes long. 7162306a36Sopenharmony_ci * 7262306a36Sopenharmony_ci * After all actions for each operation code are processed, another template 7362306a36Sopenharmony_ci * code is in the next 5 bits. The decompression ends once the "end" template 7462306a36Sopenharmony_ci * code is detected. 7562306a36Sopenharmony_ci */ 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci#include <linux/module.h> 7862306a36Sopenharmony_ci#include <linux/kernel.h> 7962306a36Sopenharmony_ci#include <linux/bitops.h> 8062306a36Sopenharmony_ci#include <linux/crc32.h> 8162306a36Sopenharmony_ci#include <asm/unaligned.h> 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci#include <linux/sw842.h> 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci/* special templates */ 8662306a36Sopenharmony_ci#define OP_REPEAT (0x1B) 8762306a36Sopenharmony_ci#define OP_ZEROS (0x1C) 8862306a36Sopenharmony_ci#define OP_END (0x1E) 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci/* sw only template - this is not in the hw design; it's used only by this 9162306a36Sopenharmony_ci * software compressor and decompressor, to allow input buffers that aren't 9262306a36Sopenharmony_ci * a multiple of 8. 9362306a36Sopenharmony_ci */ 9462306a36Sopenharmony_ci#define OP_SHORT_DATA (0x1D) 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci/* additional bits of each op param */ 9762306a36Sopenharmony_ci#define OP_BITS (5) 9862306a36Sopenharmony_ci#define REPEAT_BITS (6) 9962306a36Sopenharmony_ci#define SHORT_DATA_BITS (3) 10062306a36Sopenharmony_ci#define I2_BITS (8) 10162306a36Sopenharmony_ci#define I4_BITS (9) 10262306a36Sopenharmony_ci#define I8_BITS (8) 10362306a36Sopenharmony_ci#define CRC_BITS (32) 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci#define REPEAT_BITS_MAX (0x3f) 10662306a36Sopenharmony_ci#define SHORT_DATA_BITS_MAX (0x7) 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci/* Arbitrary values used to indicate action */ 10962306a36Sopenharmony_ci#define OP_ACTION (0x70) 11062306a36Sopenharmony_ci#define OP_ACTION_INDEX (0x10) 11162306a36Sopenharmony_ci#define OP_ACTION_DATA (0x20) 11262306a36Sopenharmony_ci#define OP_ACTION_NOOP (0x40) 11362306a36Sopenharmony_ci#define OP_AMOUNT (0x0f) 11462306a36Sopenharmony_ci#define OP_AMOUNT_0 (0x00) 11562306a36Sopenharmony_ci#define OP_AMOUNT_2 (0x02) 11662306a36Sopenharmony_ci#define OP_AMOUNT_4 (0x04) 11762306a36Sopenharmony_ci#define OP_AMOUNT_8 (0x08) 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci#define D2 (OP_ACTION_DATA | OP_AMOUNT_2) 12062306a36Sopenharmony_ci#define D4 (OP_ACTION_DATA | OP_AMOUNT_4) 12162306a36Sopenharmony_ci#define D8 (OP_ACTION_DATA | OP_AMOUNT_8) 12262306a36Sopenharmony_ci#define I2 (OP_ACTION_INDEX | OP_AMOUNT_2) 12362306a36Sopenharmony_ci#define I4 (OP_ACTION_INDEX | OP_AMOUNT_4) 12462306a36Sopenharmony_ci#define I8 (OP_ACTION_INDEX | OP_AMOUNT_8) 12562306a36Sopenharmony_ci#define N0 (OP_ACTION_NOOP | OP_AMOUNT_0) 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci/* the max of the regular templates - not including the special templates */ 12862306a36Sopenharmony_ci#define OPS_MAX (0x1a) 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci#endif 131