Re: [PATCH v2 24/36] soc: fsl: cpm1: qmc: Introduce qmc_data structure

Christophe Leroy
2024-08-23T08:11:19Z

Le 08/08/2024 à 09:11, Herve Codina a écrit :
> Current code handles CPM1 version of QMC. Some hardcoded values are used
> several times to initialize the QMC state machine. In the QUICC Engine
> (QE) version of QMC, these values are different.
>
> In order to prepare the support for the QE version of QMC and avoid the
> copy of the hardcoded values, introduce the qmc_data structure to define
> these version specific values.
>
> Signed-off-by: Herve Codina <herve.codina@bootlin.com>

Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>

> ---
> drivers/soc/fsl/qe/qmc.c | 69 ++++++++++++++++++++++++++--------------
> 1 file changed, 46 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
> index 3736a8e4575e..85fc86f91806 100644
> --- a/drivers/soc/fsl/qe/qmc.c
> +++ b/drivers/soc/fsl/qe/qmc.c
> @@ -215,8 +215,17 @@ struct qmc_chan {
> bool is_rx_stopped;
> };
>
> +struct qmc_data {
> + u32 tstate; /* Initial TSTATE value */
> + u32 rstate; /* Initial RSTATE value */
> + u32 zistate; /* Initial ZISTATE value */
> + u32 zdstate_hdlc; /* Initial ZDSTATE value (HDLC mode) */
> + u32 zdstate_transp; /* Initial ZDSTATE value (Transparent mode) */
> +};
> +
> struct qmc {
> struct device *dev;
> + const struct qmc_data *data;
> struct tsa_serial *tsa_serial;
> void __iomem *scc_regs;
> void __iomem *scc_pram;
> @@ -543,11 +552,11 @@ int qmc_chan_read_submit(struct qmc_chan *chan, dma_addr_t addr, size_t length,
> /* Restart receiver if needed */
> if (chan->is_rx_halted && !chan->is_rx_stopped) {
> /* Restart receiver */
> - if (chan->mode == QMC_TRANSPARENT)
> - qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, 0x18000080);
> - else
> - qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, 0x00000080);
> - qmc_write32(chan->s_param + QMC_SPE_RSTATE, 0x31000000);
> + qmc_write32(chan->s_param + QMC_SPE_ZDSTATE,
> + chan->mode == QMC_TRANSPARENT ?
> + chan->qmc->data->zdstate_transp :
> + chan->qmc->data->zdstate_hdlc);
> + qmc_write32(chan->s_param + QMC_SPE_RSTATE, chan->qmc->data->rstate);
> chan->is_rx_halted = false;
> }
> chan->rx_pending++;
> @@ -971,11 +980,11 @@ static int qmc_chan_start_rx(struct qmc_chan *chan)
> }
>
> /* Restart the receiver */
> - if (chan->mode == QMC_TRANSPARENT)
> - qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, 0x18000080);
> - else
> - qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, 0x00000080);
> - qmc_write32(chan->s_param + QMC_SPE_RSTATE, 0x31000000);
> + qmc_write32(chan->s_param + QMC_SPE_ZDSTATE,
> + chan->mode == QMC_TRANSPARENT ?
> + chan->qmc->data->zdstate_transp :
> + chan->qmc->data->zdstate_hdlc);
> + qmc_write32(chan->s_param + QMC_SPE_RSTATE, chan->qmc->data->rstate);
> chan->is_rx_halted = false;
>
> chan->is_rx_stopped = false;
> @@ -1121,8 +1130,8 @@ static void qmc_chan_reset_tx(struct qmc_chan *chan)
> qmc_read16(chan->s_param + QMC_SPE_TBASE));
>
> /* Reset TSTATE and ZISTATE to their initial value */
> - qmc_write32(chan->s_param + QMC_SPE_TSTATE, 0x30000000);
> - qmc_write32(chan->s_param + QMC_SPE_ZISTATE, 0x00000100);
> + qmc_write32(chan->s_param + QMC_SPE_TSTATE, chan->qmc->data->tstate);
> + qmc_write32(chan->s_param + QMC_SPE_ZISTATE, chan->qmc->data->zistate);
>
> spin_unlock_irqrestore(&chan->tx_lock, flags);
> }
> @@ -1393,11 +1402,11 @@ static int qmc_setup_chan(struct qmc *qmc, struct qmc_chan *chan)
> val = ((chan->id * (QMC_NB_TXBDS + QMC_NB_RXBDS)) + QMC_NB_TXBDS) * sizeof(cbd_t);
> qmc_write16(chan->s_param + QMC_SPE_RBASE, val);
> qmc_write16(chan->s_param + QMC_SPE_RBPTR, val);
> - qmc_write32(chan->s_param + QMC_SPE_TSTATE, 0x30000000);
> - qmc_write32(chan->s_param + QMC_SPE_RSTATE, 0x31000000);
> - qmc_write32(chan->s_param + QMC_SPE_ZISTATE, 0x00000100);
> + qmc_write32(chan->s_param + QMC_SPE_TSTATE, chan->qmc->data->tstate);
> + qmc_write32(chan->s_param + QMC_SPE_RSTATE, chan->qmc->data->rstate);
> + qmc_write32(chan->s_param + QMC_SPE_ZISTATE, chan->qmc->data->zistate);
> if (chan->mode == QMC_TRANSPARENT) {
> - qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, 0x18000080);
> + qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, chan->qmc->data->zdstate_transp);
> qmc_write16(chan->s_param + QMC_SPE_TMRBLR, 60);
> val = QMC_SPE_CHAMR_MODE_TRANSP;
> if (chan->is_reverse_data)
> @@ -1407,7 +1416,7 @@ static int qmc_setup_chan(struct qmc *qmc, struct qmc_chan *chan)
> if (ret)
> return ret;
> } else {
> - qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, 0x00000080);
> + qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, chan->qmc->data->zdstate_hdlc);
> qmc_write16(chan->s_param + QMC_SPE_MFLR, 60);
> qmc_write16(chan->s_param + QMC_SPE_CHAMR,
> QMC_SPE_CHAMR_MODE_HDLC | QMC_SPE_CHAMR_HDLC_IDLM);
> @@ -1535,11 +1544,12 @@ static void qmc_irq_gint(struct qmc *qmc)
> /* Restart the receiver if needed */
> spin_lock_irqsave(&chan->rx_lock, flags);
> if (chan->rx_pending && !chan->is_rx_stopped) {
> - if (chan->mode == QMC_TRANSPARENT)
> - qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, 0x18000080);
> - else
> - qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, 0x00000080);
> - qmc_write32(chan->s_param + QMC_SPE_RSTATE, 0x31000000);
> + qmc_write32(chan->s_param + QMC_SPE_ZDSTATE,
> + chan->mode == QMC_TRANSPARENT ?
> + chan->qmc->data->zdstate_transp :
> + chan->qmc->data->zdstate_hdlc);
> + qmc_write32(chan->s_param + QMC_SPE_RSTATE,
> + chan->qmc->data->rstate);
> chan->is_rx_halted = false;
> } else {
> chan->is_rx_halted = true;
> @@ -1597,6 +1607,11 @@ static int qmc_probe(struct platform_device *pdev)
> return -ENOMEM;
>
> qmc->dev = &pdev->dev;
> + qmc->data = of_device_get_match_data(&pdev->dev);
> + if (!qmc->data) {
> + dev_err(qmc->dev, "Missing match data\n");
> + return -EINVAL;
> + }
> INIT_LIST_HEAD(&qmc->chan_head);
>
> qmc->scc_regs = devm_platform_ioremap_resource_byname(pdev, "scc_regs");
> @@ -1752,8 +1767,16 @@ static void qmc_remove(struct platform_device *pdev)
> tsa_serial_disconnect(qmc->tsa_serial);
> }
>
> +static const struct qmc_data qmc_data_cpm1 = {
> + .tstate = 0x30000000,
> + .rstate = 0x31000000,
> + .zistate = 0x00000100,
> + .zdstate_hdlc = 0x00000080,
> + .zdstate_transp = 0x18000080,
> +};
> +
> static const struct of_device_id qmc_id_table[] = {
> - { .compatible = "fsl,cpm1-scc-qmc" },
> + { .compatible = "fsl,cpm1-scc-qmc", .data = &qmc_data_cpm1 },
> {} /* sentinel */
> };
> MODULE_DEVICE_TABLE(of, qmc_id_table);