aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSjoerd Simons <sjoerd.simons@collabora.co.uk>2015-11-06 07:22:24 -0500
committerMark Yao <mark.yao@rock-chips.com>2015-12-01 05:52:05 -0500
commitd7b53fd9e37a4127077720f4fef10330e284107c (patch)
tree3c5d57dd84791e774df8fa29af67f88bbc59b759
parentb50a1705b598fa4074a5e5e4f20ca46485d1cd0e (diff)
drm/rockchip: vop: Correct enabled clocks during setup
When doing the initial setup both the hclk and the aclk need to be enabled otherwise the board will simply hang. This only occurs when building the vop driver as a module, when its built-in the initial setup happens to run before the clock framework shuts of unused clocks (including the aclk). While there also switch to doing prepare and enable in one step rather then separate steps to reduce the amount of code required. Signed-off-by: Sjoerd Simons <sjoerd.simons@collabora.co.uk> Acked-by: Mark Yao <mark.yao@rock-chips.com> Tested-by: Yakir Yang <ykk@rock-chips.com> Tested-by: Romain Perier <romain.perier@gmail.com>
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop.c36
1 files changed, 14 insertions, 22 deletions
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 5d8ae5e49c44..48719df70419 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -1575,32 +1575,25 @@ static int vop_initial(struct vop *vop)
1575 return PTR_ERR(vop->dclk); 1575 return PTR_ERR(vop->dclk);
1576 } 1576 }
1577 1577
1578 ret = clk_prepare(vop->hclk);
1579 if (ret < 0) {
1580 dev_err(vop->dev, "failed to prepare hclk\n");
1581 return ret;
1582 }
1583
1584 ret = clk_prepare(vop->dclk); 1578 ret = clk_prepare(vop->dclk);
1585 if (ret < 0) { 1579 if (ret < 0) {
1586 dev_err(vop->dev, "failed to prepare dclk\n"); 1580 dev_err(vop->dev, "failed to prepare dclk\n");
1587 goto err_unprepare_hclk; 1581 return ret;
1588 } 1582 }
1589 1583
1590 ret = clk_prepare(vop->aclk); 1584 /* Enable both the hclk and aclk to setup the vop */
1585 ret = clk_prepare_enable(vop->hclk);
1591 if (ret < 0) { 1586 if (ret < 0) {
1592 dev_err(vop->dev, "failed to prepare aclk\n"); 1587 dev_err(vop->dev, "failed to prepare/enable hclk\n");
1593 goto err_unprepare_dclk; 1588 goto err_unprepare_dclk;
1594 } 1589 }
1595 1590
1596 /* 1591 ret = clk_prepare_enable(vop->aclk);
1597 * enable hclk, so that we can config vop register.
1598 */
1599 ret = clk_enable(vop->hclk);
1600 if (ret < 0) { 1592 if (ret < 0) {
1601 dev_err(vop->dev, "failed to prepare aclk\n"); 1593 dev_err(vop->dev, "failed to prepare/enable aclk\n");
1602 goto err_unprepare_aclk; 1594 goto err_disable_hclk;
1603 } 1595 }
1596
1604 /* 1597 /*
1605 * do hclk_reset, reset all vop registers. 1598 * do hclk_reset, reset all vop registers.
1606 */ 1599 */
@@ -1608,7 +1601,7 @@ static int vop_initial(struct vop *vop)
1608 if (IS_ERR(ahb_rst)) { 1601 if (IS_ERR(ahb_rst)) {
1609 dev_err(vop->dev, "failed to get ahb reset\n"); 1602 dev_err(vop->dev, "failed to get ahb reset\n");
1610 ret = PTR_ERR(ahb_rst); 1603 ret = PTR_ERR(ahb_rst);
1611 goto err_disable_hclk; 1604 goto err_disable_aclk;
1612 } 1605 }
1613 reset_control_assert(ahb_rst); 1606 reset_control_assert(ahb_rst);
1614 usleep_range(10, 20); 1607 usleep_range(10, 20);
@@ -1634,26 +1627,25 @@ static int vop_initial(struct vop *vop)
1634 if (IS_ERR(vop->dclk_rst)) { 1627 if (IS_ERR(vop->dclk_rst)) {
1635 dev_err(vop->dev, "failed to get dclk reset\n"); 1628 dev_err(vop->dev, "failed to get dclk reset\n");
1636 ret = PTR_ERR(vop->dclk_rst); 1629 ret = PTR_ERR(vop->dclk_rst);
1637 goto err_unprepare_aclk; 1630 goto err_disable_aclk;
1638 } 1631 }
1639 reset_control_assert(vop->dclk_rst); 1632 reset_control_assert(vop->dclk_rst);
1640 usleep_range(10, 20); 1633 usleep_range(10, 20);
1641 reset_control_deassert(vop->dclk_rst); 1634 reset_control_deassert(vop->dclk_rst);
1642 1635
1643 clk_disable(vop->hclk); 1636 clk_disable(vop->hclk);
1637 clk_disable(vop->aclk);
1644 1638
1645 vop->is_enabled = false; 1639 vop->is_enabled = false;
1646 1640
1647 return 0; 1641 return 0;
1648 1642
1643err_disable_aclk:
1644 clk_disable_unprepare(vop->aclk);
1649err_disable_hclk: 1645err_disable_hclk:
1650 clk_disable(vop->hclk); 1646 clk_disable_unprepare(vop->hclk);
1651err_unprepare_aclk:
1652 clk_unprepare(vop->aclk);
1653err_unprepare_dclk: 1647err_unprepare_dclk:
1654 clk_unprepare(vop->dclk); 1648 clk_unprepare(vop->dclk);
1655err_unprepare_hclk:
1656 clk_unprepare(vop->hclk);
1657 return ret; 1649 return ret;
1658} 1650}
1659 1651