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