diff options
Diffstat (limited to 'drivers/spi/mtk_spim.c')
-rw-r--r-- | drivers/spi/mtk_spim.c | 45 |
1 files changed, 43 insertions, 2 deletions
diff --git a/drivers/spi/mtk_spim.c b/drivers/spi/mtk_spim.c index 90f4c3cecb9..b360eca2b91 100644 --- a/drivers/spi/mtk_spim.c +++ b/drivers/spi/mtk_spim.c @@ -137,6 +137,8 @@ struct mtk_spim_capability { * @state: Controller state * @sel_clk: Pad clock * @spi_clk: Core clock + * @parent_clk: Parent clock (needed for mediatek,spi-ipm, upstream DTSI) + * @hclk: HCLK clock (needed for mediatek,spi-ipm, upstream DTSI) * @pll_clk_rate: Controller's PLL source clock rate, which is different * from SPI bus clock rate * @xfer_len: Current length of data for transfer @@ -151,6 +153,7 @@ struct mtk_spim_priv { void __iomem *base; u32 state; struct clk sel_clk, spi_clk; + struct clk parent_clk, hclk; u32 pll_clk_rate; u32 xfer_len; struct mtk_spim_capability hw_cap; @@ -650,7 +653,21 @@ static int mtk_spim_probe(struct udevice *dev) if (!priv->base) return -EINVAL; - mtk_spim_get_attr(priv, dev); + /* + * Upstream linux driver for ipm design enable all the modes + * and setup the calibrarion values directly in the driver with + * standard values. + */ + if (device_is_compatible(dev, "mediatek,spi-ipm")) { + priv->hw_cap.enhance_timing = true; + priv->hw_cap.dma_ext = true; + priv->hw_cap.ipm_design = true; + priv->hw_cap.support_quad = true; + priv->sample_sel = 0; + priv->tick_dly = 2; + } else { + mtk_spim_get_attr(priv, dev); + } ret = clk_get_by_name(dev, "sel-clk", &priv->sel_clk); if (ret < 0) { @@ -664,8 +681,31 @@ static int mtk_spim_probe(struct udevice *dev) return ret; } - clk_enable(&priv->sel_clk); + /* + * Upstream DTSI use a different compatible that provide additional + * clock instead of the assigned-clock implementation. + */ + if (device_is_compatible(dev, "mediatek,spi-ipm")) { + ret = clk_get_by_name(dev, "parent-clk", &priv->parent_clk); + if (ret < 0) { + dev_err(dev, "failed to get parent-clk\n"); + return ret; + } + + ret = clk_get_by_name(dev, "hclk", &priv->hclk); + if (ret < 0) { + dev_err(dev, "failed to get hclk\n"); + return ret; + } + + clk_enable(&priv->parent_clk); + clk_set_parent(&priv->sel_clk, &priv->parent_clk); + + clk_enable(&priv->hclk); + } + clk_enable(&priv->spi_clk); + clk_enable(&priv->sel_clk); priv->pll_clk_rate = clk_get_rate(&priv->spi_clk); if (priv->pll_clk_rate == 0) @@ -698,6 +738,7 @@ static const struct dm_spi_ops mtk_spim_ops = { static const struct udevice_id mtk_spim_ids[] = { { .compatible = "mediatek,ipm-spi" }, + { .compatible = "mediatek,spi-ipm", }, {} }; |