Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions boards/nxp/rd_rw612_bga/dts/goworld_16880_lcm.overlay
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
&lcdic {
status = "okay";
nxp,swap-bytes;
/* Raise the timer0 ratio to enable longer reset delay */
nxp,timer0-ratio = <15>;
Copy link
Member

@dleach02 dleach02 Nov 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM but what dictates using a value of 15? Is that just because what it was before in the hardcoding?

Copy link
Contributor Author

@danieldegrasse danieldegrasse Nov 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes- also this display driver uses a long reset pulse (100 ms) which requires us to increase the timer0 base value. The reset pulse is set in units of the "Timer 0 base", the period of which is calculated as 2^(timer0-ratio)/lcdic_freq. So raising this value lets us generate longer reset pulses.

/*
* Settings to connect this display:
* Populate the following resistors:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
&lcdic {
/* Byte swapping not supported for this display */
/delete-property/ nxp,swap-bytes;
/* Set timer0 ratio to enable longer resets */
nxp,timer0-ratio = <15>;

/*
* Settings to connect this display:
Expand Down
2 changes: 2 additions & 0 deletions boards/shields/lcd_par_s035/boards/rd_rw612_bga.overlay
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,6 @@
/* Set pulse width for write active and write inactive to min value */
nxp,write-active-cycles = <1>;
nxp,write-inactive-cycles = <1>;
/* Raise the timer0 ratio to enable longer reset delay */
nxp,timer0-ratio = <15>;
};
26 changes: 16 additions & 10 deletions drivers/mipi_dbi/mipi_dbi_nxp_lcdic.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
#define LCDIC_MAX_XFER 0x40000
/* Max reset width (in terms of Timer0_Period, see RST_CTRL register) */
#define LCDIC_MAX_RST_WIDTH 0x3F
/* Max reset pulse count */
#define LCDIC_MAX_RST_PULSE_COUNT 0x7

/* Descriptor for LCDIC command */
union lcdic_trx_cmd {
Expand Down Expand Up @@ -74,6 +76,8 @@
bool swap_bytes;
uint8_t write_active_min;
uint8_t write_inactive_min;
uint8_t timer0_ratio;
uint8_t timer1_ratio;
};

#ifdef CONFIG_MIPI_DBI_NXP_LCDIC_DMA
Expand Down Expand Up @@ -125,12 +129,6 @@
#define LCDIC_TX_FIFO_THRESH 0x3
#endif

/* Timer0 and Timer1 bases. We choose a longer timer0 base to enable
* long reset periods
*/
#define LCDIC_TIMER0_RATIO 0xF
#define LCDIC_TIMER1_RATIO 0x9

/* After LCDIC is enabled or disabled, there should be a wait longer than
* 5x the module clock before other registers are read
*/
Expand Down Expand Up @@ -584,7 +582,7 @@
LCDIC_Type *base = config->base;
uint32_t lcdic_freq;
uint32_t delay_ms = k_ticks_to_ms_ceil32(delay.ticks);
uint8_t rst_width, pulse_cnt;
uint32_t rst_width, pulse_cnt;

/* Calculate delay based off timer0 ratio. Formula given
* by RM is as follows:
Expand All @@ -595,13 +593,19 @@
&lcdic_freq)) {
return -EIO;
}
rst_width = (delay_ms * (lcdic_freq)) / ((1 << LCDIC_TIMER0_RATIO) * MSEC_PER_SEC);
rst_width = (delay_ms * (lcdic_freq)) / ((1 << config->timer0_ratio) * MSEC_PER_SEC);
/* If rst_width is larger than max value supported by hardware,
* increase the pulse count (rounding up)
*/
pulse_cnt = ((rst_width + (LCDIC_MAX_RST_WIDTH - 1)) / LCDIC_MAX_RST_WIDTH);
rst_width = MIN(LCDIC_MAX_RST_WIDTH, rst_width);

if ((pulse_cnt - 1) > LCDIC_MAX_RST_PULSE_COUNT) {
/* Still issue reset pulse, but warn user */
LOG_WRN("Reset pulse is too long for configured timer0 ratio");
pulse_cnt = LCDIC_MAX_RST_PULSE_COUNT + 1;
}

/* Start the reset signal */
base->RST_CTRL = LCDIC_RST_CTRL_RST_WIDTH(rst_width - 1) |
LCDIC_RST_CTRL_RST_SEQ_NUM(pulse_cnt - 1) |
Expand Down Expand Up @@ -664,9 +668,9 @@
LCDIC_TO_CTRL_CMD_SHORT_TO_MASK);

/* Ensure LCDIC timer ratios are at reset values */
base->TIMER_CTRL = LCDIC_TIMER_CTRL_TIMER_RATIO1(LCDIC_TIMER1_RATIO) |
LCDIC_TIMER_CTRL_TIMER_RATIO0(LCDIC_TIMER0_RATIO);
base->TIMER_CTRL = LCDIC_TIMER_CTRL_TIMER_RATIO1(config->timer1_ratio) |
LCDIC_TIMER_CTRL_TIMER_RATIO0(config->timer0_ratio);

