struct reset_control *rst;
        struct clk *clk_parent;
-       struct clk *clk_brick;
        struct clk *clk_safe;
-       struct clk *clk_src;
+       struct clk *clk_out;
+       struct clk *clk_pad;
        struct clk *clk_dp;
        struct clk *clk;
 
 
        clk_disable_unprepare(sor->clk);
 
-       err = clk_set_parent(sor->clk, parent);
+       err = clk_set_parent(sor->clk_out, parent);
        if (err < 0)
                return err;
 
        return 0;
 }
 
-struct tegra_clk_sor_brick {
+struct tegra_clk_sor_pad {
        struct clk_hw hw;
        struct tegra_sor *sor;
 };
 
-static inline struct tegra_clk_sor_brick *to_brick(struct clk_hw *hw)
+static inline struct tegra_clk_sor_pad *to_pad(struct clk_hw *hw)
 {
-       return container_of(hw, struct tegra_clk_sor_brick, hw);
+       return container_of(hw, struct tegra_clk_sor_pad, hw);
 }
 
-static const char * const tegra_clk_sor_brick_parents[] = {
+static const char * const tegra_clk_sor_pad_parents[] = {
        "pll_d2_out0", "pll_dp"
 };
 
-static int tegra_clk_sor_brick_set_parent(struct clk_hw *hw, u8 index)
+static int tegra_clk_sor_pad_set_parent(struct clk_hw *hw, u8 index)
 {
-       struct tegra_clk_sor_brick *brick = to_brick(hw);
-       struct tegra_sor *sor = brick->sor;
+       struct tegra_clk_sor_pad *pad = to_pad(hw);
+       struct tegra_sor *sor = pad->sor;
        u32 value;
 
        value = tegra_sor_readl(sor, SOR_CLK_CNTRL);
        return 0;
 }
 
-static u8 tegra_clk_sor_brick_get_parent(struct clk_hw *hw)
+static u8 tegra_clk_sor_pad_get_parent(struct clk_hw *hw)
 {
-       struct tegra_clk_sor_brick *brick = to_brick(hw);
-       struct tegra_sor *sor = brick->sor;
+       struct tegra_clk_sor_pad *pad = to_pad(hw);
+       struct tegra_sor *sor = pad->sor;
        u8 parent = U8_MAX;
        u32 value;
 
        return parent;
 }
 
-static const struct clk_ops tegra_clk_sor_brick_ops = {
-       .set_parent = tegra_clk_sor_brick_set_parent,
-       .get_parent = tegra_clk_sor_brick_get_parent,
+static const struct clk_ops tegra_clk_sor_pad_ops = {
+       .set_parent = tegra_clk_sor_pad_set_parent,
+       .get_parent = tegra_clk_sor_pad_get_parent,
 };
 
-static struct clk *tegra_clk_sor_brick_register(struct tegra_sor *sor,
-                                               const char *name)
+static struct clk *tegra_clk_sor_pad_register(struct tegra_sor *sor,
+                                             const char *name)
 {
-       struct tegra_clk_sor_brick *brick;
+       struct tegra_clk_sor_pad *pad;
        struct clk_init_data init;
        struct clk *clk;
 
-       brick = devm_kzalloc(sor->dev, sizeof(*brick), GFP_KERNEL);
-       if (!brick)
+       pad = devm_kzalloc(sor->dev, sizeof(*pad), GFP_KERNEL);
+       if (!pad)
                return ERR_PTR(-ENOMEM);
 
-       brick->sor = sor;
+       pad->sor = sor;
 
        init.name = name;
        init.flags = 0;
-       init.parent_names = tegra_clk_sor_brick_parents;
-       init.num_parents = ARRAY_SIZE(tegra_clk_sor_brick_parents);
-       init.ops = &tegra_clk_sor_brick_ops;
+       init.parent_names = tegra_clk_sor_pad_parents;
+       init.num_parents = ARRAY_SIZE(tegra_clk_sor_pad_parents);
+       init.ops = &tegra_clk_sor_pad_ops;
 
-       brick->hw.init = &init;
+       pad->hw.init = &init;
 
-       clk = devm_clk_register(sor->dev, &brick->hw);
+       clk = devm_clk_register(sor->dev, &pad->hw);
 
        return clk;
 }
 
        /* switch to safe parent clock */
        err = tegra_sor_set_parent_clock(sor, sor->clk_safe);
-       if (err < 0)
+       if (err < 0) {
                dev_err(sor->dev, "failed to set safe parent clock: %d\n", err);
+               return err;
+       }
 
        value = tegra_sor_readl(sor, SOR_DP_PADCTL0);
        value &= ~(SOR_DP_PADCTL_PD_TXD_3 | SOR_DP_PADCTL_PD_TXD_0 |
 
        /* switch to safe parent clock */
        err = tegra_sor_set_parent_clock(sor, sor->clk_safe);
-       if (err < 0)
+       if (err < 0) {
                dev_err(sor->dev, "failed to set safe parent clock: %d\n", err);
+               return;
+       }
 
        div = clk_get_rate(sor->clk) / 1000000 * 4;
 
        tegra_sor_writel(sor, value, SOR_XBAR_CTRL);
 
        /* switch to parent clock */
-       err = clk_set_parent(sor->clk_src, sor->clk_parent);
-       if (err < 0)
-               dev_err(sor->dev, "failed to set source clock: %d\n", err);
-
-       err = tegra_sor_set_parent_clock(sor, sor->clk_src);
-       if (err < 0)
+       err = clk_set_parent(sor->clk, sor->clk_parent);
+       if (err < 0) {
                dev_err(sor->dev, "failed to set parent clock: %d\n", err);
+               return;
+       }
+
+       err = tegra_sor_set_parent_clock(sor, sor->clk_pad);
+       if (err < 0) {
+               dev_err(sor->dev, "failed to set pad clock: %d\n", err);
+               return;
+       }
 
        value = SOR_INPUT_CONTROL_HDMI_SRC_SELECT(dc->pipe);
 
        }
 
        if (sor->soc->supports_hdmi || sor->soc->supports_dp) {
-               sor->clk_src = devm_clk_get(&pdev->dev, "source");
-               if (IS_ERR(sor->clk_src)) {
-                       err = PTR_ERR(sor->clk_src);
-                       dev_err(sor->dev, "failed to get source clock: %d\n",
-                               err);
+               struct device_node *np = pdev->dev.of_node;
+               const char *name;
+
+               /*
+                * For backwards compatibility with Tegra210 device trees,
+                * fall back to the old clock name "source" if the new "out"
+                * clock is not available.
+                */
+               if (of_property_match_string(np, "clock-names", "out") < 0)
+                       name = "source";
+               else
+                       name = "out";
+
+               sor->clk_out = devm_clk_get(&pdev->dev, name);
+               if (IS_ERR(sor->clk_out)) {
+                       err = PTR_ERR(sor->clk_out);
+                       dev_err(sor->dev, "failed to get %s clock: %d\n",
+                               name, err);
                        goto remove;
                }
        }
                goto remove;
        }
 
+       /*
+        * Starting with Tegra186, the BPMP provides an implementation for
+        * the pad output clock, so we have to look it up from device tree.
+        */
+       sor->clk_pad = devm_clk_get(&pdev->dev, "pad");
+       if (IS_ERR(sor->clk_pad)) {
+               if (sor->clk_pad != ERR_PTR(-ENOENT)) {
+                       err = PTR_ERR(sor->clk_pad);
+                       goto remove;
+               }
+
+               /*
+                * If the pad output clock is not available, then we assume
+                * we're on Tegra210 or earlier and have to provide our own
+                * implementation.
+                */
+               sor->clk_pad = NULL;
+       }
+
+       /*
+        * The bootloader may have set up the SOR such that it's module clock
+        * is sourced by one of the display PLLs. However, that doesn't work
+        * without properly having set up other bits of the SOR.
+        */
+       err = clk_set_parent(sor->clk_out, sor->clk_safe);
+       if (err < 0) {
+               dev_err(&pdev->dev, "failed to use safe clock: %d\n", err);
+               goto remove;
+       }
+
        platform_set_drvdata(pdev, sor);
        pm_runtime_enable(&pdev->dev);
 
-       pm_runtime_get_sync(&pdev->dev);
-       sor->clk_brick = tegra_clk_sor_brick_register(sor, "sor1_brick");
-       pm_runtime_put(&pdev->dev);
+       /*
+        * On Tegra210 and earlier, provide our own implementation for the
+        * pad output clock.
+        */
+       if (!sor->clk_pad) {
+               err = pm_runtime_get_sync(&pdev->dev);
+               if (err < 0) {
+                       dev_err(&pdev->dev, "failed to get runtime PM: %d\n",
+                               err);
+                       goto remove;
+               }
+
+               sor->clk_pad = tegra_clk_sor_pad_register(sor,
+                                                         "sor1_pad_clkout");
+               pm_runtime_put(&pdev->dev);
+       }
 
-       if (IS_ERR(sor->clk_brick)) {
-               err = PTR_ERR(sor->clk_brick);
-               dev_err(&pdev->dev, "failed to register SOR clock: %d\n", err);
+       if (IS_ERR(sor->clk_pad)) {
+               err = PTR_ERR(sor->clk_pad);
+               dev_err(&pdev->dev, "failed to register SOR pad clock: %d\n",
+                       err);
                goto remove;
        }