Re: [PATCH 2/2] media: hi846: Add 6MP and 8MP modes support
From: Pengyu Luo
Date: Thu Apr 30 2026 - 12:19:15 EST
On Wed, Apr 29, 2026 at 5:01 PM Sakari Ailus
<sakari.ailus@xxxxxxxxxxxxxxx> wrote:
>
> Hi Pengyu,
>
> On Wed, Apr 29, 2026 at 03:03:51PM +0800, Pengyu Luo wrote:
> > Hi846 is an 8MP sensor, but the upstream driver has only supported 2MP
> > mode for years. This patch adds 6MP and 8MP modes to maximize sensor
> > utilization.
> >
> > Note that these modes require 4-lane MIPI CSI-2, as the downstream
> > driver only exposes 2MP, 6MP, and 8MP configurations in 4-lane
> > operation on the target device. The register sequences are extracted
> > from the downstream Windows driver.
> >
> > Signed-off-by: Pengyu Luo <mitltlatltl@xxxxxxxxx>
> > ---
> > drivers/media/i2c/hi846.c | 154 +++++++++++++++++++++++++++++++++++++-
> > 1 file changed, 153 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/media/i2c/hi846.c b/drivers/media/i2c/hi846.c
> > index 09c109f3fba9..b8ae7344f1a0 100644
> > --- a/drivers/media/i2c/hi846.c
> > +++ b/drivers/media/i2c/hi846.c
> > @@ -1027,6 +1027,106 @@ static const struct hi846_reg mode_1632x1224_mipi_4lane[] = {
> > {HI846_REG_TG_ENABLE, 0x0100},
> > };
> >
> > +static const struct hi846_reg mode_3264x1836_config[] = {
> > + {HI846_REG_MODE_SELECT, 0x0000},
> > + {HI846_REG_Y_ODD_INC_FOBP, 0x1111},
> > + {HI846_REG_Y_ODD_INC_VACT, 0x1111},
> > + {HI846_REG_Y_ADDR_START_VACT_H, 0x0172},
> > + {HI846_REG_Y_ADDR_END_VACT_H, 0x089d},
> > + {HI846_REG_UNKNOWN_005C, 0x2101},
> > + {HI846_REG_FLL, 0x09de},
> > + {HI846_REG_LLP, 0x0ed8},
> > + {HI846_REG_BINNING_MODE, 0x0022},
> > + {HI846_REG_HBIN_MODE, 0x0000},
> > + {HI846_REG_UNKNOWN_0A24, 0x0000},
> > + {HI846_REG_X_START_H, 0x0000},
> > + {HI846_REG_X_OUTPUT_SIZE_H, 0x0cc0},
> > + {HI846_REG_Y_OUTPUT_SIZE_H, 0x072c},
> > + {HI846_REG_EXPOSURE, 0x09d8},
> > +
> > + /* For OTP */
> > + {HI846_REG_UNKNOWN_021C, 0x0001},
> > + {HI846_REG_UNKNOWN_021E, 0x0235},
> > +
> > + {HI846_REG_ISP_EN_H, 0x014a},
> > + {HI846_REG_UNKNOWN_0418, 0x023e},
> > + {HI846_REG_UNKNOWN_0B02, 0xe04d},
> > + {HI846_REG_UNKNOWN_0B10, 0x6821},
> > + {HI846_REG_UNKNOWN_0B12, 0x0120},
> > + {HI846_REG_UNKNOWN_0B14, 0x0001},
> > + {HI846_REG_UNKNOWN_2008, 0x38fd},
> > + {HI846_REG_UNKNOWN_326E, 0x0000},
> > +};
> > +
> > +static const struct hi846_reg mode_3264x1836_mipi_4lane[] = {
> > + {HI846_REG_UNKNOWN_0900, 0x0300},
> > + {HI846_REG_MIPI_TX_OP_MODE, 0xc319},
> > + {HI846_REG_UNKNOWN_0914, 0xc109},
> > + {HI846_REG_TCLK_PREPARE, 0x061a},
> > + {HI846_REG_UNKNOWN_0918, 0x0407},
> > + {HI846_REG_THS_ZERO, 0x0a0b},
> > + {HI846_REG_TCLK_POST, 0x0e08},
> > + {HI846_REG_UNKNOWN_091E, 0x0a00},
> > + {HI846_REG_UNKNOWN_090C, 0x0427},
> > + {HI846_REG_UNKNOWN_090E, 0x0059},
> > + {HI846_REG_UNKNOWN_0954, 0x0089},
> > + {HI846_REG_UNKNOWN_0956, 0x0000},
> > + {HI846_REG_UNKNOWN_0958, 0xca80},
> > + {HI846_REG_UNKNOWN_095A, 0x9240},
> > + {HI846_REG_PLL_CFG_MIPI2_H, 0x4124},
> > + {HI846_REG_TG_ENABLE, 0x0100},
> > +};
> > +
> > +static const struct hi846_reg mode_3264x2448_config[] = {
> > + {HI846_REG_MODE_SELECT, 0x0000},
> > + {HI846_REG_Y_ODD_INC_FOBP, 0x1111},
> > + {HI846_REG_Y_ODD_INC_VACT, 0x1111},
> > + {HI846_REG_Y_ADDR_START_VACT_H, 0x0040},
> > + {HI846_REG_Y_ADDR_END_VACT_H, 0x09cf},
> > + {HI846_REG_UNKNOWN_005C, 0x2101},
> > + {HI846_REG_FLL, 0x09de},
> > + {HI846_REG_LLP, 0x0ed8},
> > + {HI846_REG_BINNING_MODE, 0x0022},
> > + {HI846_REG_HBIN_MODE, 0x0000},
> > + {HI846_REG_UNKNOWN_0A24, 0x0000},
> > + {HI846_REG_X_START_H, 0x0000},
> > + {HI846_REG_X_OUTPUT_SIZE_H, 0x0cc0},
> > + {HI846_REG_Y_OUTPUT_SIZE_H, 0x0990},
> > + {HI846_REG_EXPOSURE, 0x09d8},
> > +
> > + /* For OTP */
> > + {HI846_REG_UNKNOWN_021C, 0x0001},
> > + {HI846_REG_UNKNOWN_021E, 0x0235},
> > +
> > + {HI846_REG_ISP_EN_H, 0x014a},
> > + {HI846_REG_UNKNOWN_0418, 0x0000},
> > + {HI846_REG_UNKNOWN_0B02, 0xe04d},
> > + {HI846_REG_UNKNOWN_0B10, 0x6821},
> > + {HI846_REG_UNKNOWN_0B12, 0x0120},
> > + {HI846_REG_UNKNOWN_0B14, 0x0001},
> > + {HI846_REG_UNKNOWN_2008, 0x38fd},
> > + {HI846_REG_UNKNOWN_326E, 0x0000},
> > +};
> > +
> > +static const struct hi846_reg mode_3264x2448_mipi_4lane[] = {
> > + {HI846_REG_UNKNOWN_0900, 0x0300},
> > + {HI846_REG_MIPI_TX_OP_MODE, 0xc319},
> > + {HI846_REG_UNKNOWN_0914, 0xc109},
> > + {HI846_REG_TCLK_PREPARE, 0x061a},
> > + {HI846_REG_UNKNOWN_0918, 0x0407},
> > + {HI846_REG_THS_ZERO, 0x0a0b},
> > + {HI846_REG_TCLK_POST, 0x0e08},
> > + {HI846_REG_UNKNOWN_091E, 0x0a00},
> > + {HI846_REG_UNKNOWN_090C, 0x0427},
> > + {HI846_REG_UNKNOWN_090E, 0x0059},
> > + {HI846_REG_UNKNOWN_0954, 0x0089},
> > + {HI846_REG_UNKNOWN_0956, 0x0000},
> > + {HI846_REG_UNKNOWN_0958, 0xca80},
> > + {HI846_REG_UNKNOWN_095A, 0x9240},
> > + {HI846_REG_PLL_CFG_MIPI2_H, 0x4124},
> > + {HI846_REG_TG_ENABLE, 0x0100},
> > +};
> > +
> > static const char * const hi846_test_pattern_menu[] = {
> > "Disabled",
> > "Solid Colour",
> > @@ -1042,9 +1142,11 @@ static const char * const hi846_test_pattern_menu[] = {
> >
> > #define FREQ_INDEX_640 0
> > #define FREQ_INDEX_1280 1
> > +#define FREQ_INDEX_3264 2
> > static const s64 hi846_link_freqs[] = {
> > [FREQ_INDEX_640] = 80000000,
> > [FREQ_INDEX_1280] = 200000000,
> > + [FREQ_INDEX_3264] = 288000000,
>
> Looking at the driver, the PLL configuration is present in the lane number
> specific register list so the link frequency is in fact the same for all
> modes. This problem isn't introduced by this patch but I think this needs
> to be fixed before adding further modes to the driver.
>
TBH, I didn't investigate the calculations. I just searched the
datasheet for it. They are exactly wrong. Thans for pointing out this.
I can fix it, but the question is this driver was writing against
25Mhz mclk, but the typical value from datasheet is 24Mhz, and one
device is using 25Mhz as the clock rate, my device is using 24Mhz,
25Mhz is unsupported on my platform. It seems that making the list not
be runtime is not allowed as nobody did like this.
Best wishes,
Pengyu
> The pixel rate is likely incorrect as well.
>
> > };
> >
> > static const struct hi846_reg_list hi846_init_regs_list_2lane = {
> > @@ -1134,7 +1236,57 @@ static const struct hi846_mode supported_modes[] = {
> > .width = 1632 * 2,
> > .height = 1224 * 2,
> > },
> > - }
> > + },
> > + {
> > + .width = 3264,
> > + .height = 1836,
> > + .link_freq_index = FREQ_INDEX_3264,
> > + .fps = 30,
> > + .frame_len = 2526,
> > + .llp = HI846_LINE_LENGTH,
> > + .reg_list_config = {
> > + .num_of_regs = ARRAY_SIZE(mode_3264x1836_config),
> > + .regs = mode_3264x1836_config,
> > + },
> > + .reg_list_2lane = {
> > + .num_of_regs = 0,
> > + },
> > + .reg_list_4lane = {
> > + .num_of_regs = ARRAY_SIZE(mode_3264x1836_mipi_4lane),
> > + .regs = mode_3264x1836_mipi_4lane,
> > + },
> > + .crop = {
> > + .left = 0x46,
> > + .top = 0x172,
> > + .width = 3264,
> > + .height = 1836,
> > + },
> > + },
> > + {
> > + .width = 3264,
> > + .height = 2448,
> > + .link_freq_index = FREQ_INDEX_3264,
> > + .fps = 30,
> > + .frame_len = 2526,
> > + .llp = HI846_LINE_LENGTH,
> > + .reg_list_config = {
> > + .num_of_regs = ARRAY_SIZE(mode_3264x2448_config),
> > + .regs = mode_3264x2448_config,
> > + },
> > + .reg_list_2lane = {
> > + .num_of_regs = 0,
> > + },
> > + .reg_list_4lane = {
> > + .num_of_regs = ARRAY_SIZE(mode_3264x2448_mipi_4lane),
> > + .regs = mode_3264x2448_mipi_4lane,
> > + },
> > + .crop = {
> > + .left = 0x46,
> > + .top = 0x40,
> > + .width = 3264,
> > + .height = 2448,
> > + },
> > + },
> > };
> >
> > struct hi846_datafmt {
>
> --
> Regards,
>
> Sakari Ailus