Check notice on line 673 in drivers/mipi_dbi/mipi_dbi_nxp_lcdic.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/mipi_dbi/mipi_dbi_nxp_lcdic.c:673 - LCDIC_TIMER_CTRL_TIMER_RATIO0(config->timer0_ratio); + LCDIC_TIMER_CTRL_TIMER_RATIO0(config->timer0_ratio);
#ifdef CONFIG_MIPI_DBI_NXP_LCDIC_DMA
/* Attach the LCDIC DMA request signal to the DMA channel we will
* use with hardware triggering.
Expand Down Expand Up @@ -807,6 +811,8 @@
DT_INST_PROP(n, nxp_write_active_cycles), \
.write_inactive_min = \
DT_INST_PROP(n, nxp_write_inactive_cycles), \
.timer0_ratio = DT_INST_PROP(n, nxp_timer0_ratio), \
.timer1_ratio = DT_INST_PROP(n, nxp_timer1_ratio), \
}; \
static struct mipi_dbi_lcdic_data mipi_dbi_lcdic_data_##n = { \
LCDIC_DMA_CHANNELS(n) \
Expand All @@ -817,5 +823,5 @@
POST_KERNEL, \
CONFIG_MIPI_DBI_INIT_PRIORITY, \
&mipi_dbi_lcdic_driver_api);

Check notice on line 826 in drivers/mipi_dbi/mipi_dbi_nxp_lcdic.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/mipi_dbi/mipi_dbi_nxp_lcdic.c:826 - -#define MIPI_DBI_LCDIC_INIT(n) \ - static void mipi_dbi_lcdic_config_func_##n( \ - const struct device *dev) \ - { \ - IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \ - mipi_dbi_lcdic_isr, \ - DEVICE_DT_INST_GET(n), 0); \ - \ - irq_enable(DT_INST_IRQN(n)); \ - } \ - \ - PINCTRL_DT_INST_DEFINE(n); \ - static const struct mipi_dbi_lcdic_config \ - mipi_dbi_lcdic_config_##n = { \ - .base = (LCDIC_Type *)DT_INST_REG_ADDR(n), \ - .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ - .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ - .clock_subsys = (clock_control_subsys_t) \ - DT_INST_CLOCKS_CELL(n, name), \ - .irq_config_func = mipi_dbi_lcdic_config_func_##n, \ - .swap_bytes = DT_INST_PROP(n, nxp_swap_bytes), \ - .write_active_min = \ - DT_INST_PROP(n, nxp_write_active_cycles), \ - .write_inactive_min = \ - DT_INST_PROP(n, nxp_write_inactive_cycles), \ - .timer0_ratio = DT_INST_PROP(n, nxp_timer0_ratio), \ - .timer1_ratio = DT_INST_PROP(n, nxp_timer1_ratio), \ - }; \ - static struct mipi_dbi_lcdic_data mipi_dbi_lcdic_data_##n = { \ - LCDIC_DMA_CHANNELS(n) \ - }; \ - DEVICE_DT_INST_DEFINE(n, mipi_dbi_lcdic_init, NULL, \ - &mipi_dbi_lcdic_data_##n, \ - &mipi_dbi_lcdic_config_##n, \ - POST_KERNEL, \ - CONFIG_MIPI_DBI_INIT_PRIORITY, \ - &mipi_dbi_lcdic_driver_api); +#define MIPI_DBI_LCDIC_INIT(n) \ + static void mipi_dbi_lcdic_config_func_##n(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), mipi_dbi_lcdic_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + \ + irq_enable(DT_INST_IRQN(n)); \ + } \ + \ + PINCTRL_DT_INST_DEFINE(n); \ + static const struct mipi_dbi_lcdic_config mipi_dbi_lcdic_config_##n = { \ + .base = (LCDIC_Type *)DT_INST_REG_ADDR(n), \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ + .clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, name), \ + .irq_config_func = mipi_dbi_lcdic_config_func_##n, \ + .swap_bytes = DT_INST_PROP(n, nxp_swap_bytes), \ + .write_active_min = DT_INST_PROP(n, nxp_write_active_cycles), \ + .write_inactive_min = DT_INST_PROP(n, nxp_write_inactive_cycles), \ + .timer0_ratio = DT_INST_PROP(n, nxp_timer0_ratio), \ + .timer1_ratio = DT_INST_PROP(n, nxp_timer1_ratio), \ + }; \ + static struct mipi_dbi_lcdic_data mipi_dbi_lcdic_data_##n = {LCDIC_DMA_CHANNELS(n)}; \ + DEVICE_DT_INST_DEFINE(n, mipi_dbi_lcdic_init, NULL, &mipi_dbi_lcdic_data_##n, \ + &mipi_dbi_lcdic_config_##n, POST_KERNEL, \ + CONFIG_MIPI_DBI_INIT_PRIORITY, &mipi_dbi_lcdic_driver_api);
DT_INST_FOREACH_STATUS_OKAY(MIPI_DBI_LCDIC_INIT)
18 changes: 18 additions & 0 deletions dts/bindings/mipi-dbi/nxp,lcdic.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,21 @@ properties:
Set minimum count of write active cycles, as a multiple of the module
clock frequency. This controls the length of the active period of the
WRX signal. Default is IP reset value. Only valid in 8080 mode.

nxp,timer0-ratio:
type: int
default: 8
description: |
Ratio for timer0, used for setting timer0 period (which is used for reset
and TX/RX short command timeout). Formula is:
timer0_period = (2 ^ timer0_ratio) / lcdic_freq
Default is IP reset value

nxp,timer1-ratio:
type: int
default: 9
description: |
Ratio for timer1, used for setting timer1 period (which is used for TE
wait time, timeout, and long command timeout). Formula is:
timer1_period = (2 ^ timer1_ratio) * timer0_period
Default is IP reset value
Loading