linux/sound/pci/hda/hda_i915.c
<<
>>
Prefs
   1/*
   2 *  hda_i915.c - routines for Haswell HDA controller power well support
   3 *
   4 *  This program is free software; you can redistribute it and/or modify it
   5 *  under the terms of the GNU General Public License as published by the Free
   6 *  Software Foundation; either version 2 of the License, or (at your option)
   7 *  any later version.
   8 *
   9 *  This program is distributed in the hope that it will be useful, but
  10 *  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  11 *  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12 *  for more details.
  13 *
  14 *  You should have received a copy of the GNU General Public License
  15 *  along with this program; if not, write to the Free Software Foundation,
  16 *  Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17 */
  18
  19#include <linux/init.h>
  20#include <linux/module.h>
  21#include <linux/pci.h>
  22#include <linux/component.h>
  23#include <drm/i915_component.h>
  24#include <sound/core.h>
  25#include "hda_controller.h"
  26#include "hda_intel.h"
  27
  28/* Intel HSW/BDW display HDA controller Extended Mode registers.
  29 * EM4 (M value) and EM5 (N Value) are used to convert CDClk (Core Display
  30 * Clock) to 24MHz BCLK: BCLK = CDCLK * M / N
  31 * The values will be lost when the display power well is disabled.
  32 */
  33#define AZX_REG_EM4                     0x100c
  34#define AZX_REG_EM5                     0x1010
  35
  36int hda_display_power(struct hda_intel *hda, bool enable)
  37{
  38        struct i915_audio_component *acomp = &hda->audio_component;
  39
  40        if (!acomp->ops)
  41                return -ENODEV;
  42
  43        dev_dbg(&hda->chip.pci->dev, "display power %s\n",
  44                enable ? "enable" : "disable");
  45        if (enable)
  46                acomp->ops->get_power(acomp->dev);
  47        else
  48                acomp->ops->put_power(acomp->dev);
  49
  50        return 0;
  51}
  52
  53void haswell_set_bclk(struct hda_intel *hda)
  54{
  55        int cdclk_freq;
  56        unsigned int bclk_m, bclk_n;
  57        struct i915_audio_component *acomp = &hda->audio_component;
  58        struct pci_dev *pci = hda->chip.pci;
  59
  60        /* Only Haswell/Broadwell need set BCLK */
  61        if (pci->device != 0x0a0c && pci->device != 0x0c0c
  62           && pci->device != 0x0d0c && pci->device != 0x160c)
  63                return;
  64
  65        if (!acomp->ops)
  66                return;
  67
  68        cdclk_freq = acomp->ops->get_cdclk_freq(acomp->dev);
  69        switch (cdclk_freq) {
  70        case 337500:
  71                bclk_m = 16;
  72                bclk_n = 225;
  73                break;
  74
  75        case 450000:
  76        default: /* default CDCLK 450MHz */
  77                bclk_m = 4;
  78                bclk_n = 75;
  79                break;
  80
  81        case 540000:
  82                bclk_m = 4;
  83                bclk_n = 90;
  84                break;
  85
  86        case 675000:
  87                bclk_m = 8;
  88                bclk_n = 225;
  89                break;
  90        }
  91
  92        azx_writew(&hda->chip, EM4, bclk_m);
  93        azx_writew(&hda->chip, EM5, bclk_n);
  94}
  95
  96static int hda_component_master_bind(struct device *dev)
  97{
  98        struct snd_card *card = dev_get_drvdata(dev);
  99        struct azx *chip = card->private_data;
 100        struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
 101        struct i915_audio_component *acomp = &hda->audio_component;
 102        int ret;
 103
 104        ret = component_bind_all(dev, acomp);
 105        if (ret < 0)
 106                return ret;
 107
 108        if (WARN_ON(!(acomp->dev && acomp->ops && acomp->ops->get_power &&
 109                      acomp->ops->put_power && acomp->ops->get_cdclk_freq))) {
 110                ret = -EINVAL;
 111                goto out_unbind;
 112        }
 113
 114        /*
 115         * Atm, we don't support dynamic unbinding initiated by the child
 116         * component, so pin its containing module until we unbind.
 117         */
 118        if (!try_module_get(acomp->ops->owner)) {
 119                ret = -ENODEV;
 120                goto out_unbind;
 121        }
 122
 123        return 0;
 124
 125out_unbind:
 126        component_unbind_all(dev, acomp);
 127
 128        return ret;
 129}
 130
 131static void hda_component_master_unbind(struct device *dev)
 132{
 133        struct snd_card *card = dev_get_drvdata(dev);
 134        struct azx *chip = card->private_data;
 135        struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
 136        struct i915_audio_component *acomp = &hda->audio_component;
 137
 138        module_put(acomp->ops->owner);
 139        component_unbind_all(dev, acomp);
 140        WARN_ON(acomp->ops || acomp->dev);
 141}
 142
 143static const struct component_master_ops hda_component_master_ops = {
 144        .bind = hda_component_master_bind,
 145        .unbind = hda_component_master_unbind,
 146};
 147
 148static int hda_component_master_match(struct device *dev, void *data)
 149{
 150        /* i915 is the only supported component */
 151        return !strcmp(dev->driver->name, "i915");
 152}
 153
 154int hda_i915_init(struct hda_intel *hda)
 155{
 156        struct component_match *match = NULL;
 157        struct device *dev = &hda->chip.pci->dev;
 158        struct i915_audio_component *acomp = &hda->audio_component;
 159        int ret;
 160
 161        component_match_add(dev, &match, hda_component_master_match, hda);
 162        ret = component_master_add_with_match(dev, &hda_component_master_ops,
 163                                              match);
 164        if (ret < 0)
 165                goto out_err;
 166
 167        /*
 168         * Atm, we don't support deferring the component binding, so make sure
 169         * i915 is loaded and that the binding successfully completes.
 170         */
 171        request_module("i915");
 172
 173        if (!acomp->ops) {
 174                ret = -ENODEV;
 175                goto out_master_del;
 176        }
 177
 178        dev_dbg(dev, "bound to i915 component master\n");
 179
 180        return 0;
 181out_master_del:
 182        component_master_del(dev, &hda_component_master_ops);
 183out_err:
 184        dev_err(dev, "failed to add i915 component master (%d)\n", ret);
 185
 186        return ret;
 187}
 188
 189int hda_i915_exit(struct hda_intel *hda)
 190{
 191        struct device *dev = &hda->chip.pci->dev;
 192
 193        component_master_del(dev, &hda_component_master_ops);
 194
 195        return 0;
 196}
 197